diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index b15cdf6..0000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,86 +0,0 @@ -name: Build Release Artifacts - -on: - workflow_dispatch: - push: - branches: - - master - -jobs: - package: - runs-on: ${{ matrix.os }} - - strategy: - matrix: - os: [ubuntu-latest, windows-latest] - - steps: - - name: Checkout branch - uses: actions/checkout@v2 - - - name: Setup Node - uses: actions/setup-node@v1 - with: - node-version: '14.x' - - - name: Get package version - uses: actions/github-script@v6 - id: version - with: - script: | - return JSON.parse(require('fs').readFileSync('package.json')).version; - result-encoding: string - - - name: Install Dependencies - run: npm install - - - name: Install Gulp on Mac - run: npm install -g gulp - if: startsWith(matrix.os, 'mac') - - - name: Build - run: gulp prep-pkg - - - name: Package Win/Linux - run: npm run dist - if: startsWith(matrix.os, 'win') || startsWith(matrix.os, 'ubuntu') - - - name: Package Mac - run: PYTHON_PATH=$(which python) npm run dist - if: startsWith(matrix.os, 'mac') - - - name: Upload Linux Version - uses: actions/upload-artifact@v2 - with: - path: ./release/INTO-CPS-Application-${{ steps.version.outputs.result }}.AppImage - name: INTO-CPS-Application-${{ steps.version.outputs.result }}-linux.AppImage - if: startsWith(matrix.os, 'ubuntu') - - - name: Upload Windows Version - uses: actions/upload-artifact@v2 - with: - path: ./release/INTO-CPS-Application Setup ${{ steps.version.outputs.result }}.exe - name: INTO-CPS-Application-${{ steps.version.outputs.result }}-win-setup.exe - if: startsWith(matrix.os, 'windows') - - - name: Upload Portable Windows Version - uses: actions/upload-artifact@v2 - with: - path: ./release/INTO-CPS-Application ${{ steps.version.outputs.result }}.exe - name: INTO-CPS-Application-${{ steps.version.outputs.result }}-win-portable.exe - if: startsWith(matrix.os, 'windows') - - - name: Upload Dmg - uses: actions/upload-artifact@v2 - with: - path: ./release/INTO-CPS-Application-${{ steps.version.outputs.result }}.dmg - name: INTO-CPS-Application-${{ steps.version.outputs.result }}-mac.dmg - if: startsWith(matrix.os, 'mac') - - - name: Upload Darwin Zip - uses: actions/upload-artifact@v2 - with: - path: ./release/INTO-CPS-Application-${{ steps.version.outputs.result }}-mac.zip - name: INTO-CPS-Application-${{ steps.version.outputs.result }}-darwin_x64.zip - if: startsWith(matrix.os, 'mac') - diff --git a/.github/workflows/snapshots.yml b/.github/workflows/snapshots.yml deleted file mode 100644 index e3e87b6..0000000 --- a/.github/workflows/snapshots.yml +++ /dev/null @@ -1,86 +0,0 @@ -name: Build Snapshot - -on: - push: - branches: - - 'development' - - 'snapshot/**' - -jobs: - package: - runs-on: ${{ matrix.os }} - - strategy: - matrix: - os: [ubuntu-latest, windows-latest, macos-latest] - - steps: - - name: Checkout branch - uses: actions/checkout@v2 - - - name: Setup Node - uses: actions/setup-node@v1 - with: - node-version: '14.x' - - - name: Get package version - uses: actions/github-script@v6 - id: version - with: - script: | - return JSON.parse(require('fs').readFileSync('package.json')).version; - result-encoding: string - - - name: Install Dependencies - run: npm install - - - name: Install Gulp on Mac - run: npm install -g gulp - if: startsWith(matrix.os, 'mac') - - - name: Build - run: gulp prep-pkg - - - name: Package Win/Linux - run: npm run dist - if: startsWith(matrix.os, 'win') || startsWith(matrix.os, 'ubuntu') - - - name: Package Mac - run: PYTHON_PATH=$(which python) npm run dist - if: startsWith(matrix.os, 'mac') - - - name: Upload Linux Version - uses: actions/upload-artifact@v2 - with: - path: ./release/INTO-CPS-Application-${{ steps.version.outputs.result }}.AppImage - name: INTO-CPS-Application-SNAPSHOT-v${{ steps.version.outputs.result }}.${{ github.run_number }}-linux_x64.AppImage - if: startsWith(matrix.os, 'ubuntu') - - - name: Upload Windows Version - uses: actions/upload-artifact@v2 - with: - path: ./release/INTO-CPS-Application Setup ${{ steps.version.outputs.result }}.exe - name: INTO-CPS-Application-SNAPSHOT-v${{ steps.version.outputs.result }}.${{ github.run_number }}-win_x86-Setup.exe - if: startsWith(matrix.os, 'windows') - - - name: Upload Portable Windows Version - uses: actions/upload-artifact@v2 - with: - path: ./release/INTO-CPS-Application ${{ steps.version.outputs.result }}.exe - name: INTO-CPS-Application-SNAPSHOT-v${{ steps.version.outputs.result }}.${{ github.run_number }}-win_x86-Portable.exe - if: startsWith(matrix.os, 'windows') - - - name: Upload Dmg - uses: actions/upload-artifact@v2 - with: - path: ./release/INTO-CPS-Application-${{ steps.version.outputs.result }}.dmg - name: INTO-CPS-Application-SNAPSHOT-v${{ steps.version.outputs.result }}.${{ github.run_number }}-darwin_x64.dmg - if: startsWith(matrix.os, 'mac') - - - name: Upload Darwin Zip - uses: actions/upload-artifact@v2 - with: - path: ./release/INTO-CPS-Application-${{ steps.version.outputs.result }}-mac.zip - name: INTO-CPS-Application-SNAPSHOT-v${{ steps.version.outputs.result }}.${{ github.run_number }}-darwin_x64.zip - if: startsWith(matrix.os, 'mac') - diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 85ca808..0000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: Run All Tests - -on: - push: - branches: - - test - -jobs: - run-tests: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - with: - ref: test - - - name: Setup Node - uses: actions/setup-node@v1 - with: - node-version: '14.x' - - - name: Install Java - run: /usr/bin/sudo apt-get install openjdk-8-jre-headless - - - name: Install Node Dependencies - run: npm install - - - name: Run Gulp - run: gulp - - - name: Run headless tests - uses: GabrielBB/xvfb-action@v1.0 - with: - run: npm test diff --git a/.gitignore b/.gitignore index d8b1a4d..d299d48 100644 --- a/.gitignore +++ b/.gitignore @@ -1,58 +1,63 @@ -# documentation -docs/_build - -# Logs -logs -*.log -npm-debug.log* - -# Runtime data -pids -*.pid -*.seed - -# node-waf configuration -.lock-wscript - -# Dependency directories -node_modules -jspm_packages - -# Build folder -dist/ - -# Release folder -release/ - -# Vim auxiliary files -.*.un~ -.*.swp -.*.swo -*~ - -bower_components/ -typings/ -.vscode/ - - -.DS_Store - -test-create -demo-project -test-sim -test-vdmsim -target -test-project/Models/watertankController/generated -downloader-test/installed -downloader-test/*.zip - -**/R_* -**/test-project/downloads - - -MakeFile - -pkg/ - -# WebStorm project files -.idea/ +# documentation +docs/_build + +# Logs +logs +*.log +npm-debug.log* + +# Runtime data +pids +*.pid +*.seed + +# node-waf configuration +.lock-wscript + +# Dependency directories +node_modules +jspm_packages + +# Build folder +dist/ + +# Release folder +release/ + +# Vim auxiliary files +.*.un~ +.*.swp +.*.swo +*~ + +bower_components/ +typings/ +.vscode/ + + +.DS_Store + +test-create +demo-project +test-sim +test-vdmsim +target +test-project/Models/watertankController/generated +downloader-test/installed +downloader-test/*.zip + +**/R_* +**/test-project/downloads + +#Test results +monocart-report/ +test/coverage-reports/ +coverage/ +test-results/ + +MakeFile + +pkg/ + +# WebStorm project files +.idea/ diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 84fa967..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "into-cps-app-common"] - path = into-cps-app-common - url = https://github.com/INTO-CPS-Association/into-cps-app-common.git diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 3639451..0f6f033 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -1,3 +1,5 @@ +# Contributors + The authors and contributors of the INTO-CPS Application are, in no particular order: @@ -17,3 +19,4 @@ Etienne Brosse Martin Mansfield Anders Terkelsen Kristoffer Stampe Villadsen +Simone Micalizzi diff --git a/DEVELOPER.md b/DEVELOPER.md index 52bfae5..84b1c0c 100644 --- a/DEVELOPER.md +++ b/DEVELOPER.md @@ -1,26 +1,32 @@ # Development environment documentation + ## Required technologies and tools + - [Node Package Manager (NPM)](https://www.npmjs.com/package/npm): a package management system used to maintain packages used by the application. NPM 3 or higher is required. +- [Node.js](https://nodejs.org/) (v14.x is required). - [Gulp](https://gulpjs.com/docs/en/getting-started/quick-start): a build system used to build the application. -- [Electron](http://electron.atom.io/): The app is built with Electron v10.4.7. -- [Node.js](https://nodejs.org/) (v14.x is required). - [Visual Studio Code](https://code.visualstudio.com/) is a good choice as an editor: it's cross-platform and is actually built on top of Electron. That said, everything can be used. To manage multiple versions of **`Node.js`** &/or **`npm`**, consider using a [node version manager](https://github.com/search?q=node+version+manager+archived%3Afalse&type=repositories&ref=advsearch). + ## How to build and run the application + The following are the commands to run the application. After checking out the repo: -1. To install node dependencies: `npm install` -2. To install gulp: `npm install -g gulp` (it's easiest to have it installed globally) -3. To build the UI: `gulp` or `gulp build` -4. To run it: `npm start` -5. To run tests: `npm test` -6. To build and create a developer .exe file: `gulp package` + +1. To install node dependencies: `npm install` +2. To install gulp: `npm install -g gulp` (it's easiest to have it installed globally) +3. To build the UI: `gulp` or `gulp build` +4. To run it: `npm start` +5. To run tests: `npm test` +6. To build the application for the release: `npm run dist` or `npm run dist:win` for Windows only. Please note that it's required to run the `gulp` command first. ## Useful commands and properties + - `gulp watch`: it will automatically detect when you save a file and run the corresponding build task so you only have to refresh the app when developing. -- `--no-sandbox`: the property `--no-sandbox` has been inserted to `npm start` to disable sandbox mode to prevent GPU mismanagement errors, caused by Electron conflicts, during virtualization on a Linux operating system. It is necessary, however, that this property be entered while starting the built program from the terminal. For example, starting the AppImage from the terminal we would type `./NomeAppImage --no-sandbox`. This way, the application will be started without any problems. +- `npm run clean`: cleans the working envorinment from different folders, making it ready to be deployed. ## Latest builds + The master branch is built automatically on git pushes and the output, for successful builds. Please find the artifacts by clicking in the run [of the Package workflow](https://github.com/INTO-CPS-Association/into-cps-application/actions?query=workflow%3APackage). These builds represent ongoing work. They have not been fully tested and are not guaranteed to work. Normally, you are advised to use one of the [releases](https://github.com/INTO-CPS-Association/into-cps-application/releases). diff --git a/README.md b/README.md index a764fa4..20e3739 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ -INTO-CPS Application ---- +# INTO-CPS Application The INTO-CPS Application is the frontend of the INTO-CPS Tool Chain. It is used to configure and run FMI-based co-simulations. Other features include model @@ -7,16 +6,15 @@ checking, test automation and design space exploration. The App is primarily a UI. Most of the modelling and simulation work is done by the INTO-CPS tools themselves. These can be downloaded from within the app. -For additional details besides this document, see the [wiki](https://github.com/INTO-CPS-Association/into-cps-application/wiki). +For additional details besides this document, see the [wiki](https://github.com/INTO-CPS-Association/into-cps-application/wiki). ![The INTO-CPS Application](src/resources/screenshot.png?raw=true "The INTO-CPS App") +## How to build -How to build ---- The app is built with [Electron](http://electron.atom.io/) and -[Node.js](https://nodejs.org/) (v6 recommended). You need npm (comes with Node.js). Npm 3 or higher is required. Npm -can be upgraded with `npm install npm@latest -g`. We use Gulp to manage tasks. It's easiest to have it installed globally (`npm install -g gulp`). +[Node.js](https://nodejs.org/) (v14.x is required). You need npm (comes with Node.js). Npm 3 or higher is required. Npm +can be upgraded with `npm install npm@latest -g`. We use Gulp to manage tasks. It's easiest to have it installed globally (`npm install -g gulp`). After checking out the repo: @@ -25,17 +23,16 @@ After checking out the repo: 3. To run it: `npm start` 4. To run the tests: `npm test` +## Development -Development ---- For an editor, [Visual Studio Code](https://code.visualstudio.com/) is a good choice. It's cross-platform and is actually built on top of Electron. That said, you can use whatever you want. -Further developer info is available in https://github.com/into-cps-association/into-cps-application/wiki +Further developer info is available in + +## Latest builds -Latest builds ---- The master branch is built automatically on git pushes and the output, for successful builds. Please find the artifacts by clickin in the run [of the Package workflow](https://github.com/INTO-CPS-Association/into-cps-application/actions?query=workflow%3APackage). @@ -43,10 +40,8 @@ These builds represent ongoing work. They have not been fully tested and are not guaranteed to work. Normally, you are advised to use one of the [releases](https://github.com/INTO-CPS-Association/into-cps-application/releases). +## About -About ---- INTO-CPS is an EU Horizon 2020 research project that is creating an integrated tool chain for comprehensive Model-Based Design of Cyber-Physical Systems. For -more, see: http://into-cps.au.dk/ - +more, see: diff --git a/docs/conf.py b/docs/conf.py deleted file mode 100644 index d388ac8..0000000 --- a/docs/conf.py +++ /dev/null @@ -1,72 +0,0 @@ -# Configuration file for the Sphinx documentation builder. -# -# This file only contains a selection of the most common options. For a full -# list see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Path setup -------------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -# import os -# import sys -# sys.path.insert(0, os.path.abspath('.')) - - -# -- Project information ----------------------------------------------------- - -project = "INTO-CPS Desktop Application" -copyright = "2020, INTO-CPS Association" -author = "INTO-CPS Association" - -# The full version, including alpha/beta/rc tags -release = "4.0.0" - -master_doc = "index" - -# -- General configuration --------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - "recommonmark", - "sphinx_rtd_theme", - "sphinx.ext.imgconverter", -] - - -# Add any paths that contain templates here, relative to this directory. -templates_path = ["_templates"] - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. -exclude_patterns = [ - "_build", - "Thumbs.db", - ".DS_Store", - "submodules/**/[rR][eE][aA][dD][mM][eE].[mM][dD]", - "submodules/**/CONTRIBUTORS.md", - "submodules/**/LICENSE.md", -] - - -# -- Options for HTML output ------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = "sphinx_rtd_theme" - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ["_static"] - - -# We do not wish to process "GitHub" README.MD in the source tree - -# html_logo = "images/logo.svg" diff --git a/docs/developer_documentation.rst b/docs/developer_documentation.rst deleted file mode 100644 index 9e2870c..0000000 --- a/docs/developer_documentation.rst +++ /dev/null @@ -1,11 +0,0 @@ -Developer Documentation -======================= - -This section of the documentation provides relevant information to maintainers and contributers of the project. - -Overview --------- - -.. image:: images/INTO_CPS_modules.svg - -test \ No newline at end of file diff --git a/docs/first_steps.rst b/docs/first_steps.rst deleted file mode 100644 index 1fb4f01..0000000 --- a/docs/first_steps.rst +++ /dev/null @@ -1,66 +0,0 @@ -.. _first_steps: - -First Steps -=========== - -The following sections guides you through the process of installing the application, installing its dependencies and finally demonstrates how a co-simulation can be configured and executed within the application. - - -Install the application ------------------------ - -There are two options for installing the application. -The recommended approach is to download the latest `Release Build`_, which is may lack bleeding edge features, but is typically much more stable. -The alternative, is building the latest `Development Build`_ from source, which gives access to the most recently added features, but at a potential cost of stability. - -Release Build -^^^^^^^^^^^^^^ -The latest release of the application for Windows, Linux, and macOS can be found on `GitHub Releases `__. -Download and extract the zip archive corresponding to your host architecture. -The extracted directory should look similar to this: - -.. image:: images/application_extracted.png - :height: 350 - :align: center - :alt: Extracted Application - -Development Build -^^^^^^^^^^^^^^^^^ - -1. clone the repository: ``git clone https://github.com/INTO-CPS-Association/into-cps-application/tree/development`` -2. change working directory to repository: ``cd into-cps-application`` -3. install node dependencies: ``npm install`` -5. build ui: ``gulp`` -6. run the test: ``npm test`` - - - - - -Installing toolchain dependencies ---------------------------------- - -The application is modular by design, as such it relies on external programs to support its features. -The easiest way to install these is using the built in download manager. - -.. image:: images/download_manager.png - :height: 400 - :align: center - :alt: Download Manager Window - -1. Start the application by executing the program ``into-cps-app-x.x.x`` -2. Press the "Window.Show Download Manager" tab, a window will appear -3. Select the latest version of the toolchain -4. Select and download "Co-simulation Orchestration Engine - Co-simulation" - -.. note:: - This guide only installs the dependency necessary to perform co-simulations inside the application. - To access other features it may be necessary to install additional programs. - - -Performing a Co-Simulation --------------------------- - -.. warning:: - Missing! - Here we should explain how to run, say the water tank example. \ No newline at end of file diff --git a/docs/images/INTO_CPS_modules.drawio b/docs/images/INTO_CPS_modules.drawio deleted file mode 100644 index de1ea40..0000000 --- a/docs/images/INTO_CPS_modules.drawio +++ /dev/null @@ -1 +0,0 @@ -7VtLc6M4EP4te3DV7CEuEA+bY+J4Z6dqpja1qZ3dOcog25oBRAkR2/PrVwLJPET8Jtg1ycGBRhLQ39etVqsZWJNo/ZHCZPmFBCgcACNYD6zHAQDAtB3+T0g2hcQ0Pa+QLCgOpKwUPOOfSAoNKc1wgNJaQ0ZIyHBSF/okjpHPajJIKVnVm81JWL9rAhfyjkYpePZhiLRm/+KALdVruF554U+EF0t56zEYFRciqBrLgdMlDMiqIrKmA2tCCWHFUbSeoFBoT+ml6PfHK1e3D0ZRzA7pAORjsI16NxTwV5WnhLIlWZAYhtNS+kBJFgdIDGDws7LNZ0ISLjS58DtibCNxgxkjXLRkUSivojVm/4nuQ0eefatceVzLkfOTjTqJGd1UOonTb9VrZbf8TPXTFSJ1lJKM+vKdLckhSBdItgKSo0IdlX5Six8RiRC/DW9AUQgZfqkzA0qCLbbtZNd7SuGm0iAhOGZpZeQnIeANpLFYtiSKNBVgNfBstAfjne35QfEE6qzyKqUo50g7X6SmXmCYyTeeZDTXLTCmAWaEaoSq02W1xAw9JzBX/Yr7hzo15jgMJyTkw4i+VuCgcWBzecoo+YEqV8ZgZrnuLoBfEGVovRM7pWSjrjTTlUOsSuNWel1WzNo1Xke7ovGdCrV7McAujcm5WmNSxnAtxuRoxpRPmJhPNLdsTua4P3Ny+zWnmjGVtnWOOamYp2ZP5qXt6VD9jvqNF0A1YNjGCPsCBtuwq8CYQ8Ny90CTnz0hirmGED0br+vwf1bDMC1vj/9T8Wx7+7P931jzf7/5JEpIzPV7HwjKNMnGPRCrcwOGeBHzY5/3EUA9CD8lPOi9vBDhIChoiFL8E87yoQSaUlt8XOdh4DxySQhnKHyA/o9FTtmKe5znf60UGL3iHrerD3nLQTXAb3Obd9xhjFVArmYcqaLjeKEBeWd7wwaWd9a4PgqZz1PO16YvOA5Rr1/3MDrNPbh9uwe3L3eunqZigk+UfBdrZmA8otSnOGGYxBeNQuZz5Pp+WxQSjLyZsVOVRwT1Tt3Z2WolVYlCTNBRGGKamsZuPg4BOnFNrzfiAo24UTT8nrZQdQ850yVMxJVovRDB93AGU+wPA+JnUa6OYlZ4IinODaFlpvncaDAjjJHokLmJCWAvEnI30gSWq5PdbuG6cwmu6zmB5+en24MhgOkytz6zG0zaHFBnmNgaJpOQZIG4FUlZS2T1y8PjgDeER1/5/8rey3V69F7uu/c6BJM39V4jDZN377Ubnjf1XmNN/zcf3MpAthbcSlX1ENx6Gv8/RQnXGaIf0t815V//WqyZeLcdMHQ0vrblhC3nfHVu91pvgq+npxa2W+FVEl9H5tE1GwQY7c48NttbY6eB+HmZxy2FSwubrm/ZwhyjVwvTV+PPWZLrU0zaOE4yAe6c0AgWNKlbYxjiJEX7VVubRat6jkmMbiTYNRtIAU/HqTUvtS0FOAuplsV6BSmSsXeoXvdChh5kdQiVvoaHQTBRGyQfhsOh7qn62407uHzHtEF1RrwzhobR4aTYUo5wcGQnecDf1BvVmKBG6LheobkGaxZzNff33NGu9vVZs+x90R2glqKGf1IOGTA+CXOdC38BjK8YrXTncv2lDdtYctNA6C02FYCeqpj8NeWCv7M4vnzgEkA0nrcGLq4/RrP23dCjNWo3a3LeVKP9lDN0WX2ldoy73V88yZ3ZR9Yy2l635Vct9QcqzZTb1e3ZUo91jD1t/XdaFfwmW/UnmZLjXJcpKVVVTOkLRILsX/Wd8Os3JMfsz5AsPTXxJROfNoSVwMngC6MUi8KipnJVqtvPaLh5oND/Iai7T8slJK0ZDFn8FGCKfLkc44YiNPGQFqYpqmhMz7BHxa/jgVPWeMXKbe8Cb7sUvADUWrGqrUMNjBaswSWw1vMmU5iKp+OOjsO6wsxf8oMZYiuE9M3Bd7DPnCBbwDa9rsDWUy/6lBkH9+L7pME2T1LLoxww822vHTvznbRArujNaVGbkp1Zvmg1Zi+n6WeLWVv22rVAbg7UzNMUStAGOmVG1LM3A+CGLLesF364EIcTEkVi098QPeO7CEVERg8JRSmHCBbVdwaZ85+o+JJukrcvxppRNZSS8Aer3KDlnpgbf8KJVny0kw+cMkLFJ28q7zc8fPgGgbst0BUBoPRBF9pHBa7ToJaru/82alvHewR+Wn7YV1Cq/D7Smv4P \ No newline at end of file diff --git a/docs/images/INTO_CPS_modules.pdf b/docs/images/INTO_CPS_modules.pdf deleted file mode 100644 index 82c0718..0000000 Binary files a/docs/images/INTO_CPS_modules.pdf and /dev/null differ diff --git a/docs/images/INTO_CPS_modules.svg b/docs/images/INTO_CPS_modules.svg deleted file mode 100644 index 5c680c0..0000000 --- a/docs/images/INTO_CPS_modules.svg +++ /dev/null @@ -1,3 +0,0 @@ - - -
Current Editor
Current Editor
Graphical Editor
Graphical Edi...
!componentAdded
!componentAdded
Project Description
Project Description
mm.json
mm.json
SSP
SSP
Cloud hosted
Cloud h...
mm.json
mm.json
SSP
SSP
Cloud hosted
Cloud h...
Importer(s)
Importer(s)
Exporter(s)
Exporter(s)
Supported input formats
Supported input form...
Supported output formats
Supported output for...
addComponent(...)
addComponent(...)
User Interface Views
User Interface Views
COE Runner(s)
COE Runner(s)
Cloud COE
Cloud COE
MaestroV1
MaestroV1
Multiple Views Possible
Multiple Views Possible
Easy to switch between
Easy to switch between
Common in-memory representation of model,
independent of storage format.
Common in-memory representation of model...
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/docs/images/application_extracted.png b/docs/images/application_extracted.png deleted file mode 100644 index ddb4361..0000000 Binary files a/docs/images/application_extracted.png and /dev/null differ diff --git a/docs/images/application_preview.png b/docs/images/application_preview.png deleted file mode 100644 index e4f2f43..0000000 Binary files a/docs/images/application_preview.png and /dev/null differ diff --git a/docs/images/download_manager.png b/docs/images/download_manager.png deleted file mode 100644 index b5e25c2..0000000 Binary files a/docs/images/download_manager.png and /dev/null differ diff --git a/docs/images/github_actions.png b/docs/images/github_actions.png deleted file mode 100644 index 03449f9..0000000 Binary files a/docs/images/github_actions.png and /dev/null differ diff --git a/docs/images/github_preview.png b/docs/images/github_preview.png deleted file mode 100644 index 14b9cf6..0000000 Binary files a/docs/images/github_preview.png and /dev/null differ diff --git a/docs/images/into-cps-preview.png b/docs/images/into-cps-preview.png deleted file mode 100644 index 841bb37..0000000 Binary files a/docs/images/into-cps-preview.png and /dev/null differ diff --git a/docs/images/logo.svg b/docs/images/logo.svg deleted file mode 100644 index 1d97d02..0000000 --- a/docs/images/logo.svg +++ /dev/null @@ -1,219 +0,0 @@ - - - -image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - INTO-CPS - - - - - - - \ No newline at end of file diff --git a/docs/images/readthedocs_repository.drawio b/docs/images/readthedocs_repository.drawio deleted file mode 100644 index d467586..0000000 --- a/docs/images/readthedocs_repository.drawio +++ /dev/null @@ -1 +0,0 @@ -7VrbcqM4EP0aP4YChLF5nNiZnYdsbWpTU3N5EyCDNoAYIXzJ168EEiBjHJI49mQqTlWCWqIROqdPt6VMwCLd/kVhHv9NQpRMbDPcTsByYttTz+a/hWFXG+a2NEQUh7XJag33+BFJoymtJQ5RoQ1khCQM57oxIFmGAqbZIKVkow9bkUR/ag4j1DPcBzDpW7/hkMXSarle2/EF4Shm6v1mdUcK1WD5JkUMQ7LpmMDNBCwoIay+SrcLlIi1U+tS3/d5oLeZGEUZG3MDxI+/5tQH6UN+63+5RWH0k15ZcrYF26k35h3oXjYJZTGJSAaTm9Z63VpvCcn5MIsb/0OM7SR+sGSEm2KWJrKXz5HuvvOGaUxV84doqsZyq7V2shWUdI1C6aSeqpjf4BJIU0FKGqBj7y2pBGmE2JFxoAGKExyRFPHJ8fsoSiDDa30eUFItasbJWz9RCnedATnBGSs6nu+EgQ+QQWN5kjIyZuz5HrJ748Hx8fyinoFqdV6lNVVseQ5z5vUz1zAp5Tp8gyyIebDaZlngLOJ/N8iPCXnocYyhLdMJAhMcZfw64FAiyg1rRBnmcfhJdqQ4DCv2UVTgR+hXrgRF5Gpyv9PryXTJLQn0UXINg4eIkjILFyQhtHouWFWfhkriGWg7OaAj0n8bvV2SHYmkPlWke9PgsLgaTFdSCZ9Hph76V0pRlVvL1l2Q1argJNcZcRIOAPdM6rHF7LvSB379oxUS3mqlQzSUchSMkgfUwd6sPk2PUnP7VOoUwiK+qFSdRKv6YgR0cXFUW7moJybvegOO9XVmYruJkI8Qr/llJC7LPIQMTUS01n0+VV3Kwp/eueGAjyImm6yqL4Zu+fNVrI7oQRW7Mg3LBI6ebU6kYjPD3Bcy13Dcc2mZ1aPZvwiGgg6x4NWSBEWPALyky8VlsEtwFlaAb2LM0H0Oq5De8JJYJ4gvoEThrd8YGoD/KRn3gqS9Qv+OFJhhcpBRt3sDfMIYScdwkAnVHeZOT6MG2WC5ujQARbNNWymrIXG3RjaH2aHB+mwMrR5ET+cjWkMi4/BM2emE+WF6plL2dciA94KMlsb7pcJwWXHKlG+/C0zdnmTelUnSl8lzIK0quKbRwfpIBfc7oA1Ggj0gxucBG4ypwniSLFP+/rDKSWPrLopykcaImOXY4u0jEXcTMfjdEvF0DFsWJM1Jhqoq8NMH0GOAdmZ7Oz3OpSsuu4d0F9brSbP7+YHhAIaOeWEMFUQdDL9WX6dfksm1LZFXbRTriXz2/EQ+bu/nlGWbNzaT2xet27xBdV6RKmyDZuXcXyWphRiYS/HTNcmkj9YoITmiHQmv/QxouOjUsHHdxWIw4p6M3MGY74V0h2aklo1Fc2okyLHCSdKZ2KL6HKTTwvxsObwnojDEqH2djAgpasxLTLn3elqZCIbDRabUw3QbiSM0I0NsQ+hDYeTBaRTH9jzD6370DZxGkDoCNLMMB/Q1aPpmGnRol2+PN08y4TCBOqjvr7QPCxwYq4Rrx1GYT1GizT09c8/7iw6sM6446Ff0XwsRxAPZGgaMjEjVw4vYJ/57yNaWtZetp33cpgeytftmuHmXyMpqI8Ww1O5JnZbN45sponGHKOavLmBq83btzORhr2V5e/bUF/aqte/yOfn+0sc0r/0W/7IT5Zku+cB2ukR8crw9nx8fb4NXjQeOvRcYb3Bi7fTr3APfSv0SJ2ExevMirM4FXrht8SceIHlH5VQcIM0tHXwVOq89qDSbkqVxPNOdvOT0iDfb/9Gph7f/6ARu/gc= \ No newline at end of file diff --git a/docs/images/readthedocs_repository.svg b/docs/images/readthedocs_repository.svg deleted file mode 100644 index 3648d85..0000000 --- a/docs/images/readthedocs_repository.svg +++ /dev/null @@ -1,3 +0,0 @@ - - -
Watches using webhook
Watches using webhook
update
shown to
update...
Read the Docs
Read the D...
Pulls
Pulls
Documentation
repository
Documentat...
Component A
Component A
Component B
Component...
Updates
Updates
Developer
Developer
User
User
builds
docs
builds...
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/docs/images/sphinx.drawio b/docs/images/sphinx.drawio deleted file mode 100644 index 03bad84..0000000 --- a/docs/images/sphinx.drawio +++ /dev/null @@ -1 +0,0 @@ -7Vhbb5swFP41eWwEOCHJ45Jm3apWq5ZJ6R5dfAreDEbGFLJfPzuYAHF6WZUUdepL5HN8bDjfd25hgBZxeSFwGl1zAmzgOaQcoPOB503ckfrVik2lmM28ShEKSiqV2yhW9A8YpWO0OSWQdQwl50zStKsMeJJAIDs6LAQvumb3nHWfmuIQLMUqwMzWrimRkdG6/qzZ+AI0jMyjp96k2ohxbWw8ySJMeNFSoeUALQTnslrF5QKYxq7GpTr3+ZHd3YsJSORLDowWF2gp1t9vz9YPl+zb+lJch2fj6pYHzHLjcEruzfvKTQ1CEVEJqxQHWi4UzwM0j2TMlOSqpfIs1TtxGeoYGN7hjAZDwoM83r7b/J4n0lCr4gHNzUNBSCgf9cbdYaRiC3gMUmyUiTkw8qbVERNXqIa5aFgaG++iFj++b2LDxEW4u7mBTi0Mev+A5NRCDYiKJCNyISMe8gSzZaOdC54nBPStjpIamyvOU4PtL5ByY7DDueRd5BVYYnNrzm+Fn1oYjmvxvGxvnm/a0g0IqnwHYZSHWdJePM2RcprnIoAnwKkzF4sQ5BN2/mHOBTAs6UP3PY7O4KwXBksqb1vrFn9KaujTQoe9/4j1cZ+s143mg/a3pn3SK+1W41ulEU1KKxi6VD/TCY/Q2Dzf2WtsyGpsbt3sOp3NORFUvgXV1uN3OCR4o56HhIkF5XA4fI9IjpyekXRRH2X7lFXzpWXzEaLeqGzadVMoeEUeyFwA+QGlPHk4M3wH7IZnVFKeKGWgzHRfm+sIp+qv29WegdTszjGj4UHzT2bjjkvJ4+PkizvuVnFv0ne+jHoZc145spwyz7x3kWeelWfXWPwmvEg+8utAfqHe88v+kvI1SXNVDR2GkzDHIWR2BjJG0wyenyv3KSJUQGDQLyDbskgZW3DG9YCf8ERfSnAWbbPXfQ2rO7qeJbbi/xisuntV88CU4aKpTeuuvB6fV3tk+1FVDs+5+iD2hcSiqT8cvx21Smy+q273Wh+n0fIv \ No newline at end of file diff --git a/docs/images/sphinx.svg b/docs/images/sphinx.svg deleted file mode 100644 index 11d31ae..0000000 --- a/docs/images/sphinx.svg +++ /dev/null @@ -1,3 +0,0 @@ - - -
pdf
pdf
Sphinx
Sphinx
html
html
...
...
reStructuredText
reStruct...
Markdown
Markdown
Input languages
Input languages
Target Languages
Target Languages
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/docs/images/submodule_documentation.drawio b/docs/images/submodule_documentation.drawio deleted file mode 100644 index b454afe..0000000 --- a/docs/images/submodule_documentation.drawio +++ /dev/null @@ -1 +0,0 @@ -3Vlbc9o6EP41foTxJdwegeT0ZKY5zUw67WNGWMJWI1uOLAfor+/Kkm184ZrCScsL1kparff7dlcLljeP1p8ESsIHjgmzXBuvLe/Wcl1nNBrAl5JstGQycbUgEBSbRZXgif4kRmgbaUYxSWsLJedM0qQu9HkcE1/WZEgIvqovW3JWPzVBAWkJnnzE2tLvFMvQSJ3hpJr4l9AgNEeP3ZGeiFCx2LxJGiLMV1si787y5oJzqZ+i9Zww5bzCL3rfPztmS8MEieUxGxYPt19e0Lchv5evrw/+t9W0N+15WssbYpl5YcsdMtA3W3JQC1bLjXHF8DXjxUQvzYGawgJ3mKyrSXgK1He/3y8UgUVal54xzijVupKslTyUEQOBA4+I0SCGZx/ejAgQvBEhKWAyNRMRxVhtnwkChqBFrsqGccJpLHPEBzNrcKt0ZZJrY3PV5nVBH1nv9KNTogO0JjwiUmxgidngjQyghtFeAfCq4seNEYVbzCiWIcPIoNRcgQYPBrcTMLxpYXgfY/pGcYbU3k9U4ShIAn6QXFCIpiYEQM1EPfqZYJuZQP4LUZCsQirJU4J8NbeC+K7DJHgWY4LNCFMB8Ue5wifmQnlixtCCsEd1rpa3AP3cWLDgUvLoGApInvweOF13UIdz0obT866Jp+N0BGUDsQCcn+x8e5MMTWBUKeh4rzjjOsndcdsrzqjDK87NxdzS8soDIqkUXAnbHqrYaR+m8slE1fQ7yNKSz0cRdQ8bdtO3jpPTAdOgA6bJxVDaXVEgJ6kTjWuqmvEjSyVdbtpFxHJnvV4Pcz8tVCxEOTcC+4YoUjDEi1Qng+bYpkCBdV+k8lwFIV89S/5M41Qixt6jaasibm2tamTunbr0DId9mAM+fJE/J9i8eqkoKsd2sLlXDbZ26a9Bq8G4/+/rl9788ekILmjRLfezCByF8mR3LuR/YAI+kGon9VzbcVG4cq4dfKBce+r43bn55AMDIiWNg2dI5cACfM2j9yb/vyCZHkibdiNwOvJm1w17fLHAGbd8SjC0/Waouhce8Bixu0o6q+ezas1nrlJR7qsfwLCN+Q1DubEOEkZpWLZL2gB16n6ngpE8Ez45mAba3heEQQZ/qx/Q5Uuz9VFRYSvdNfpcp6lCG2Z2bf/w0FTUuKOW3VShCOIRYrOlaCoE2mwtM1TdaXCZfBsG77Krub6wq2KWtqDiWencd1Bv0srZNPZZhjva8svGeV5yZ9DrBzmz55xxkZ/rLfPPvtg/psHcE3k7M4Xddwe2OeNc+hZL+HKZEmk1c8VvwNDt6nGu3KDfNIKq8zbS1aBf7DbitpxSXTxtlCQMeKovlLbPeIb/hgvjHnq0kfvfkHHa0PzJPTkc/kIE9OSAYCByTl2tMf/wN7GTGFkWwnrd7Liedf2gPTydrzCs/vDQ6bj628i7+wU= \ No newline at end of file diff --git a/docs/images/submodule_documentation.svg b/docs/images/submodule_documentation.svg deleted file mode 100644 index 45c11e2..0000000 --- a/docs/images/submodule_documentation.svg +++ /dev/null @@ -1,3 +0,0 @@ - - -
...
...
Individual Git repositories
Individual Git repositories
Maestro v2
Maestro v2
+---docs
|   index.rst
|   how_to_install.rst
|   ...


+---docs...
INTO-CPS
Documentation
INTO-CPS...
+---docs
|      index.rst
|      getting_started.rst
|      ...

+---docs...
includes
includes
INTO-CPS application cloud
INTO-CPS application cloud
+---docs
|   index.rst
|   docker_intergration.rst
|   ...
+---docs...
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/docs/images/user_interface_overview.png b/docs/images/user_interface_overview.png deleted file mode 100644 index 644c0ec..0000000 Binary files a/docs/images/user_interface_overview.png and /dev/null differ diff --git a/docs/index.rst b/docs/index.rst deleted file mode 100644 index 900ed60..0000000 --- a/docs/index.rst +++ /dev/null @@ -1,23 +0,0 @@ -INTO-CPS Desktop Application -============================ -Welcome to the INTO-CPS Desktop Application documentation. -The best way to get started is to follow the :ref:`first_steps` guide which guides you thorugh the installation process and the basics of the application. - -.. image:: images/application_preview.png - -For a guide on how to use the various features of the application :ref:`user_interface` provides an overview of how to access the most important functionality. - -.. note:: - The INTO-CPS Toolchain refers to a collection of programs not limited to the the desktop application. - For an comprehensive overview of all tools take a look at the `INTO-CPS toolchain documentation `__ - -.. toctree:: - :maxdepth: 2 - :caption: Content - :hidden: - - first_steps - interface - integrations - tutorials - developer_documentation \ No newline at end of file diff --git a/docs/integrations.rst b/docs/integrations.rst deleted file mode 100644 index fe3098c..0000000 --- a/docs/integrations.rst +++ /dev/null @@ -1,16 +0,0 @@ -Integrations -============ - -The application is built in a modular fashion that allows extra functionality to be accessed from within the application by installing extenal tools. -Typically, these are installed using the :ref:`download_manager`, however there are some cases where a plugin must be installed manually. - -Below is a overview of the different integrations in terms of the funcationality they provide and how to install them. - - -Modelio -------- -Modelio is a combined UML/BPMN modeler supporting a wide range of models and diagrams. - - -.. warning:: - integrate `this `__ \ No newline at end of file diff --git a/docs/interface.rst b/docs/interface.rst deleted file mode 100644 index 5fddbdb..0000000 --- a/docs/interface.rst +++ /dev/null @@ -1,57 +0,0 @@ -.. _user_interface: - -User Interface -============== - -The INTO-CPS Application is the front-end of the INTO-CPS tool chain. The following screenshot shows how it looks. - -.. warning:: - Here we should explain in simple terms how to use the application. - Important concepts such as multimodel-config and co-simulation configuration should be explained! - - Additionally, a video demonstation would go a long way - - Also we need need to consider what we are trying to convey. For example what information does the old docs convey: - - :: - - The app is composed of 2 primary views: On the left, the project browser left is always visible. It shows the various components of an INTO-CPS project. These components can be clicked to trigger various actions. - In the center, the main view is shown. The contents of this view depend on which action has been trigerred in the project browser. A few example views are shown below. - - -Overview --------- -The app is composed of 2 primary views: On the left, the project browser left is always visible. It shows the various components of an INTO-CPS project. These components can be clicked to trigger various actions. -In the center, the main view is shown. The contents of this view depend on which action has been trigerred in the project browser. A few example views are shown below. - -.. image:: images/user_interface_overview.png - :height: 400 - :align: center - :alt: Overview of most important interface components - - -Important Functionality ------------------------ - -.. warning:: - here we should describe how to use the various components of the application - -.. _download_manager: - -Download Manager -^^^^^^^^^^^^^^^^ - - -Example Projects -^^^^^^^^^^^^^^^^ - - -Plotting -^^^^^^^^ - - -Design-Space Exploration -^^^^^^^^^^^^^^^^^^^^^^^^ - - - diff --git a/docs/make.bat b/docs/make.bat deleted file mode 100644 index 922152e..0000000 --- a/docs/make.bat +++ /dev/null @@ -1,35 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=. -set BUILDDIR=_build - -if "%1" == "" goto help - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 -) - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% - -:end -popd diff --git a/docs/tutorials.rst b/docs/tutorials.rst deleted file mode 100644 index 7ab6a9b..0000000 --- a/docs/tutorials.rst +++ /dev/null @@ -1,7 +0,0 @@ -Tutorials -========= - -.. _example-wt: - -Simulating the Water Tank Example ---------------------------------- \ No newline at end of file diff --git a/downloader-test/downloader-test.js b/downloader-test/downloader-test.js deleted file mode 100644 index f7aab5e..0000000 --- a/downloader-test/downloader-test.js +++ /dev/null @@ -1,92 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - - -#!/usr/bin/env node - -console = require("console"); -downloader = require("../dist/downloader/Downloader"); - -const VERSIONS_URL = "http://overture.au.dk/into-cps/site/download/versions.json"; -function progress(state) { - console.log(parseInt(state.percentage * 100, 10) + "%"); -} - - -function testDownloadAndUnpack() { - var tool; - console.log("Fetching list of available version") - return downloader.fetchVersionList(VERSIONS_URL) - .then(function (data) { - console.log(JSON.stringify(data) + "\n"); - console.log("Fetching version 0.0.6"); - return downloader.fetchVersion(data["0.0.6"]); - }) - .then(function(data) { - console.log(JSON.stringify(data) + "\n"); - console.log("Downloading tool: Overture Tool Wrapper"); - tool = data.tools.overtureToolWrapper; - return downloader.downloadTool(tool, ".", progress); - }).then(function (filePath) { - console.log("Download complete: " + filePath); - console.log("Unpacking tool"); - return downloader.installTool(tool, filePath, "installed"); - }) - .then(function () { - console.log("Installation complete\n"); - return; - }, function (error) { - console.log(error); - }); -} - -function testInstallerLaunch() { - var dummyTool = { - platforms: { - linux64: { - action: "launch" - } - } - }; - - console.log("Running dummy tool installer"); - downloader.installTool(dummyTool, "./dummy_installer.sh", ".") - .then(function (stdout) { - console.log("Dummy tool installer stdout:"); - console.log(stdout + "\n"); - console.log("Dummy tool installation successful"); - }, function (error) { - console.log(error); - }); -} - -testDownloadAndUnpack() -.then(testInstallerLaunch); diff --git a/downloader-test/dummy_installer.sh b/downloader-test/dummy_installer.sh deleted file mode 100755 index 451138c..0000000 --- a/downloader-test/dummy_installer.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash - -## -## This file is part of the INTO-CPS toolchain. -## -## Copyright (c) 2017-CurrentYear, INTO-CPS Association, -## c/o Professor Peter Gorm Larsen, Department of Engineering -## Finlandsgade 22, 8200 Aarhus N. -## -## All rights reserved. -## -## THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR -## THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. -## ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES -## RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL -## VERSION 3, ACCORDING TO RECIPIENTS CHOICE. -## -## The INTO-CPS toolchain and the INTO-CPS Association Public License -## are obtained from the INTO-CPS Association, either from the above address, -## from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. -## GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. -## -## This program is distributed WITHOUT ANY WARRANTY; without -## even the implied warranty of MERCHANTABILITY or FITNESS FOR -## A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE -## BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF -## THE INTO-CPS ASSOCIATION. -## -## See the full INTO-CPS Association Public License conditions for more details. -## -## See the CONTRIBUTORS file for author and contributor information. -## - - -echo "I am just a dummy! Dummy!" diff --git a/gulpfile.js b/gulpfile.js deleted file mode 100644 index 9996b94..0000000 --- a/gulpfile.js +++ /dev/null @@ -1,410 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -"use strict"; - -// file globs -var outputPath = "dist/", - htmlSrcs = ["src/**/*.html"], - jsSrcs = "src/**/*.js", - tsSrcs = ["src/**/*.ts"], - resourcesFolder = "src/resources", - cssSrcs = [ - "src/styles.css", - "src/resources/bootstrap/css/bootstrap.css", - resourcesFolder + "/w2ui-1.5/w2ui.min.css" - ], - customResources = [resourcesFolder + "/into-cps/**/*"], - configJsons = ["./package.json"]; -// Gulp plugins -var gulp = require("gulp"), - ts = require("gulp-typescript"), - sourcemap = require("gulp-sourcemaps"), - tsProject = ts.createProject("tsconfig.json"), - del = require("del"), - filter = require("gulp-filter"), - debug = require("gulp-debug"), - merge = require("merge-stream"), - packager = require("electron-packager"), - packageJSON = require("./package.json"), - webpack = require("webpack"), - htmlhint = require("gulp-htmlhint"), - runSequence = require("run-sequence"), - bump = require("gulp-bump"), - gutil = require("gulp-util"), - git = require("gulp-git"), - fs = require("fs"), - minimist = require("minimist"), - semver = require("semver"), - cleancss = require("gulp-clean-css"), - uglify = require("gulp-uglify"), - pipeline = require('readable-stream').pipeline, - saveLicense = require("uglify-save-license"), - zip = require('gulp-zip'); -// Tasks - -// Automated Release Prep - -function getPackageJson() { - // multiple calls so the version number won't be updated - return JSON.parse(fs.readFileSync("./package.json", "utf8")); -} - -var knownOptions = { - string: "vt", - boolean: "rel", - boolean: "verbose", - default: { vt: "patch", rel: false, verbose: false, } -}; - -var options = minimist(process.argv.slice(2), knownOptions); - -gulp.task("bump-rel", function () { - var pkg = getPackageJson(); - var newVer = semver.inc(pkg.version, options.vt); - - if (!options.rel) { - newVer += "-rc"; - } - - return gulp - .src(configJsons) - - .pipe(bump({ version: newVer })) - .pipe(gulp.dest("./")); -}); - -gulp.task("bump-dev", function () { - var pkg = getPackageJson(); - var newVer = semver.inc(pkg.version, "prepatch", "dev"); - newVer = newVer.slice(0, -2); - - return gulp - .src(configJsons) - .pipe(bump({ version: newVer })) - .pipe(gulp.dest("./")); -}); - -gulp.task("commit-changes", function () { - return gulp - .src(["./package.json"]) - .pipe(git.add()) - .pipe(git.commit("[GULP] Bump version number")); -}); - -gulp.task("push-changes", function (cb) { - git.push("origin", "master", cb); -}); - -gulp.task("create-new-tag", function (cb) { - var version = getPackageJson().version; - var tag = "v" + version; - git.tag(tag, "Created Tag for version: " + version, function (error) { - if (error) { - return cb(error); - } - git.push("origin", "master", { args: "--tags" }, cb); - }); -}); - -gulp.task("prep-release", - gulp.series( - "bump-rel", - "commit-changes", - "push-changes", - "create-new-tag" - ) -); - -gulp.task("prep-new-dev", - gulp.series( - "bump-dev", - "commit-changes", - "push-changes" - ) -); - -// Clean everything! -gulp.task("clean", function () { - return del([outputPath]); -}); - -// Compile and uglify. Only used for packaged app -gulp.task("compile-ts-uglify", function () { - return pipeline( - gulp.src(tsSrcs), - tsProject(), - uglify({ - output: { comments: saveLicense } - }), - gulp.dest(outputPath)); -}); - -// Compile TS->JS with sourcemaps. -gulp.task("compile-ts", function () { - var tsResult = gulp - .src(tsSrcs) - .pipe(sourcemap.init()) - .pipe(tsProject()); - - return tsResult.js.pipe(sourcemap.write()).pipe(gulp.dest(outputPath)); -}); - -// Compile Angular 2 application -gulp.task("compile-ng2", function (callback) { - webpack(require("./webpack.config.js"), function (err, stats) { - if(options.verbose) { - if (err) { guitl.log(err); } - if (stats) { gutil.log(stats); } - } - callback(); - }); -}); - -// Copy bootstrap fonts to destination -gulp.task("copy-fonts", function () { - return gulp - .src("src/resources/bootstrap/fonts/**/*") - .pipe(gulp.dest(outputPath + "fonts")); -}); - -// Copy custom resources -gulp.task("copy-custom", function () { - return gulp - .src(customResources) - .pipe(gulp.dest(outputPath + "resources/into-cps")); -}); - -// Copy css to app folder -gulp.task("copy-css", function () { - return gulp - .src(cssSrcs) - .pipe(cleancss()) - .pipe(gulp.dest(outputPath + "css")); -}); - -// Copy html to app folder -gulp.task("copy-html", function () { - return gulp - .src(htmlSrcs) - .pipe( - htmlhint({ - "attr-lowercase": [ - "formControlName", - "formGroupName", - "formArrayName", - "*ngIf", - "*ngFor", - "[(ngModel)]", - "[formGroup]", - "[formControl]", - "(ngSubmit)", - "#configForm", - "[basePath]", - "(pathChange)", - "[ngModel]", - "(ngModelChange)", - "[ngValue]", - "[ngModelOptions]" - ], - "doctype-first": false - }) - ) - .pipe(htmlhint.reporter()) - .pipe(gulp.dest(outputPath)); -}); - -// Copy js to app folder -gulp.task("copy-js", function () { - return ( - gulp - .src(jsSrcs) - // process js here if needed - .pipe(gulp.dest(outputPath)) - ); -}); - -//Build App for debugging -gulp.task( - "build", - gulp.series( - "compile-ts", - "compile-ng2", - "copy-js", - "copy-html", - "copy-css", - "copy-fonts", - "copy-custom" - ) -); - -//Prep App for packaging -gulp.task( - "prep-pkg", - gulp.series( - "compile-ts-uglify", - "compile-ng2", - "copy-js", - "copy-html", - "copy-css", - "copy-fonts", - "copy-custom" - ) -); - -//Build packages -gulp.task("pkg-darwin", function (done) { - var options = { - dir: ".", - name: packageJSON.name + "-" + packageJSON.version, - platform: "darwin", - arch: "x64", - overwrite: true, - prune: true, - icon: "src/resources/into-cps/appicon/into-cps-logo.png.icns", - out: "pkg", - "app-version": packageJSON.version, - "version-string": { - CompanyName: packageJSON.author.name, - ProductName: packageJSON.productName - } - }; - - return packager(options) - .then(appPaths => { - console.log(appPaths); - return; - }) - .catch((e) => console.error(e)); -}); - -gulp.task('package-darwin', gulp.series('clean', 'prep-pkg', 'pkg-darwin')); - - -gulp.task("pkg-linux", function (callback) { - var options = { - dir: '.', - name: packageJSON.name + '-' + packageJSON.version, - platform: "linux", - arch: "ia32,x64", - overwrite: true, - prune: true, - out: 'pkg', - "app-version": packageJSON.version, - "version-string": { - "CompanyName": packageJSON.author.name, - "ProductName": packageJSON.productName - } - }; - - return packager(options) - .then(appPaths => { - console.log(appPaths); - return; - }) - .catch((e) => console.error(e)); -}); - -gulp.task('package-linux', gulp.series('clean', 'prep-pkg', 'pkg-linux')); - - -gulp.task("pkg-win32", function (callback) { - var options = { - dir: ".", - name: packageJSON.name + "-" + packageJSON.version, - platform: "win32", - arch: "all", - overwrite: true, - prune: true, - icon: "src/resources/into-cps/appicon/into-cps-logo.png.ico", - out: "pkg", - "app-version": packageJSON.version, - "version-string": { - CompanyName: packageJSON.author.name, - ProductName: packageJSON.productName - } - }; - return packager(options).then(appPaths => { - console.log(appPaths); - return; - }) - .catch((e) => console.error(e)); -}); - -gulp.task("package-win32", gulp.series("clean", "prep-pkg", "pkg-win32")); - -gulp.task("package-all", - gulp.series( - "package-win32", - "package-linux", - "package-darwin") -); - -gulp.task("pkg", function (callback) { - del('pkg'); - del('zipped'); - var options = { - dir: ".", - name: packageJSON.name + "-" + packageJSON.version, - overwrite: true, - prune: true, - icon: "src/resources/into-cps/appicon/into-cps-logo.png.ico", - out: "pkg", - "app-version": packageJSON.version, - "version-string": { - CompanyName: packageJSON.author.name, - ProductName: packageJSON.productName - } - }; - return packager(options).then(appPaths => { - gulp.src(appPaths[0] + '/**') - .pipe(zip(appPaths[0] + '.zip')) - .pipe(gulp.dest('zipped')) - }) - .catch((e) => console.error(e)); -}); - - -gulp.task("package", gulp.series("clean", "prep-pkg", "pkg")); - - - -// Watch for changes and rebuild on the fly -gulp.task("watch", function () { - gulp.watch(htmlSrcs, ["copy-html"]); - gulp.watch(jsSrcs, ["copy-js"]); - gulp.watch(tsSrcs, ["compile-ts"]); - gulp.watch(cssSrcs, ["copy-css"]); - gulp.watch(customResources, ["copy-custom"]); -}); - -// Default task -gulp.task("default", gulp.series("build")); diff --git a/gulpfile.mjs b/gulpfile.mjs new file mode 100644 index 0000000..2e886cc --- /dev/null +++ b/gulpfile.mjs @@ -0,0 +1,181 @@ +/* + * This file is part of the INTO-CPS toolchain. + * + * Copyright (c) 2017-CurrentYear, INTO-CPS Association, + * c/o Professor Peter Gorm Larsen, Department of Engineering + * Finlandsgade 22, 8200 Aarhus N. + * + * All rights reserved. + * + * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR + * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. + * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES + * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL + * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. + * + * The INTO-CPS toolchain and the INTO-CPS Association Public License + * are obtained from the INTO-CPS Association, either from the above address, + * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. + * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. + * + * This program is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE + * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF + * THE INTO-CPS ASSOCIATION. + * + * See the full INTO-CPS Association Public License conditions for more details. + * + * See the CONTRIBUTORS file for author and contributor information. + */ + +"use strict"; + +import gulp from "gulp"; +import fs from 'fs'; +import path from 'path'; +import ts from "gulp-typescript"; +import sourcemap from "gulp-sourcemaps"; +import htmlhint from "gulp-htmlhint"; +import cleancss from "gulp-clean-css"; +import {deleteAsync} from 'del'; + +// File globs +var outputPath = "dist/", + htmlSrcs = ["src/**/*.html"], + jsSrcs = "src/**/*.js", + tsSrcs = ["src/**/*.ts"], + resourcesFolder = "src/resources", + cssSrcs = [ + "src/styles.css", + "src/resources/bootstrap/css/bootstrap.css", + resourcesFolder + "/w2ui-2.0/w2ui-2.0.css" + ], + customResources = [resourcesFolder + "/**/*", "!" + resourcesFolder + "/**/*.{png,ico,jpg,jpeg,gif}" ]; + +// Gulp plugins +const tsProject = ts.createProject("tsconfig.json"); + +// Clean output directory +gulp.task("clean", async function () { + return await deleteAsync([outputPath]); +}); + +// Copy custom resources +gulp.task("copy-custom", function () { + return gulp + .src(customResources) + .pipe(gulp.dest(outputPath + "resources")); +}); + +// Copy immages to resources folder +gulp.task("copy-images", function (done) { + const imageExtensions = ['.png', '.jpg', '.jpeg', '.gif', '.ico']; + const sourceDir = resourcesFolder; + const destDir = path.join(outputPath, 'resources/'); + + if (!fs.existsSync(destDir)) { + fs.mkdirSync(destDir, { recursive: true }); + } + + const copyImagesRecursively = (srcDir, destDir) => { + const files = fs.readdirSync(srcDir); + + files.forEach(file => { + const sourceFile = path.join(srcDir, file); + const destFile = path.join(destDir, file); + const stats = fs.statSync(sourceFile); + + if (stats.isDirectory()) { + if (!fs.existsSync(destFile)) { + fs.mkdirSync(destFile); + } + copyImagesRecursively(sourceFile, destFile); + } else if (imageExtensions.includes(path.extname(file).toLowerCase())) { + fs.copyFileSync(sourceFile, destFile); + } + }); + }; + + copyImagesRecursively(sourceDir, destDir); + + done(); +}); + + +// Copy css to app folder +gulp.task("copy-css", function () { + return gulp + .src(cssSrcs, { allowEmpty: true }) //allowEmpty to be removed when all css files are in place + .pipe(cleancss()) + .pipe(gulp.dest(outputPath + "css")); +}); + +// Copy html to app folder +gulp.task("copy-html", function () { + return gulp + .src(htmlSrcs) + .pipe( + htmlhint({ + "attr-lowercase": [ + "formControlName", + "formGroupName", + "formArrayName", + "*ngIf", + "*ngFor", + "[(ngModel)]", + "[formGroup]", + "[formControl]", + "(ngSubmit)", + "#configForm", + "[basePath]", + "(pathChange)", + "[ngModel]", + "(ngModelChange)", + "[ngValue]", + "[ngModelOptions]" + ], + "doctype-first": false + }) + ) + .pipe(htmlhint.reporter()) + .pipe(gulp.dest(outputPath)); +}); + +// Copy js to app folder +gulp.task("copy-js", function () { + return ( + gulp + .src(jsSrcs) + // process js here if needed + .pipe(gulp.dest(outputPath)) + ); +}); + +// Compile TS->JS with sourcemaps. +gulp.task("compile-ts", function () { + return gulp.src(tsSrcs) + .pipe(sourcemap.init()) + .pipe(tsProject()) + .pipe(sourcemap.write()) + .pipe(gulp.dest(outputPath)); +}); + +// Build task +gulp.task( + "build", + gulp.series( + "compile-ts", + "copy-js", + "copy-html", + "copy-css", + "copy-custom", + "copy-images") +); +// Watch for changes and rebuild +gulp.task("watch", function () { + gulp.watch(tsSrcs, gulp.series("build")); +}); + +// Default task +gulp.task("default", gulp.series("build")); diff --git a/mcr.config.ts b/mcr.config.ts new file mode 100644 index 0000000..17429db --- /dev/null +++ b/mcr.config.ts @@ -0,0 +1,30 @@ +import { CoverageReportOptions} from "monocart-coverage-reports" + +// https://github.com/cenfun/monocart-coverage-reports +const coverageOptions: CoverageReportOptions = { + + name: 'Coverage Report', + + reports: [ + 'console-details', + 'v8', + "lcovonly" + ], + + entryFilter: { + '**/node_modules/**': false, + '**/dist/**': false, + 'src/**/*.ts': true, + 'src/**/*.js': true + }, + sourceFilter: { + '**/node_modules/**': false, + '**/dist/**': false, + 'src/**/*.ts': true, + 'src/**/*.js': true + }, + + outputDir: 'test/coverage-reports' +} + +export default coverageOptions \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index e9ec6df..5303084 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,22956 +1,10852 @@ { - "name": "into-cps-app", - "version": "4.0.8-dev", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "7zip-bin": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.1.1.tgz", - "integrity": "sha512-sAP4LldeWNz0lNzmTird3uWfFDWWTeg6V/MsmyyLR9X1idwKBWIgt/ZvinqQldJm3LecKEs1emkbquO6PCiLVQ==", - "dev": true - }, - "@angular-devkit/architect": { - "version": "0.13.10", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.13.10.tgz", - "integrity": "sha512-FC+YmeXwFdNMmqnX1nIOkXBQMxWQSbgYz5crWcb7FtOWTNH1IgM/22tZ6lpf3kiAfTtBbnb7oTkA4Y69nUaoQg==", - "requires": { - "@angular-devkit/core": "7.3.10", - "rxjs": "6.3.3" - }, - "dependencies": { - "rxjs": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", - "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", - "requires": { - "tslib": "^1.9.0" - } - } - } - }, - "@angular-devkit/build-angular": { - "version": "0.901.15", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-0.901.15.tgz", - "integrity": "sha512-Qhyfnjda+lbI97xpimb0g6RYiu/Xf/Awtx2xBRaE0pGW/T/qrGEeKwF4mu2CAgDSHK+0+V1msW8ttPMw+Z8org==", - "dev": true, - "requires": { - "@angular-devkit/architect": "0.901.15", - "@angular-devkit/build-optimizer": "0.901.15", - "@angular-devkit/build-webpack": "0.901.15", - "@angular-devkit/core": "9.1.15", - "@babel/core": "7.9.0", - "@babel/generator": "7.9.3", - "@babel/preset-env": "7.9.0", - "@babel/template": "7.8.6", - "@jsdevtools/coverage-istanbul-loader": "3.0.3", - "@ngtools/webpack": "9.1.15", - "ajv": "6.12.3", - "autoprefixer": "9.7.4", - "babel-loader": "8.0.6", - "browserslist": "^4.9.1", - "cacache": "15.0.0", - "caniuse-lite": "^1.0.30001032", - "circular-dependency-plugin": "5.2.0", - "copy-webpack-plugin": "6.0.3", - "core-js": "3.6.4", - "css-loader": "3.5.1", - "cssnano": "4.1.10", - "file-loader": "6.0.0", - "find-cache-dir": "3.3.1", - "glob": "7.1.6", - "jest-worker": "25.1.0", - "karma-source-map-support": "1.4.0", - "less": "3.11.3", - "less-loader": "5.0.0", - "license-webpack-plugin": "2.1.4", - "loader-utils": "2.0.0", - "mini-css-extract-plugin": "0.9.0", - "minimatch": "3.0.4", - "open": "7.0.3", - "parse5": "4.0.0", - "postcss": "7.0.27", - "postcss-import": "12.0.1", - "postcss-loader": "3.0.0", - "raw-loader": "4.0.0", - "regenerator-runtime": "0.13.5", - "rimraf": "3.0.2", - "rollup": "2.1.0", - "rxjs": "6.5.4", - "sass": "1.26.3", - "sass-loader": "8.0.2", - "semver": "7.1.3", - "source-map": "0.7.3", - "source-map-loader": "0.2.4", - "speed-measure-webpack-plugin": "1.3.1", - "style-loader": "1.1.3", - "stylus": "0.54.7", - "stylus-loader": "3.0.2", - "terser": "4.6.10", - "terser-webpack-plugin": "3.0.3", - "tree-kill": "1.2.2", - "webpack": "4.42.0", - "webpack-dev-middleware": "3.7.2", - "webpack-dev-server": "3.11.0", - "webpack-merge": "4.2.2", - "webpack-sources": "1.4.3", - "webpack-subresource-integrity": "1.4.0", - "worker-plugin": "4.0.3" - }, - "dependencies": { - "@angular-devkit/architect": { - "version": "0.901.15", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.901.15.tgz", - "integrity": "sha512-t4yT34jQ3wA3NFZxph/PquITv8tFrkaexUusbNp4UN10+k+04lPF3aPnJJhM1VKjjfChznMMhLnqLjA+9o0Rmw==", - "dev": true, - "requires": { - "@angular-devkit/core": "9.1.15", - "rxjs": "6.5.4" - } - }, - "@angular-devkit/core": { - "version": "9.1.15", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-9.1.15.tgz", - "integrity": "sha512-zyUDaFQvnqsptoXhodbH4u+voXIldfDx+d0M2OMLj0tbfD4zp2fy7UOeTvu+lq2/LLNAObkG4JSK5DM9v1s08w==", - "dev": true, - "requires": { - "ajv": "6.12.3", - "fast-json-stable-stringify": "2.1.0", - "magic-string": "0.25.7", - "rxjs": "6.5.4", - "source-map": "0.7.3" - } - }, - "ajv": { - "version": "6.12.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz", - "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "cacache": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.0.0.tgz", - "integrity": "sha512-L0JpXHhplbJSiDGzyJJnJCTL7er7NzbBgxzVqLswEb4bO91Zbv17OUMuUeu/q0ZwKn3V+1HM4wb9tO4eVE/K8g==", - "dev": true, - "requires": { - "chownr": "^1.1.2", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", - "infer-owner": "^1.0.4", - "lru-cache": "^5.1.1", - "minipass": "^3.1.1", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^1.0.3", - "move-concurrently": "^1.0.1", - "p-map": "^3.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^2.7.1", - "ssri": "^8.0.0", - "tar": "^6.0.1", - "unique-filename": "^1.1.1" - }, - "dependencies": { - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "requires": { - "is-docker": "^2.0.0" - } - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "minipass": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.5.tgz", - "integrity": "sha512-+8NzxD82XQoNKNrl1d/FSi+X8wAEWR+sbYAfIvub4Nz0d22plFG72CEVVaufV8PNf4qSslFTD8VMOxNVhHCjTw==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, - "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - } - }, - "open": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/open/-/open-7.0.3.tgz", - "integrity": "sha512-sP2ru2v0P290WFfv49Ap8MF6PkzGNnGlAwHweB4WR4mr5d2d0woiCluUeJ218w7/+PmoBy9JmYgD5A4mLcWOFA==", - "dev": true, - "requires": { - "is-docker": "^2.0.0", - "is-wsl": "^2.1.1" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "rxjs": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", - "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "semver": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.1.3.tgz", - "integrity": "sha512-ekM0zfiA9SCBlsKa2X1hxyxiI4L3B6EbVJkkdgQXnSEEaHlGdvyodMruTiulSRWMMB4NeIuYNMC9rTKTz97GxA==", - "dev": true - }, - "serialize-javascript": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz", - "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "ssri": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", - "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", - "dev": true, - "requires": { - "minipass": "^3.1.1" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "tar": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", - "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", - "dev": true, - "requires": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "dependencies": { - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-3.0.3.tgz", - "integrity": "sha512-bZFnotuIKq5Rqzrs+qIwFzGdKdffV9epG5vDSEbYzvKAhPeR5RbbrQysfPgbIIMhNAQtZD2hGwBfSKUXjXZZZw==", - "dev": true, - "requires": { - "cacache": "^15.0.4", - "find-cache-dir": "^3.3.1", - "jest-worker": "^26.0.0", - "p-limit": "^2.3.0", - "schema-utils": "^2.6.6", - "serialize-javascript": "^3.1.0", - "source-map": "^0.6.1", - "terser": "^4.6.13", - "webpack-sources": "^1.4.3" - }, - "dependencies": { - "cacache": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", - "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", - "dev": true, - "requires": { - "@npmcli/fs": "^1.0.0", - "@npmcli/move-file": "^1.0.1", - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", - "infer-owner": "^1.0.4", - "lru-cache": "^6.0.0", - "minipass": "^3.1.1", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^1.0.3", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^8.0.1", - "tar": "^6.0.2", - "unique-filename": "^1.1.1" - } - }, - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true - }, - "jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", - "dev": true, - "requires": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - } - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "terser": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", - "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - } - } - } - }, - "webpack": { - "version": "4.42.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.42.0.tgz", - "integrity": "sha512-EzJRHvwQyBiYrYqhyjW9AqM90dE4+s1/XtCfn7uWg6cS72zH+2VPFAlsnW0+W0cDi0XRjNKUMoJtpSi50+Ph6w==", - "dev": true, - "requires": { - "@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" - }, - "dependencies": { - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", + "name": "into-cps-app", + "version": "5.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "into-cps-app", + "version": "5.0.0", + "license": "SEE LICENSE IN ", + "dependencies": { + "@playwright/test": "^1.47.2", + "@popperjs/core": "^2.11.8", + "@types/w2ui": "^1.4.37", + "bootstrap": "^5.3.3", + "del": "^7.1.0", + "gulp": "^5.0.0", + "gulp-sourcemaps": "^3.0.0", + "gulp-typescript": "^6.0.0-alpha.1", + "jquery": "^3.7.1", + "mocha": "^10.7.3" + }, + "devDependencies": { + "@types/node": "^22.7.5", + "electron": "^32.1.2", + "electron-builder": "^25.1.7", + "electron-playwright-helpers": "^1.7.1", + "gulp-clean-css": "^4.3.0", + "gulp-htmlhint": "^4.0.2", + "monocart-coverage-reports": "^2.11.1", + "monocart-reporter": "^2.9.6", + "nyc": "^17.1.0", + "playwright": "^1.47.2", + "source-map-support": "^0.5.21", + "ts-node": "^10.9.2", + "typescript": "^5.6.2" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.0.tgz", + "integrity": "sha512-INCKxTtbXtcNbUZ3YXutwMpEleqttcswhAdee7dhuoVrD2cnuc3PqtERBtxkX5nziX9vnBL8WXmSGwv8CuPV6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.0.tgz", + "integrity": "sha512-qETICbZSLe7uXv9VE8T/RWOdIE5qqyTucOt4zLYMafj2MRO271VGgLd4RACJMeBO37UPWhXiKMBk7YlJ0fOzQA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/generator": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.0.tgz", + "integrity": "sha512-/AIkAmInnWwgEAJGQr9vY0c66Mj6kjkE2ZPB1PurTRaRAh3U+J45sAQMjQDJdh4WbR3l0x5xkimXBKyBXXAu2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.26.0", + "@babel/types": "^7.26.0", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", "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" - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - } - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "dev": true - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "serialize-javascript": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", - "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "ssri": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", - "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "terser-webpack-plugin": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", - "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", - "dev": true, - "requires": { - "cacache": "^12.0.2", - "find-cache-dir": "^2.1.0", - "is-wsl": "^1.1.0", - "schema-utils": "^1.0.0", - "serialize-javascript": "^4.0.0", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - } - } - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "@angular-devkit/build-optimizer": { - "version": "0.901.15", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.901.15.tgz", - "integrity": "sha512-fCX27AAaM91UlNtjwUhqBFTvL3U0PexeVpQORJ7hAr4DG1z3DUHJS4RHCjlgM060ny0fj1V5gu21j1QAQx52vA==", - "dev": true, - "requires": { - "loader-utils": "2.0.0", - "source-map": "0.7.3", - "tslib": "1.11.1", - "typescript": "3.6.5", - "webpack-sources": "1.4.3" - }, - "dependencies": { - "tslib": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", - "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==", - "dev": true - }, - "typescript": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.5.tgz", - "integrity": "sha512-BEjlc0Z06ORZKbtcxGrIvvwYs5hAnuo6TKdNFL55frVDlB+na3z5bsLhFaIxmT+dPWgBIjMo6aNnTOgHHmHgiQ==", - "dev": true - } - } - }, - "@angular-devkit/build-webpack": { - "version": "0.901.15", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.901.15.tgz", - "integrity": "sha512-vETkDD3xbWtm5zylKhKG2IYjmnED5DPBHCg/M0QmxMBEEiZOtqVrAwkJGSnErVInPmqW0jixIz3wCiMUBBA/dQ==", - "dev": true, - "requires": { - "@angular-devkit/architect": "0.901.15", - "@angular-devkit/core": "9.1.15", - "rxjs": "6.5.4" - }, - "dependencies": { - "@angular-devkit/architect": { - "version": "0.901.15", - "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.901.15.tgz", - "integrity": "sha512-t4yT34jQ3wA3NFZxph/PquITv8tFrkaexUusbNp4UN10+k+04lPF3aPnJJhM1VKjjfChznMMhLnqLjA+9o0Rmw==", - "dev": true, - "requires": { - "@angular-devkit/core": "9.1.15", - "rxjs": "6.5.4" - } - }, - "@angular-devkit/core": { - "version": "9.1.15", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-9.1.15.tgz", - "integrity": "sha512-zyUDaFQvnqsptoXhodbH4u+voXIldfDx+d0M2OMLj0tbfD4zp2fy7UOeTvu+lq2/LLNAObkG4JSK5DM9v1s08w==", - "dev": true, - "requires": { - "ajv": "6.12.3", - "fast-json-stable-stringify": "2.1.0", - "magic-string": "0.25.7", - "rxjs": "6.5.4", - "source-map": "0.7.3" - } - }, - "ajv": { - "version": "6.12.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz", - "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "rxjs": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", - "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - } - } - }, - "@angular-devkit/core": { - "version": "7.3.10", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.10.tgz", - "integrity": "sha512-h8Yj2+UfBsPI7jZ8X88tImO/7RPgNWUcKF8Uq/J5eUSN6z0FMO0lluD4sM7X8aikb7RK8MwkwrqB/xfxvvkOow==", - "requires": { - "ajv": "6.9.1", - "chokidar": "2.0.4", - "fast-json-stable-stringify": "2.0.0", - "rxjs": "6.3.3", - "source-map": "0.7.3" - }, - "dependencies": { - "rxjs": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", - "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", - "requires": { - "tslib": "^1.9.0" - } - } - } - }, - "@angular-devkit/schematics": { - "version": "7.3.10", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-7.3.10.tgz", - "integrity": "sha512-LMTGQ8kJb80LjTttu0ZqWXddzYtDwjKtMKY9X0A60Iz8/wbGl0j+wYG7KAVoRF0JeieYXs8Dl9KWdjyJyvJ/RA==", - "requires": { - "@angular-devkit/core": "7.3.10", - "rxjs": "6.3.3" - }, - "dependencies": { - "rxjs": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", - "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", - "requires": { - "tslib": "^1.9.0" - } - } - } - }, - "@angular/animations": { - "version": "7.2.16", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-7.2.16.tgz", - "integrity": "sha512-jH7haM3Hgtn1EW9b0Vfq6UqSz+rx3l7k+gJi9tuHEOPZdBTjtv3sNQxmM0IKxzOuTfM8KhRFkUlzyi43kfdp0w==", - "requires": { - "tslib": "^1.9.0" - } - }, - "@angular/cli": { - "version": "7.3.10", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-7.3.10.tgz", - "integrity": "sha512-ikSwYa3Pc8GkfyoQ+bzblxyuPnKzNYD6SRVbO4CXUbTJB+NmOCNEV3LTwwMANVBp4Z6fBMdUZccJdFbT4FbG2Q==", - "requires": { - "@angular-devkit/architect": "0.13.10", - "@angular-devkit/core": "7.3.10", - "@angular-devkit/schematics": "7.3.10", - "@schematics/angular": "7.3.10", - "@schematics/update": "0.13.10", - "@yarnpkg/lockfile": "1.1.0", - "ini": "1.3.5", - "inquirer": "6.2.1", - "npm-package-arg": "6.1.0", - "open": "6.0.0", - "pacote": "9.4.0", - "semver": "5.6.0", - "symbol-observable": "1.2.0" - }, - "dependencies": { - "semver": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" - } - } - }, - "@angular/common": { - "version": "7.2.16", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-7.2.16.tgz", - "integrity": "sha512-lPo2Vt5zmKeKTdMxHMUuViouMiK4QsmO6dGTIhJ7QAx9mov0QYb4sUVKN9Ix32Aeeznaa97qJnhevyDncJqvSA==", - "requires": { - "tslib": "^1.9.0" - } - }, - "@angular/compiler": { - "version": "7.2.16", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-7.2.16.tgz", - "integrity": "sha512-8iX+E9Cnet2167RdP8wM5PGPoEnw/jZNvHrtTRHs4g53n/Rg45iLmE9qFzxCqXGBmUO9LXKYdcXnettFKFLifg==", - "requires": { - "tslib": "^1.9.0" - } - }, - "@angular/compiler-cli": { - "version": "7.2.16", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-7.2.16.tgz", - "integrity": "sha512-3PK0Rlepvsy+MSw5oZEl26j+7E1hBI42T5+7hpZxf/c3vcPRORZ71oR3Ez/q51D2rkvovv8m8Ihv0Xjs0xDibQ==", - "requires": { - "canonical-path": "1.0.0", - "chokidar": "^2.1.1", - "convert-source-map": "^1.5.1", - "dependency-graph": "^0.7.2", - "magic-string": "^0.25.0", - "minimist": "^1.2.0", - "reflect-metadata": "^0.1.2", - "shelljs": "^0.8.1", - "source-map": "^0.6.1", - "tslib": "^1.9.0", - "yargs": "13.1.0" - }, - "dependencies": { - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - } - } - }, - "@angular/core": { - "version": "7.2.16", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-7.2.16.tgz", - "integrity": "sha512-z1RuBinuYeC4KLv8Z95YOgIQLd4nkoApdxkIZaWALwSkgeBuHJn4bCBn2cL0gJ/KO2x18TiTU5HuC+uyBt0AVQ==", - "requires": { - "tslib": "^1.9.0" - } - }, - "@angular/forms": { - "version": "7.2.16", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-7.2.16.tgz", - "integrity": "sha512-50JTXco6w1HOi5o6RQ6PVSR0tD4Y2aRcCFBfLXvzDi78aZOSEdOYaSm78RDUNzGCbjwdMCIbX8eOdQgUUtsEFA==", - "requires": { - "tslib": "^1.9.0" - } - }, - "@angular/http": { - "version": "7.2.16", - "resolved": "https://registry.npmjs.org/@angular/http/-/http-7.2.16.tgz", - "integrity": "sha512-yvjbNyzFSmmz4UTjCdy5M8mk0cZqf9TvSf8yN5UVIwtw4joyuUdlgJCuin0qSbQOKIf/JjHoofpO2JkPCGSNww==", - "requires": { - "tslib": "^1.9.0" - } - }, - "@angular/platform-browser": { - "version": "7.2.16", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-7.2.16.tgz", - "integrity": "sha512-6LltxoPlbtUgSec5a+BGPHZ0UYdqFizxSsplC1PoJdqH17DDxQjxcluAfXnLlvOYFSSPvYa73PSOpmUU2vp4gA==", - "requires": { - "tslib": "^1.9.0" - } - }, - "@angular/platform-browser-dynamic": { - "version": "7.2.16", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-7.2.16.tgz", - "integrity": "sha512-xsQ0qB54h7oY5UATK9VW25Y4dvG7uQe9+X4cf/GWB+R3eCzP8J9Ekxs4VU9y2ujlQkD64PV8gpKu0FHFh7wjIQ==", - "requires": { - "tslib": "^1.9.0" - } - }, - "@angular/platform-server": { - "version": "7.2.16", - "resolved": "https://registry.npmjs.org/@angular/platform-server/-/platform-server-7.2.16.tgz", - "integrity": "sha512-I6i4oy543iKiUHRzCMp/SuAOPP7WPMcVKz8sNwtWbI2mT2i5dihK9fBLOYoMVSYN5oL7yVEd/9dkcp881/ojxg==", - "requires": { - "domino": "^2.1.0", - "tslib": "^1.9.0", - "xhr2": "^0.1.4" - } - }, - "@angular/router": { - "version": "7.2.16", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-7.2.16.tgz", - "integrity": "sha512-SXDfkoGVUHhy83K+sR+39mmqTs4nSUh4DZbhFe4gii+mgAtBvlbeH8KBCqPNf7xq24aadyI2LCSGnGwgVKmXrA==", - "requires": { - "tslib": "^1.9.0" - } - }, - "@babel/code-frame": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", - "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", - "dev": true, - "requires": { - "@babel/highlight": "^7.14.5" - } - }, - "@babel/compat-data": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", - "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", - "dev": true - }, - "@babel/core": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz", - "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==", - "dev": true, - "requires": { - "@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" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "@babel/generator": { - "version": "7.9.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.3.tgz", - "integrity": "sha512-RpxM252EYsz9qLUIq6F7YJyK1sv0wWDBFuztfDGWaQKzHjqDHysxSiRUpA/X9jmfqo+WzkAVKFaUily5h+gDCQ==", - "dev": true, - "requires": { - "@babel/types": "^7.9.0", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.15.4.tgz", - "integrity": "sha512-QwrtdNvUNsPCj2lfNQacsGSQvGX8ee1ttrBrcozUP2Sv/jylewBP/8QFe6ZkBsC8T/GYWonNAWJV4aRR9AL2DA==", - "dev": true, - "requires": { - "@babel/types": "^7.15.4" - } - }, - "@babel/helper-builder-binary-assignment-operator-visitor": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.15.4.tgz", - "integrity": "sha512-P8o7JP2Mzi0SdC6eWr1zF+AEYvrsZa7GSY1lTayjF5XJhVH0kjLYUZPvTMflP7tBgZoe9gIhTa60QwFpqh/E0Q==", - "dev": true, - "requires": { - "@babel/helper-explode-assignable-expression": "^7.15.4", - "@babel/types": "^7.15.4" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz", - "integrity": "sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.15.0", - "@babel/helper-validator-option": "^7.14.5", - "browserslist": "^4.16.6", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "@babel/helper-create-class-features-plugin": { - "version": "7.17.6", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.6.tgz", - "integrity": "sha512-SogLLSxXm2OkBbSsHZMM4tUi8fUzjs63AT/d0YQIzr6GSd8Hxsbk2KYDX0k0DweAzGMj/YWeiCsorIdtdcW8Eg==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", - "@babel/helper-member-expression-to-functions": "^7.16.7", - "@babel/helper-optimise-call-expression": "^7.16.7", - "@babel/helper-replace-supers": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", - "dev": true, - "requires": { - "@babel/highlight": "^7.16.7" - } - }, - "@babel/generator": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.3.tgz", - "integrity": "sha512-+R6Dctil/MgUsZsZAkYgK+ADNSZzJRRy0TvY65T71z/CR854xHQ1EweBYXdfT+HNeN7w0cSJJEzgxZMv40pxsg==", - "dev": true, - "requires": { - "@babel/types": "^7.17.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz", - "integrity": "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-function-name": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", - "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", - "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", - "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.7.tgz", - "integrity": "sha512-VtJ/65tYiU/6AbMTDwyoXGPKHgTsfRarivm+YbB5uAzKUyuPjgZSgAFeG87FCigc7KNHu2Pegh1XIT3lXjvz3Q==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz", - "integrity": "sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-replace-supers": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz", - "integrity": "sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw==", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-member-expression-to-functions": "^7.16.7", - "@babel/helper-optimise-call-expression": "^7.16.7", - "@babel/traverse": "^7.16.7", - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", - "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", - "dev": true - }, - "@babel/highlight": { - "version": "7.16.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", - "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.16.7", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.3.tgz", - "integrity": "sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA==", - "dev": true - }, - "@babel/template": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", - "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.16.7", - "@babel/parser": "^7.16.7", - "@babel/types": "^7.16.7" - } - }, - "@babel/traverse": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", - "integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.3", - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", - "@babel/helper-hoist-variables": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.17.3", - "@babel/types": "^7.17.0", - "debug": "^4.1.0", - "globals": "^11.1.0" - } - }, - "@babel/types": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", - "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.16.7", - "to-fast-properties": "^2.0.0" - } - }, - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "@babel/helper-create-regexp-features-plugin": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.14.5.tgz", - "integrity": "sha512-TLawwqpOErY2HhWbGJ2nZT5wSkR192QpN+nBg1THfBfftrlvOh+WbhrxXCH4q4xJ9Gl16BGPR/48JA+Ryiho/A==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.14.5", - "regexpu-core": "^4.7.1" - } - }, - "@babel/helper-environment-visitor": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", - "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" - }, - "dependencies": { - "@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", - "dev": true - }, - "@babel/types": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", - "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.16.7", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/helper-explode-assignable-expression": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.15.4.tgz", - "integrity": "sha512-J14f/vq8+hdC2KoWLIQSsGrC9EFBKE4NFts8pfMpymfApds+fPqR30AOUWc4tyr56h9l/GA1Sxv2q3dLZWbQ/g==", - "dev": true, - "requires": { - "@babel/types": "^7.15.4" - } - }, - "@babel/helper-function-name": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz", - "integrity": "sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.15.4", - "@babel/template": "^7.15.4", - "@babel/types": "^7.15.4" - }, - "dependencies": { - "@babel/template": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", - "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.14.5", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4" - } - } - } - }, - "@babel/helper-get-function-arity": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz", - "integrity": "sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==", - "dev": true, - "requires": { - "@babel/types": "^7.15.4" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz", - "integrity": "sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==", - "dev": true, - "requires": { - "@babel/types": "^7.15.4" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz", - "integrity": "sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==", - "dev": true, - "requires": { - "@babel/types": "^7.15.4" - } - }, - "@babel/helper-module-imports": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz", - "integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==", - "dev": true, - "requires": { - "@babel/types": "^7.15.4" - } - }, - "@babel/helper-module-transforms": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.8.tgz", - "integrity": "sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.15.4", - "@babel/helper-replace-supers": "^7.15.4", - "@babel/helper-simple-access": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", - "@babel/helper-validator-identifier": "^7.15.7", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.6" - }, - "dependencies": { - "@babel/template": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", - "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.14.5", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4" - } - } - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz", - "integrity": "sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==", - "dev": true, - "requires": { - "@babel/types": "^7.15.4" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", - "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", - "dev": true - }, - "@babel/helper-remap-async-to-generator": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.15.4.tgz", - "integrity": "sha512-v53MxgvMK/HCwckJ1bZrq6dNKlmwlyRNYM6ypaRTdXWGOE2c1/SCa6dL/HimhPulGhZKw9W0QhREM583F/t0vQ==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.15.4", - "@babel/helper-wrap-function": "^7.15.4", - "@babel/types": "^7.15.4" - } - }, - "@babel/helper-replace-supers": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz", - "integrity": "sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==", - "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.15.4", - "@babel/helper-optimise-call-expression": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" - } - }, - "@babel/helper-simple-access": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz", - "integrity": "sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==", - "dev": true, - "requires": { - "@babel/types": "^7.15.4" - } - }, - "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.15.4.tgz", - "integrity": "sha512-BMRLsdh+D1/aap19TycS4eD1qELGrCBJwzaY9IE8LrpJtJb+H7rQkPIdsfgnMtLBA6DJls7X9z93Z4U8h7xw0A==", - "dev": true, - "requires": { - "@babel/types": "^7.15.4" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz", - "integrity": "sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==", - "dev": true, - "requires": { - "@babel/types": "^7.15.4" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", - "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", - "dev": true - }, - "@babel/helper-validator-option": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", - "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", - "dev": true - }, - "@babel/helper-wrap-function": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.15.4.tgz", - "integrity": "sha512-Y2o+H/hRV5W8QhIfTpRIBwl57y8PrZt6JM3V8FOo5qarjshHItyH5lXlpMfBfmBefOqSCpKZs/6Dxqp0E/U+uw==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.15.4", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" - }, - "dependencies": { - "@babel/template": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", - "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.14.5", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4" - } - } - } - }, - "@babel/helpers": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz", - "integrity": "sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==", - "dev": true, - "requires": { - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" - }, - "dependencies": { - "@babel/template": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", - "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.14.5", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4" - } - } - } - }, - "@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.14.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz", - "integrity": "sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==", - "dev": true - }, - "@babel/plugin-proposal-async-generator-functions": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.15.8.tgz", - "integrity": "sha512-2Z5F2R2ibINTc63mY7FLqGfEbmofrHU9FitJW1Q7aPaKFhiPvSq6QEt/BoWN5oME3GVyjcRuNNSRbb9LC0CSWA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-remap-async-to-generator": "^7.15.4", - "@babel/plugin-syntax-async-generators": "^7.8.4" - } - }, - "@babel/plugin-proposal-class-properties": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz", - "integrity": "sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7" - }, - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", - "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", - "dev": true - } - } - }, - "@babel/plugin-proposal-dynamic-import": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.14.5.tgz", - "integrity": "sha512-ExjiNYc3HDN5PXJx+bwC50GIx/KKanX2HiggnIUAYedbARdImiCU4RhhHfdf0Kd7JNXGpsBBBCOm+bBVy3Gb0g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - } - }, - "@babel/plugin-proposal-export-namespace-from": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.7.tgz", - "integrity": "sha512-ZxdtqDXLRGBL64ocZcs7ovt71L3jhC1RGSyR996svrCi3PYqHNkb3SwPJCs8RIzD86s+WPpt2S73+EHCGO+NUA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3" - }, - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", - "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", - "dev": true - } - } - }, - "@babel/plugin-proposal-json-strings": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.14.5.tgz", - "integrity": "sha512-NSq2fczJYKVRIsUJyNxrVUMhB27zb7N7pOFGQOhBKJrChbGcgEAqyZrmZswkPk18VMurEeJAaICbfm57vUeTbQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-json-strings": "^7.8.3" - } - }, - "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.7.tgz", - "integrity": "sha512-K3XzyZJGQCr00+EtYtrDjmwX7o7PLK6U9bi1nCwkQioRFVUv6dJoxbQjtWVtP+bCPy82bONBKG8NPyQ4+i6yjg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" - }, - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", - "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", - "dev": true - } - } - }, - "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.5.tgz", - "integrity": "sha512-gun/SOnMqjSb98Nkaq2rTKMwervfdAoz6NphdY0vTfuzMfryj+tDGb2n6UkDKwez+Y8PZDhE3D143v6Gepp4Hg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - } - }, - "@babel/plugin-proposal-numeric-separator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.5.tgz", - "integrity": "sha512-yiclALKe0vyZRZE0pS6RXgjUOt87GWv6FYa5zqj15PvhOGFO69R5DusPlgK/1K5dVnCtegTiWu9UaBSrLLJJBg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - } - }, - "@babel/plugin-proposal-object-rest-spread": { - "version": "7.15.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.15.6.tgz", - "integrity": "sha512-qtOHo7A1Vt+O23qEAX+GdBpqaIuD3i9VRrWgCJeq7WO6H2d14EK3q11urj5Te2MAeK97nMiIdRpwd/ST4JFbNg==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.15.0", - "@babel/helper-compilation-targets": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.15.4" - } - }, - "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.14.5.tgz", - "integrity": "sha512-3Oyiixm0ur7bzO5ybNcZFlmVsygSIQgdOa7cTfOYCMY+wEPAYhZAJxi3mixKFCTCKUhQXuCTtQ1MzrpL3WT8ZQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" - } - }, - "@babel/plugin-proposal-optional-chaining": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.5.tgz", - "integrity": "sha512-ycz+VOzo2UbWNI1rQXxIuMOzrDdHGrI23fRiz/Si2R4kv2XZQ1BK8ccdHwehMKBlcH/joGW/tzrUmo67gbJHlQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.14.5", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - } - }, - "@babel/plugin-proposal-private-methods": { - "version": "7.16.11", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.11.tgz", - "integrity": "sha512-F/2uAkPlXDr8+BHpZvo19w3hLFKge+k75XUprE6jaqKxjGkSYcK+4c+bup5PdW/7W/Rpjwql7FTVEDW+fRAQsw==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.16.10", - "@babel/helper-plugin-utils": "^7.16.7" - }, - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", - "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", - "dev": true - } - } - }, - "@babel/plugin-proposal-private-property-in-object": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.7.tgz", - "integrity": "sha512-rMQkjcOFbm+ufe3bTZLyOfsOUOxyvLXZJCTARhJr+8UMSoZmqTe1K1BgkFcrW37rAchWg57yI69ORxiWvUINuQ==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-create-class-features-plugin": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5" - }, - "dependencies": { - "@babel/helper-annotate-as-pure": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz", - "integrity": "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", - "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", - "dev": true - }, - "@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", - "dev": true - }, - "@babel/types": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", - "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.16.7", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/plugin-proposal-unicode-property-regex": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.14.5.tgz", - "integrity": "sha512-6axIeOU5LnY471KenAB9vI8I5j7NQ2d652hIYwVyRfgaZT5UpiqFKCuVXCDMSrU+3VFafnu2c5m3lrWIlr6A5Q==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-dynamic-import": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-export-namespace-from": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.3" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-jsx": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.7.tgz", - "integrity": "sha512-Esxmk7YjA8QysKeT3VhTXvF6y77f/a91SIs4pWb4H2eWGQkCKFgQaG6hdoEVZtGsrAcb2K5BW66XsOErD4WU3Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - }, - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", - "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", - "dev": true - } - } - }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-typescript": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz", - "integrity": "sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - }, - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", - "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", - "dev": true - } - } - }, - "@babel/plugin-transform-arrow-functions": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.14.5.tgz", - "integrity": "sha512-KOnO0l4+tD5IfOdi4x8C1XmEIRWUjNRV8wc6K2vz/3e8yAOoZZvsRXRRIF/yo/MAOFb4QjtAw9xSxMXbSMRy8A==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-async-to-generator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.14.5.tgz", - "integrity": "sha512-szkbzQ0mNk0rpu76fzDdqSyPu0MuvpXgC+6rz5rpMb5OIRxdmHfQxrktL8CYolL2d8luMCZTR0DpIMIdL27IjA==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-remap-async-to-generator": "^7.14.5" - } - }, - "@babel/plugin-transform-block-scoped-functions": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.14.5.tgz", - "integrity": "sha512-dtqWqdWZ5NqBX3KzsVCWfQI3A53Ft5pWFCT2eCVUftWZgjc5DpDponbIF1+c+7cSGk2wN0YK7HGL/ezfRbpKBQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-block-scoping": { - "version": "7.15.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.15.3.tgz", - "integrity": "sha512-nBAzfZwZb4DkaGtOes1Up1nOAp9TDRRFw4XBzBBSG9QK7KVFmYzgj9o9sbPv7TX5ofL4Auq4wZnxCoPnI/lz2Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-classes": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.15.4.tgz", - "integrity": "sha512-Yjvhex8GzBmmPQUvpXRPWQ9WnxXgAFuZSrqOK/eJlOGIXwvv8H3UEdUigl1gb/bnjTrln+e8bkZUYCBt/xYlBg==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.15.4", - "@babel/helper-function-name": "^7.15.4", - "@babel/helper-optimise-call-expression": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-replace-supers": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", - "globals": "^11.1.0" - } - }, - "@babel/plugin-transform-computed-properties": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.14.5.tgz", - "integrity": "sha512-pWM+E4283UxaVzLb8UBXv4EIxMovU4zxT1OPnpHJcmnvyY9QbPPTKZfEj31EUvG3/EQRbYAGaYEUZ4yWOBC2xg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-destructuring": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.7.tgz", - "integrity": "sha512-0mDE99nK+kVh3xlc5vKwB6wnP9ecuSj+zQCa/n0voENtP/zymdT4HH6QEb65wjjcbqr1Jb/7z9Qp7TF5FtwYGw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-dotall-regex": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.14.5.tgz", - "integrity": "sha512-loGlnBdj02MDsFaHhAIJzh7euK89lBrGIdM9EAtHFo6xKygCUGuuWe07o1oZVk287amtW1n0808sQM99aZt3gw==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-duplicate-keys": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.14.5.tgz", - "integrity": "sha512-iJjbI53huKbPDAsJ8EmVmvCKeeq21bAze4fu9GBQtSLqfvzj2oRuHVx4ZkDwEhg1htQ+5OBZh/Ab0XDf5iBZ7A==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-exponentiation-operator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.14.5.tgz", - "integrity": "sha512-jFazJhMBc9D27o9jDnIE5ZErI0R0m7PbKXVq77FFvqFbzvTMuv8jaAwLZ5PviOLSFttqKIW0/wxNSDbjLk0tYA==", - "dev": true, - "requires": { - "@babel/helper-builder-binary-assignment-operator-visitor": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-for-of": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.15.4.tgz", - "integrity": "sha512-DRTY9fA751AFBDh2oxydvVm4SYevs5ILTWLs6xKXps4Re/KG5nfUkr+TdHCrRWB8C69TlzVgA9b3RmGWmgN9LA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-function-name": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.14.5.tgz", - "integrity": "sha512-vbO6kv0fIzZ1GpmGQuvbwwm+O4Cbm2NrPzwlup9+/3fdkuzo1YqOZcXw26+YUJB84Ja7j9yURWposEHLYwxUfQ==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-literals": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.14.5.tgz", - "integrity": "sha512-ql33+epql2F49bi8aHXxvLURHkxJbSmMKl9J5yHqg4PLtdE6Uc48CH1GS6TQvZ86eoB/ApZXwm7jlA+B3kra7A==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-member-expression-literals": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.14.5.tgz", - "integrity": "sha512-WkNXxH1VXVTKarWFqmso83xl+2V3Eo28YY5utIkbsmXoItO8Q3aZxN4BTS2k0hz9dGUloHK26mJMyQEYfkn/+Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-modules-amd": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.5.tgz", - "integrity": "sha512-3lpOU8Vxmp3roC4vzFpSdEpGUWSMsHFreTWOMMLzel2gNGfHE5UWIh/LN6ghHs2xurUp4jRFYMUIZhuFbody1g==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5", - "babel-plugin-dynamic-import-node": "^2.3.3" - } - }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.15.4.tgz", - "integrity": "sha512-qg4DPhwG8hKp4BbVDvX1s8cohM8a6Bvptu4l6Iingq5rW+yRUAhe/YRup/YcW2zCOlrysEWVhftIcKzrEZv3sA==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-simple-access": "^7.15.4", - "babel-plugin-dynamic-import-node": "^2.3.3" - } - }, - "@babel/plugin-transform-modules-systemjs": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.15.4.tgz", - "integrity": "sha512-fJUnlQrl/mezMneR72CKCgtOoahqGJNVKpompKwzv3BrEXdlPspTcyxrZ1XmDTIr9PpULrgEQo3qNKp6dW7ssw==", - "dev": true, - "requires": { - "@babel/helper-hoist-variables": "^7.15.4", - "@babel/helper-module-transforms": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-validator-identifier": "^7.14.9", - "babel-plugin-dynamic-import-node": "^2.3.3" - } - }, - "@babel/plugin-transform-modules-umd": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.5.tgz", - "integrity": "sha512-RfPGoagSngC06LsGUYyM9QWSXZ8MysEjDJTAea1lqRjNECE3y0qIJF/qbvJxc4oA4s99HumIMdXOrd+TdKaAAA==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.14.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.14.9.tgz", - "integrity": "sha512-l666wCVYO75mlAtGFfyFwnWmIXQm3kSH0C3IRnJqWcZbWkoihyAdDhFm2ZWaxWTqvBvhVFfJjMRQ0ez4oN1yYA==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.14.5" - } - }, - "@babel/plugin-transform-new-target": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.14.5.tgz", - "integrity": "sha512-Nx054zovz6IIRWEB49RDRuXGI4Gy0GMgqG0cII9L3MxqgXz/+rgII+RU58qpo4g7tNEx1jG7rRVH4ihZoP4esQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-object-super": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.14.5.tgz", - "integrity": "sha512-MKfOBWzK0pZIrav9z/hkRqIk/2bTv9qvxHzPQc12RcVkMOzpIKnFCNYJip00ssKWYkd8Sf5g0Wr7pqJ+cmtuFg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-replace-supers": "^7.14.5" - } - }, - "@babel/plugin-transform-parameters": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.15.4.tgz", - "integrity": "sha512-9WB/GUTO6lvJU3XQsSr6J/WKvBC2hcs4Pew8YxZagi6GkTdniyqp8On5kqdK8MN0LMeu0mGbhPN+O049NV/9FQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-property-literals": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.14.5.tgz", - "integrity": "sha512-r1uilDthkgXW8Z1vJz2dKYLV1tuw2xsbrp3MrZmD99Wh9vsfKoob+JTgri5VUb/JqyKRXotlOtwgu4stIYCmnw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-react-jsx": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.16.7.tgz", - "integrity": "sha512-8D16ye66fxiE8m890w0BpPpngG9o9OVBBy0gH2E+2AR7qMR2ZpTYJEqLxAsoroenMId0p/wMW+Blc0meDgu0Ag==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.7", - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-jsx": "^7.16.7", - "@babel/types": "^7.16.7" - }, - "dependencies": { - "@babel/helper-annotate-as-pure": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz", - "integrity": "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-module-imports": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", - "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", - "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", - "dev": true - }, - "@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", - "dev": true - }, - "@babel/types": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", - "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.16.7", - "to-fast-properties": "^2.0.0" - } - } - } - }, - "@babel/plugin-transform-regenerator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.14.5.tgz", - "integrity": "sha512-NVIY1W3ITDP5xQl50NgTKlZ0GrotKtLna08/uGY6ErQt6VEQZXla86x/CTddm5gZdcr+5GSsvMeTmWA5Ii6pkg==", - "dev": true, - "requires": { - "regenerator-transform": "^0.14.2" - } - }, - "@babel/plugin-transform-reserved-words": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.14.5.tgz", - "integrity": "sha512-cv4F2rv1nD4qdexOGsRQXJrOcyb5CrgjUH9PKrrtyhSDBNWGxd0UIitjyJiWagS+EbUGjG++22mGH1Pub8D6Vg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-shorthand-properties": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.14.5.tgz", - "integrity": "sha512-xLucks6T1VmGsTB+GWK5Pl9Jl5+nRXD1uoFdA5TSO6xtiNjtXTjKkmPdFXVLGlK5A2/or/wQMKfmQ2Y0XJfn5g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-spread": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.15.8.tgz", - "integrity": "sha512-/daZ8s2tNaRekl9YJa9X4bzjpeRZLt122cpgFnQPLGUe61PH8zMEBmYqKkW5xF5JUEh5buEGXJoQpqBmIbpmEQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.15.4" - } - }, - "@babel/plugin-transform-sticky-regex": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.14.5.tgz", - "integrity": "sha512-Z7F7GyvEMzIIbwnziAZmnSNpdijdr4dWt+FJNBnBLz5mwDFkqIXU9wmBcWWad3QeJF5hMTkRe4dAq2sUZiG+8A==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-template-literals": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.14.5.tgz", - "integrity": "sha512-22btZeURqiepOfuy/VkFr+zStqlujWaarpMErvay7goJS6BWwdd6BY9zQyDLDa4x2S3VugxFb162IZ4m/S/+Gg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-typeof-symbol": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.14.5.tgz", - "integrity": "sha512-lXzLD30ffCWseTbMQzrvDWqljvZlHkXU+CnseMhkMNqU1sASnCsz3tSzAaH3vCUXb9PHeUb90ZT1BdFTm1xxJw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-transform-typescript": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.8.tgz", - "integrity": "sha512-bHdQ9k7YpBDO2d0NVfkj51DpQcvwIzIusJ7mEUaMlbZq3Kt/U47j24inXZHQ5MDiYpCs+oZiwnXyKedE8+q7AQ==", - "dev": true, - "requires": { - "@babel/helper-create-class-features-plugin": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-typescript": "^7.16.7" - }, - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", - "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", - "dev": true - } - } - }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.14.5.tgz", - "integrity": "sha512-UygduJpC5kHeCiRw/xDVzC+wj8VaYSoKl5JNVmbP7MadpNinAm3SvZCxZ42H37KZBKztz46YC73i9yV34d0Tzw==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.14.5", - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/preset-env": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.9.0.tgz", - "integrity": "sha512-712DeRXT6dyKAM/FMbQTV/FvRCms2hPCx+3weRjZ8iQVQWZejWWk1wwG6ViWMyqb/ouBbGOl5b6aCk0+j1NmsQ==", - "dev": true, - "requires": { - "@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" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "@babel/preset-modules": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz", - "integrity": "sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - } - }, - "@babel/preset-typescript": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.16.7.tgz", - "integrity": "sha512-WbVEmgXdIyvzB77AQjGBEyYPZx+8tTsO50XtfozQrkW8QB2rLJpH2lgx0TRw5EJrBxOZQ+wCcyPVQvS8tjEHpQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-validator-option": "^7.16.7", - "@babel/plugin-transform-typescript": "^7.16.7" - }, - "dependencies": { - "@babel/helper-plugin-utils": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", - "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", - "dev": true - }, - "@babel/helper-validator-option": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", - "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", - "dev": true - } - } - }, - "@babel/runtime": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz", - "integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==", - "dev": true, - "requires": { - "regenerator-runtime": "^0.13.4" - } - }, - "@babel/template": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", - "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.6", - "@babel/types": "^7.8.6" - } - }, - "@babel/traverse": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz", - "integrity": "sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.15.4", - "@babel/helper-function-name": "^7.15.4", - "@babel/helper-hoist-variables": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "dependencies": { - "@babel/generator": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz", - "integrity": "sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==", - "dev": true, - "requires": { - "@babel/types": "^7.15.6", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - } - }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "@babel/types": { - "version": "7.15.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz", - "integrity": "sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.14.9", - "to-fast-properties": "^2.0.0" - } - }, - "@develar/schema-utils": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz", - "integrity": "sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==", - "dev": true, - "requires": { - "ajv": "^6.12.0", - "ajv-keywords": "^3.4.1" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - } - } - }, - "@electron/get": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/@electron/get/-/get-1.13.0.tgz", - "integrity": "sha512-+SjZhRuRo+STTO1Fdhzqnv9D2ZhjxXP6egsJ9kiO8dtP68cDx7dFCwWi64dlMQV7sWcfW1OYCW4wviEBzmRsfQ==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "env-paths": "^2.2.0", - "fs-extra": "^8.1.0", - "global-agent": "^2.0.2", - "global-tunnel-ng": "^2.7.1", - "got": "^9.6.0", - "progress": "^2.0.3", - "semver": "^6.2.0", - "sumchecker": "^3.0.1" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "@electron/universal": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-1.0.5.tgz", - "integrity": "sha512-zX9O6+jr2NMyAdSkwEUlyltiI4/EBLu2Ls/VD3pUQdi3cAYeYfdQnT2AJJ38HE4QxLccbU13LSpccw1IWlkyag==", - "dev": true, - "requires": { - "@malept/cross-spawn-promise": "^1.1.0", - "asar": "^3.0.3", - "debug": "^4.3.1", - "dir-compare": "^2.4.0", - "fs-extra": "^9.0.1" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - } - } - }, - "@gar/promisify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.2.tgz", - "integrity": "sha512-82cpyJyKRoQoRi+14ibCeGPu0CwypgtBAdBhq1WfvagpCZNKqwXbKwXllYSMG91DhmG4jt9gN8eP6lGOtozuaw==", - "dev": true - }, - "@gulp-sourcemaps/identity-map": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-1.0.2.tgz", - "integrity": "sha512-ciiioYMLdo16ShmfHBXJBOFm3xPC4AuwO4xeRpFeHz7WK9PYsWCmigagG2XyzZpubK4a3qNKoUBDhbzHfa50LQ==", - "dev": true, - "requires": { - "acorn": "^5.0.3", - "css": "^2.2.1", - "normalize-path": "^2.1.1", - "source-map": "^0.6.0", - "through2": "^2.0.3" - }, - "dependencies": { - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "@gulp-sourcemaps/map-sources": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz", - "integrity": "sha1-iQrnxdjId/bThIYCFazp1+yUW9o=", - "dev": true, - "requires": { - "normalize-path": "^2.0.1", - "through2": "^2.0.3" - } - }, - "@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true - }, - "@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "dependencies": { - "@types/yargs": { - "version": "16.0.4", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", - "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "@jsdevtools/coverage-istanbul-loader": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@jsdevtools/coverage-istanbul-loader/-/coverage-istanbul-loader-3.0.3.tgz", - "integrity": "sha512-TAdNkeGB5Fe4Og+ZkAr1Kvn9by2sfL44IAHFtxlh1BA1XJ5cLpO9iSNki5opWESv3l3vSHsZ9BNKuqFKbEbFaA==", - "dev": true, - "requires": { - "convert-source-map": "^1.7.0", - "istanbul-lib-instrument": "^4.0.1", - "loader-utils": "^1.4.0", - "merge-source-map": "^1.1.0", - "schema-utils": "^2.6.4" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - } - } - }, - "@malept/cross-spawn-promise": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz", - "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.1" - }, - "dependencies": { - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "@malept/flatpak-bundler": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@malept/flatpak-bundler/-/flatpak-bundler-0.4.0.tgz", - "integrity": "sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "fs-extra": "^9.0.0", - "lodash": "^4.17.15", - "tmp-promise": "^3.0.2" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - } - } - }, - "@ngtools/webpack": { - "version": "9.1.15", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-9.1.15.tgz", - "integrity": "sha512-2k2SpBd8ssZ1XnLwM09t34pHck96d3ndyxBfg19IpXXXB/FbvhVXTkypB2ktpoGHy/8oSPeUDjz6O9x+p5iT8A==", - "dev": true, - "requires": { - "@angular-devkit/core": "9.1.15", - "enhanced-resolve": "4.1.1", - "rxjs": "6.5.4", - "webpack-sources": "1.4.3" - }, - "dependencies": { - "@angular-devkit/core": { - "version": "9.1.15", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-9.1.15.tgz", - "integrity": "sha512-zyUDaFQvnqsptoXhodbH4u+voXIldfDx+d0M2OMLj0tbfD4zp2fy7UOeTvu+lq2/LLNAObkG4JSK5DM9v1s08w==", - "dev": true, - "requires": { - "ajv": "6.12.3", - "fast-json-stable-stringify": "2.1.0", - "magic-string": "0.25.7", - "rxjs": "6.5.4", - "source-map": "0.7.3" - } - }, - "ajv": { - "version": "6.12.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz", - "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "rxjs": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", - "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - } - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@npmcli/fs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.0.0.tgz", - "integrity": "sha512-8ltnOpRR/oJbOp8vaGUnipOi3bqkcW+sLHFlyXIr08OGHmVJLB1Hn7QtGXbYcpVtH1gAYZTlmDXtE4YV0+AMMQ==", - "dev": true, - "requires": { - "@gar/promisify": "^1.0.1", - "semver": "^7.3.5" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "@npmcli/move-file": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", - "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", - "dev": true, - "requires": { - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2" - }, - "dependencies": { - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "@playwright/test": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.19.2.tgz", - "integrity": "sha512-5oCmlYHjtOL662OxSkZBYGnoHWIQui7b4YHWNeSCYwhQjmjVcV5njRc8oBZlU8IwJgG7ZH2yhDk1haU96ygbWw==", - "dev": true, - "requires": { - "@babel/code-frame": "7.16.7", - "@babel/core": "7.16.12", - "@babel/plugin-proposal-class-properties": "7.16.7", - "@babel/plugin-proposal-dynamic-import": "7.16.7", - "@babel/plugin-proposal-export-namespace-from": "7.16.7", - "@babel/plugin-proposal-logical-assignment-operators": "7.16.7", - "@babel/plugin-proposal-nullish-coalescing-operator": "7.16.7", - "@babel/plugin-proposal-numeric-separator": "7.16.7", - "@babel/plugin-proposal-optional-chaining": "7.16.7", - "@babel/plugin-proposal-private-methods": "7.16.11", - "@babel/plugin-proposal-private-property-in-object": "7.16.7", - "@babel/plugin-syntax-async-generators": "7.8.4", - "@babel/plugin-syntax-json-strings": "7.8.3", - "@babel/plugin-syntax-object-rest-spread": "7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "7.8.3", - "@babel/plugin-transform-modules-commonjs": "7.16.8", - "@babel/plugin-transform-react-jsx": "7.16.7", - "@babel/preset-typescript": "7.16.7", - "babel-plugin-module-resolver": "4.1.0", - "colors": "1.4.0", - "commander": "8.3.0", - "debug": "4.3.3", - "expect": "27.2.5", - "jest-matcher-utils": "27.2.5", - "jpeg-js": "0.4.3", - "json5": "2.2.0", - "mime": "3.0.0", - "minimatch": "3.0.4", - "ms": "2.1.3", - "open": "8.4.0", - "pirates": "4.0.4", - "pixelmatch": "5.2.1", - "playwright-core": "1.19.2", - "pngjs": "6.0.0", - "rimraf": "3.0.2", - "source-map-support": "0.4.18", - "stack-utils": "2.0.5", - "yazl": "2.5.1" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", - "dev": true, - "requires": { - "@babel/highlight": "^7.16.7" - } - }, - "@babel/compat-data": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.0.tgz", - "integrity": "sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng==", - "dev": true - }, - "@babel/core": { - "version": "7.16.12", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.16.12.tgz", - "integrity": "sha512-dK5PtG1uiN2ikk++5OzSYsitZKny4wOCD0nrO4TqnW4BVBTQ2NGS3NgilvT/TEyxTST7LNyWV/T4tXDoD3fOgg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.16.8", - "@babel/helper-compilation-targets": "^7.16.7", - "@babel/helper-module-transforms": "^7.16.7", - "@babel/helpers": "^7.16.7", - "@babel/parser": "^7.16.12", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.16.10", - "@babel/types": "^7.16.8", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "semver": "^6.3.0", - "source-map": "^0.5.0" - } - }, - "@babel/generator": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.17.3.tgz", - "integrity": "sha512-+R6Dctil/MgUsZsZAkYgK+ADNSZzJRRy0TvY65T71z/CR854xHQ1EweBYXdfT+HNeN7w0cSJJEzgxZMv40pxsg==", - "dev": true, - "requires": { - "@babel/types": "^7.17.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz", - "integrity": "sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.16.4", - "@babel/helper-validator-option": "^7.16.7", - "browserslist": "^4.17.5", - "semver": "^6.3.0" - } - }, - "@babel/helper-function-name": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz", - "integrity": "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz", - "integrity": "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", - "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-module-imports": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", - "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-module-transforms": { - "version": "7.17.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.17.6.tgz", - "integrity": "sha512-2ULmRdqoOMpdvkbT8jONrZML/XALfzxlb052bldftkicAUy8AxSCkD5trDPQcwHNmolcl7wP6ehNqMlyUw6AaA==", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-module-imports": "^7.16.7", - "@babel/helper-simple-access": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/helper-validator-identifier": "^7.16.7", - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.3", - "@babel/types": "^7.17.0" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz", - "integrity": "sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==", - "dev": true - }, - "@babel/helper-simple-access": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz", - "integrity": "sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz", - "integrity": "sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw==", - "dev": true, - "requires": { - "@babel/types": "^7.16.0" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", - "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", - "dev": true, - "requires": { - "@babel/types": "^7.16.7" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", - "dev": true - }, - "@babel/helper-validator-option": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", - "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", - "dev": true - }, - "@babel/helpers": { - "version": "7.17.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.2.tgz", - "integrity": "sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ==", - "dev": true, - "requires": { - "@babel/template": "^7.16.7", - "@babel/traverse": "^7.17.0", - "@babel/types": "^7.17.0" - } - }, - "@babel/highlight": { - "version": "7.16.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", - "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.16.7", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.3.tgz", - "integrity": "sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA==", - "dev": true - }, - "@babel/plugin-proposal-dynamic-import": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.7.tgz", - "integrity": "sha512-I8SW9Ho3/8DRSdmDdH3gORdyUuYnk1m4cMxUAdu5oy4n3OfN8flDEH+d60iG7dUfi0KkYwSvoalHzzdRzpWHTg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-dynamic-import": "^7.8.3" - } - }, - "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz", - "integrity": "sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" - } - }, - "@babel/plugin-proposal-numeric-separator": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.7.tgz", - "integrity": "sha512-vQgPMknOIgiuVqbokToyXbkY/OmmjAzr/0lhSIbG/KmnzXPGwW/AdhdKpi+O4X/VkWiWjnkKOBiqJrTaC98VKw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/plugin-syntax-numeric-separator": "^7.10.4" - } - }, - "@babel/plugin-proposal-optional-chaining": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz", - "integrity": "sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-skip-transparent-expression-wrappers": "^7.16.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - } - }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.16.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.8.tgz", - "integrity": "sha512-oflKPvsLT2+uKQopesJt3ApiaIS2HW+hzHFcwRNtyDGieAeC/dIHZX8buJQ2J2X1rxGPy4eRcUijm3qcSPjYcA==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.16.7", - "@babel/helper-plugin-utils": "^7.16.7", - "@babel/helper-simple-access": "^7.16.7", - "babel-plugin-dynamic-import-node": "^2.3.3" - } - }, - "@babel/template": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", - "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.16.7", - "@babel/parser": "^7.16.7", - "@babel/types": "^7.16.7" - } - }, - "@babel/traverse": { - "version": "7.17.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.3.tgz", - "integrity": "sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.17.3", - "@babel/helper-environment-visitor": "^7.16.7", - "@babel/helper-function-name": "^7.16.7", - "@babel/helper-hoist-variables": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.17.3", - "@babel/types": "^7.17.0", - "debug": "^4.1.0", - "globals": "^11.1.0" - } - }, - "@babel/types": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", - "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.16.7", - "to-fast-properties": "^2.0.0" - } - }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "requires": { - "debug": "4" - } - }, - "browserslist": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.0.tgz", - "integrity": "sha512-bnpOoa+DownbciXj0jVGENf8VYQnE2LNWomhYuCsMmmx9Jd9lwq0WXODuwpSsp8AVdKM2/HorrzxAfbKvWTByQ==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001313", - "electron-to-chromium": "^1.4.76", - "escalade": "^3.1.1", - "node-releases": "^2.0.2", - "picocolors": "^1.0.0" - } - }, - "caniuse-lite": { - "version": "1.0.30001314", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001314.tgz", - "integrity": "sha512-0zaSO+TnCHtHJIbpLroX7nsD+vYuOVjl3uzFbJO1wMVbuveJA0RK2WcQA9ZUIOiO0/ArMiMgHJLxfEZhQiC0kw==", - "dev": true - }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true - }, - "commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "dev": true - }, - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "requires": { - "ms": "2.1.2" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "electron-to-chromium": { - "version": "1.4.77", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.77.tgz", - "integrity": "sha512-fiDxw8mO9Ph1Z0bjX2sFTPpi0J0QkOiwOJF+5Q0J0baNc/F9lLePAvDPlnoxvbUYYMizqrKPeotRRkJ9LtxAew==", - "dev": true - }, - "extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dev": true, - "requires": { - "@types/yauzl": "^2.9.1", - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - } - }, - "fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", - "dev": true, - "requires": { - "pend": "~1.2.0" - } - }, - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "requires": { - "is-docker": "^2.0.0" - } - }, - "mime": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", - "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", - "dev": true - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "node-releases": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", - "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", - "dev": true - }, - "open": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz", - "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==", - "dev": true, - "requires": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - } - }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "playwright-core": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.19.2.tgz", - "integrity": "sha512-OsL3sJZIo1UxKNWSP7zW7sk3FyUGG06YRHxHeBw51eIOxTCQRx5t+hXd0cvXashN2CHnd3hIZTs2aKa/im4hZQ==", - "dev": true, - "requires": { - "commander": "8.3.0", - "debug": "4.3.3", - "extract-zip": "2.0.1", - "https-proxy-agent": "5.0.0", - "jpeg-js": "0.4.3", - "mime": "3.0.0", - "pngjs": "6.0.0", - "progress": "2.0.3", - "proper-lockfile": "4.1.2", - "proxy-from-env": "1.1.0", - "rimraf": "3.0.2", - "socks-proxy-agent": "6.1.1", - "stack-utils": "2.0.5", - "ws": "8.4.2", - "yauzl": "2.10.0", - "yazl": "2.5.1" - } - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "socks": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz", - "integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==", - "dev": true, - "requires": { - "ip": "^1.1.5", - "smart-buffer": "^4.2.0" - } - }, - "socks-proxy-agent": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.1.1.tgz", - "integrity": "sha512-t8J0kG3csjA4g6FTbsMOWws+7R7vuRC8aQ/wy3/1OWmsgwA68zs/+cExQ0koSitUDXqhufF/YJr9wtNMZHw5Ew==", - "dev": true, - "requires": { - "agent-base": "^6.0.2", - "debug": "^4.3.1", - "socks": "^2.6.1" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", - "dev": true, - "requires": { - "source-map": "^0.5.6" - } - }, - "ws": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.4.2.tgz", - "integrity": "sha512-Kbk4Nxyq7/ZWqr/tarI9yIt/+iNNFOjBXEWgTb4ydaNHBNGgvf2QHbS9fdfsndfjFlFwEd4Al+mw83YkaD10ZA==", - "dev": true - }, - "yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", - "dev": true, - "requires": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - } - } - }, - "@schematics/angular": { - "version": "7.3.10", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-7.3.10.tgz", - "integrity": "sha512-R/oBE5Nbs/meMVqLLFjeVf3G+ROJAPtRbiJ+22EZ6V63RQfLbW37zX+z3Wv7yD9URtYE7X9Ojtz9WEfmSzBPUg==", - "requires": { - "@angular-devkit/core": "7.3.10", - "@angular-devkit/schematics": "7.3.10", - "typescript": "3.2.4" - }, - "dependencies": { - "typescript": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.4.tgz", - "integrity": "sha512-0RNDbSdEokBeEAkgNbxJ+BLwSManFy9TeXz8uW+48j/xhEXv1ePME60olyzw2XzUqUBNAYFeJadIqAgNqIACwg==" - } - } - }, - "@schematics/update": { - "version": "0.13.10", - "resolved": "https://registry.npmjs.org/@schematics/update/-/update-0.13.10.tgz", - "integrity": "sha512-X02qa+rpeD6+eacR0fy+Yr+OKrj3FTpod9TkfshMa1WwIFoWlshF/bpPmLoMGXOD+zCYoHrPimpkvEFPjOvCDQ==", - "requires": { - "@angular-devkit/core": "7.3.10", - "@angular-devkit/schematics": "7.3.10", - "@yarnpkg/lockfile": "1.1.0", - "ini": "1.3.5", - "pacote": "9.4.0", - "rxjs": "6.3.3", - "semver": "5.6.0", - "semver-intersect": "1.4.0" - }, - "dependencies": { - "rxjs": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", - "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", - "requires": { - "tslib": "^1.9.0" - } - }, - "semver": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" - } - } - }, - "@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", - "dev": true - }, - "@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", - "dev": true, - "requires": { - "defer-to-connect": "^1.0.1" - } - }, - "@types/ace": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@types/ace/-/ace-0.0.42.tgz", - "integrity": "sha512-ZakacqExJnGSoz0fSFtSL1A1Df+MIqTIPBBMl1ppEU8wS5AWGx0EPQPOyiAazkyMrskI0iG16tT+K1ZmIJGGnA==" - }, - "@types/adm-zip": { - "version": "0.4.34", - "resolved": "https://registry.npmjs.org/@types/adm-zip/-/adm-zip-0.4.34.tgz", - "integrity": "sha512-8ToYLLAYhkRfcmmljrKi22gT2pqu7hGMDtORP1emwIEGmgUTZOsaDjzWFzW5N2frcFRz/50CWt4zA1CxJ73pmQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/bluebird": { - "version": "3.0.37", - "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.0.37.tgz", - "integrity": "sha1-LnazlKqb6kDQQkGjHAiHomAoM4g=", - "dev": true - }, - "@types/bunyan": { - "version": "0.0.35", - "resolved": "https://registry.npmjs.org/@types/bunyan/-/bunyan-0.0.35.tgz", - "integrity": "sha1-e6ufnibFgEE7jDI9P6dr0I3RvKw=", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/cacheable-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", - "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", - "dev": true, - "requires": { - "@types/http-cache-semantics": "*", - "@types/keyv": "*", - "@types/node": "*", - "@types/responselike": "*" - } - }, - "@types/caseless": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz", - "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==", - "dev": true - }, - "@types/debug": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", - "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==", - "dev": true, - "requires": { - "@types/ms": "*" - } - }, - "@types/fs-extra": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.7.tgz", - "integrity": "sha512-YGq2A6Yc3bldrLUlm17VNWOnUbnEzJ9CMgOeLFtQF3HOCN5lQBO8VyjG00a5acA5NNSM30kHVGp1trZgnVgi1Q==", - "requires": { - "@types/node": "*" - }, - "dependencies": { - "@types/node": { - "version": "16.10.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.3.tgz", - "integrity": "sha512-ho3Ruq+fFnBrZhUYI46n/bV2GjwzSkwuT4dTf0GkuNFmnb8nq4ny2z9JEVemFi6bdEJanHLlYfy9c6FN9B9McQ==" - } - } - }, - "@types/glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA==", - "dev": true, - "requires": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/http-cache-semantics": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", - "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", - "dev": true - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", - "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", - "dev": true - }, - "@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "*" - } - }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "@types/jquery": { - "version": "2.0.57", - "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-2.0.57.tgz", - "integrity": "sha512-QUJ5wVL8iTZofgZjCfVnHxcMqqPPLfVfEKe8rfksMdmSmqEenpcpEBQO45VSSfng/tunwoLF+3I8rzEzVhYNLQ==" - }, - "@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", - "dev": true - }, - "@types/keyv": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.3.tgz", - "integrity": "sha512-FXCJgyyN3ivVgRoml4h94G/p3kY+u/B86La+QptcqJaWtBWtmc6TtkNfS40n9bIvyLteHh7zXOtgbobORKPbDg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", - "dev": true - }, - "@types/ms": { - "version": "0.7.31", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", - "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==", - "dev": true - }, - "@types/node": { - "version": "12.20.28", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.28.tgz", - "integrity": "sha512-cBw8gzxUPYX+/5lugXIPksioBSbE42k0fZ39p+4yRzfYjN6++eq9kAPdlY9qm+MXyfbk9EmvCYAYRn380sF46w==", - "dev": true - }, - "@types/plist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/plist/-/plist-3.0.2.tgz", - "integrity": "sha512-ULqvZNGMv0zRFvqn8/4LSPtnmN4MfhlPNtJCTpKuIIxGVGZ2rYWzFXrvEBoh9CVyqSE7D6YFRJ1hydLHI6kbWw==", - "dev": true, - "optional": true, - "requires": { - "@types/node": "*", - "xmlbuilder": ">=11.0.1" - } - }, - "@types/puppeteer": { - "version": "5.4.4", - "resolved": "https://registry.npmjs.org/@types/puppeteer/-/puppeteer-5.4.4.tgz", - "integrity": "sha512-3Nau+qi69CN55VwZb0ATtdUAlYlqOOQ3OfQfq0Hqgc4JMFXiQT/XInlwQ9g6LbicDslE6loIFsXFklGh5XmI6Q==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/puppeteer-core": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@types/puppeteer-core/-/puppeteer-core-5.4.0.tgz", - "integrity": "sha512-yqRPuv4EFcSkTyin6Yy17pN6Qz2vwVwTCJIDYMXbE3j8vTPhv0nCQlZOl5xfi0WHUkqvQsjAR8hAfjeMCoetwg==", - "dev": true, - "requires": { - "@types/puppeteer": "*" - } - }, - "@types/q": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.5.tgz", - "integrity": "sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ==", - "dev": true - }, - "@types/request": { - "version": "2.48.8", - "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.8.tgz", - "integrity": "sha512-whjk1EDJPcAR2kYHRbFl/lKeeKYTi05A15K9bnLInCVroNDCtXce57xKdI0/rQaA3K+6q0eFyUBPmqfSndUZdQ==", - "dev": true, - "requires": { - "@types/caseless": "*", - "@types/node": "*", - "@types/tough-cookie": "*", - "form-data": "^2.5.0" - }, - "dependencies": { - "form-data": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - } - } - }, - "@types/responselike": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", - "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/source-list-map": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", - "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", - "dev": true - }, - "@types/sql.js": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/sql.js/-/sql.js-0.0.29.tgz", - "integrity": "sha512-QDdqZ0k+p1YnphkSdZerpuH/hOs/wE9VftNgsw56IIG5Qm3X+VZ6NbnnvmFNkRoBn5Ke/juE/gypZ/y4Cr3faw==", - "requires": { - "@types/node": "*" - }, - "dependencies": { - "@types/node": { - "version": "16.10.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.3.tgz", - "integrity": "sha512-ho3Ruq+fFnBrZhUYI46n/bV2GjwzSkwuT4dTf0GkuNFmnb8nq4ny2z9JEVemFi6bdEJanHLlYfy9c6FN9B9McQ==" - } - } - }, - "@types/stack-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", - "dev": true - }, - "@types/tough-cookie": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.1.tgz", - "integrity": "sha512-Y0K95ThC3esLEYD6ZuqNek29lNX2EM1qxV8y2FTLUB0ff5wWrk7az+mLrnNFUnaXcgKye22+sFBRXOgpPILZNg==", - "dev": true - }, - "@types/verror": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.5.tgz", - "integrity": "sha512-9UjMCHK5GPgQRoNbqdLIAvAy0EInuiqbW0PBMtVP6B5B2HQJlvoJHM+KodPZMEjOa5VkSc+5LH7xy+cUzQdmHw==", - "dev": true, - "optional": true - }, - "@types/w2ui": { - "version": "1.4.33", - "resolved": "https://registry.npmjs.org/@types/w2ui/-/w2ui-1.4.33.tgz", - "integrity": "sha512-JjIUhJZqeUGUCLDH7BF5mbNb94mdlzJ0acuxHr4kD1PwMgu6KqYRV5BAr5xqkhu1LZDnnfRhNe1adB3sX+tsUA==", - "requires": { - "@types/jquery": "*" - } - }, - "@types/webpack-sources": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.9.tgz", - "integrity": "sha512-bvzMnzqoK16PQIC8AYHNdW45eREJQMd6WG/msQWX5V2+vZmODCOPb4TJcbgRljTZZTwTM4wUMcsI8FftNA7new==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/source-list-map": "*", - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "@types/which": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/which/-/which-1.3.2.tgz", - "integrity": "sha512-8oDqyLC7eD4HM307boe2QWKyuzdzWBj56xI/imSl2cpL+U3tCMaTAkMJ4ee5JBZ/FsOJlvRGeIShiZDAl1qERA==", - "dev": true - }, - "@types/xml2js": { - "version": "0.0.32", - "resolved": "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.0.32.tgz", - "integrity": "sha1-n36YzwrcyghaNc3q0DGbWsGcn9k=", - "dev": true - }, - "@types/yargs": { - "version": "17.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.3.tgz", - "integrity": "sha512-K7rm3Ke3ag/pAniBe80A6J6fjoqRibvCrl3dRmtXV9eCEt9h/pZwmHX9MzjQVUc/elneQTL4Ky7XKorC71Lmxw==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "@types/yargs-parser": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", - "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", - "dev": true - }, - "@types/yauzl": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz", - "integrity": "sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==", - "dev": true, - "optional": true, - "requires": { - "@types/node": "*" - } - }, - "@wdio/config": { - "version": "6.12.1", - "resolved": "https://registry.npmjs.org/@wdio/config/-/config-6.12.1.tgz", - "integrity": "sha512-V5hTIW5FNlZ1W33smHF4Rd5BKjGW2KeYhyXDQfXHjqLCeRiirZ9fABCo9plaVQDnwWSUMWYaAaIAifV82/oJCQ==", - "dev": true, - "requires": { - "@wdio/logger": "6.10.10", - "deepmerge": "^4.0.0", - "glob": "^7.1.2" - } - }, - "@wdio/logger": { - "version": "6.10.10", - "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-6.10.10.tgz", - "integrity": "sha512-2nh0hJz9HeZE0VIEMI+oPgjr/Q37ohrR9iqsl7f7GW5ik+PnKYCT9Eab5mR1GNMG60askwbskgGC1S9ygtvrSw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "loglevel": "^1.6.0", - "loglevel-plugin-prefix": "^0.8.4", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "@wdio/protocols": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-6.12.0.tgz", - "integrity": "sha512-UhTBZxClCsM3VjaiDp4DoSCnsa7D1QNmI2kqEBfIpyNkT3GcZhJb7L+nL0fTkzCwi7+/uLastb3/aOwH99gt0A==", - "dev": true - }, - "@wdio/repl": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/@wdio/repl/-/repl-6.11.0.tgz", - "integrity": "sha512-FxrFKiTkFyELNGGVEH1uijyvNY7lUpmff6x+FGskFGZB4uSRs0rxkOMaEjxnxw7QP1zgQKr2xC7GyO03gIGRGg==", - "dev": true, - "requires": { - "@wdio/utils": "6.11.0" - } - }, - "@wdio/utils": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-6.11.0.tgz", - "integrity": "sha512-vf0sOQzd28WbI26d6/ORrQ4XKWTzSlWLm9W/K/eJO0NASKPEzR+E+Q2kaa+MJ4FKXUpjbt+Lxfo+C26TzBk7tg==", - "dev": true, - "requires": { - "@wdio/logger": "6.10.10" - } - }, - "@webassemblyjs/ast": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz", - "integrity": "sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ==", - "dev": true, - "requires": { - "@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": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz", - "integrity": "sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz", - "integrity": "sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz", - "integrity": "sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz", - "integrity": "sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.8.5" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz", - "integrity": "sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz", - "integrity": "sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "mamacro": "^0.0.3" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz", - "integrity": "sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz", - "integrity": "sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA==", - "dev": true, - "requires": { - "@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": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz", - "integrity": "sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.8.5.tgz", - "integrity": "sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.8.5.tgz", - "integrity": "sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz", - "integrity": "sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q==", - "dev": true, - "requires": { - "@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": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz", - "integrity": "sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg==", - "dev": true, - "requires": { - "@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": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz", - "integrity": "sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q==", - "dev": true, - "requires": { - "@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": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz", - "integrity": "sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw==", - "dev": true, - "requires": { - "@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": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz", - "integrity": "sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg==", - "dev": true, - "requires": { - "@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": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz", - "integrity": "sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/wast-parser": "1.8.5", - "@xtuc/long": "4.2.2" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "@yarnpkg/lockfile": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", - "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==" - }, - "JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "requires": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - } - }, - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "dev": true, - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - } - }, - "ace-builds": { - "version": "1.4.13", - "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.4.13.tgz", - "integrity": "sha512-SOLzdaQkY6ecPKYRDDg+MY1WoGgXA34cIvYJNNoBMGGUswHmlauU2Hy0UL96vW0Fs/LgFbMUjD+6vqzWTldIYQ==" - }, - "acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", - "dev": true - }, - "adm-zip": { - "version": "0.5.9", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.9.tgz", - "integrity": "sha512-s+3fXLkeeLjZ2kLjCBwQufpI5fuN+kIGBxu6530nVQZGVol0d7Y/M88/xw9HGGUcJjKf8LutN3VPRUBq6N7Ajg==", - "dev": true - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "agentkeepalive": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-3.5.2.tgz", - "integrity": "sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ==", - "requires": { - "humanize-ms": "^1.2.1" - } - }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ajv": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.1.tgz", - "integrity": "sha512-XDN92U311aINL77ieWHmqCcNlwjoP5cHXDxIxbf2MaPYuCXOHS7gHH8jktxeK5omgd52XbSTX6a4Piwd1pQmzA==", - "requires": { - "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-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true - }, - "alphanum-sort": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", - "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", - "dev": true - }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", - "dev": true - }, - "ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "dev": true, - "requires": { - "string-width": "^4.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "ansi-colors": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", - "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", - "dev": true - }, - "ansi-cyan": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz", - "integrity": "sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM=", - "dev": true, - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==" - }, - "ansi-gray": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", - "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", - "dev": true, - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-html": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", - "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", - "dev": true - }, - "ansi-red": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz", - "integrity": "sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=", - "dev": true, - "requires": { - "ansi-wrap": "0.1.0" - } - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "ansi-wrap": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", - "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=", - "dev": true - }, - "any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=", - "dev": true - }, - "any-shell-escape": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/any-shell-escape/-/any-shell-escape-0.1.1.tgz", - "integrity": "sha1-1Vq5ciRMcaml4asIefML8RCAaVk=", - "dev": true - }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "app-builder-bin": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-3.7.1.tgz", - "integrity": "sha512-ql93vEUq6WsstGXD+SBLSIQw6SNnhbDEM0swzgugytMxLp3rT24Ag/jcC80ZHxiPRTdew1niuR7P3/FCrDqIjw==", - "dev": true - }, - "app-builder-lib": { - "version": "22.13.1", - "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-22.13.1.tgz", - "integrity": "sha512-TsUe7gCdH1cnSknUcqwVRAAxsFxsxcU/BJvnKR8ASzjaZtePW7MU+AEaDVDUURycgYxQ9XeymGjmuQGS32jcbw==", - "dev": true, - "requires": { - "7zip-bin": "~5.1.1", - "@develar/schema-utils": "~2.6.5", - "@electron/universal": "1.0.5", - "@malept/flatpak-bundler": "^0.4.0", - "async-exit-hook": "^2.0.1", - "bluebird-lst": "^1.0.9", - "builder-util": "22.13.1", - "builder-util-runtime": "8.8.1", - "chromium-pickle-js": "^0.2.0", - "debug": "^4.3.2", - "ejs": "^3.1.6", - "electron-osx-sign": "^0.5.0", - "electron-publish": "22.13.1", - "fs-extra": "^10.0.0", - "hosted-git-info": "^4.0.2", - "is-ci": "^3.0.0", - "isbinaryfile": "^4.0.8", - "js-yaml": "^4.1.0", - "lazy-val": "^1.0.5", - "minimatch": "^3.0.4", - "read-config-file": "6.2.0", - "sanitize-filename": "^1.6.3", - "semver": "^7.3.5", - "temp-file": "^3.4.0" - }, - "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "fs-extra": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", - "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "hosted-git-info": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", - "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "append-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", - "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=", - "dev": true, - "requires": { - "buffer-equal": "^1.0.0" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" - }, - "archiver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.0.tgz", - "integrity": "sha512-iUw+oDwK0fgNpvveEsdQ0Ase6IIKztBJU2U0E9MzszMfmVVUyv1QJhS2ITW9ZCqx8dktAxVAjWWkKehuZE8OPg==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "async": "^3.2.0", - "buffer-crc32": "^0.2.1", - "readable-stream": "^3.6.0", - "readdir-glob": "^1.0.0", - "tar-stream": "^2.2.0", - "zip-stream": "^4.1.0" - }, - "dependencies": { - "async": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.1.tgz", - "integrity": "sha512-XdD5lRO/87udXCMC9meWdYiR+Nq6ZjUfXidViUZGu2F1MO4T3XwZ1et0hb2++BgLfhyJwy44BGB/yx80ABx8hg==", - "dev": true - } - } - }, - "archiver-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", - "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", - "dev": true, - "requires": { - "glob": "^7.1.4", - "graceful-fs": "^4.2.0", - "lazystream": "^1.0.0", - "lodash.defaults": "^4.2.0", - "lodash.difference": "^4.5.0", - "lodash.flatten": "^4.4.0", - "lodash.isplainobject": "^4.0.6", - "lodash.union": "^4.6.0", - "normalize-path": "^3.0.0", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - } - } - }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" - }, - "arr-filter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz", - "integrity": "sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4=", - "dev": true, - "requires": { - "make-iterator": "^1.0.0" - } - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" - }, - "arr-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz", - "integrity": "sha1-Onc0X/wc814qkYJWAfnljy4kysQ=", - "dev": true, - "requires": { - "make-iterator": "^1.0.0" - } - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" - }, - "array-differ": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", - "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", - "dev": true - }, - "array-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", - "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", - "dev": true - }, - "array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", - "dev": true - }, - "array-flatten": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", - "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", - "dev": true - }, - "array-initial": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz", - "integrity": "sha1-L6dLJnOTccOUe9enrcc74zSz15U=", - "dev": true, - "requires": { - "array-slice": "^1.0.0", - "is-number": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - } - } - }, - "array-last": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz", - "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==", - "dev": true, - "requires": { - "is-number": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - } - } - }, - "array-slice": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", - "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", - "dev": true - }, - "array-sort": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz", - "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==", - "dev": true, - "requires": { - "default-compare": "^1.0.0", - "get-value": "^2.0.6", - "kind-of": "^5.0.2" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", - "dev": true, - "optional": true - }, - "asar": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/asar/-/asar-3.1.0.tgz", - "integrity": "sha512-vyxPxP5arcAqN4F/ebHd/HhwnAiZtwhglvdmc7BR2f0ywbVNTOpSeyhLDbGXtE/y58hv1oC75TaNIXutnsOZsQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "chromium-pickle-js": "^0.2.0", - "commander": "^5.0.0", - "glob": "^7.1.6", - "minimatch": "^3.0.4" - }, - "dependencies": { - "commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", - "dev": true - } - } - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "assert": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", - "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", - "dev": true, - "requires": { - "object-assign": "^4.1.1", - "util": "0.10.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - } - } - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" - }, - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "async-done": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz", - "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.2", - "process-nextick-args": "^2.0.0", - "stream-exhaust": "^1.0.1" - } - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==" - }, - "async-exit-hook": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz", - "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==", - "dev": true - }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "dev": true - }, - "async-settle": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz", - "integrity": "sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs=", - "dev": true, - "requires": { - "async-done": "^1.2.2" - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" - }, - "author-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/author-regex/-/author-regex-1.0.0.tgz", - "integrity": "sha1-0IiFvmubv5Q5/gh8dihyRfCoFFA=", - "dev": true - }, - "autoprefixer": { - "version": "9.7.4", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.4.tgz", - "integrity": "sha512-g0Ya30YrMBAEZk60lp+qfX5YQllG+S5W3GYCFvyHTvhOki0AEQJLPEcIuGRsqVwLi8FvXPVtwTGhfr38hVpm0g==", - "dev": true, - "requires": { - "browserslist": "^4.8.3", - "caniuse-lite": "^1.0.30001020", - "chalk": "^2.4.2", - "normalize-range": "^0.1.2", - "num2fraction": "^1.2.2", - "postcss": "^7.0.26", - "postcss-value-parser": "^4.0.2" - } - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" - }, - "axios": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", - "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", - "dev": true, - "requires": { - "follow-redirects": "^1.14.8" - }, - "dependencies": { - "follow-redirects": { - "version": "1.14.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", - "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==", - "dev": true - } - } - }, - "babel-loader": { - "version": "8.0.6", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.0.6.tgz", - "integrity": "sha512-4BmWKtBOBm13uoUwd08UwjZlaw3O9GWf456R9j+5YykFZ6LUIjIKLc0zEZf+hauxPOJs96C8k6FvYD09vWzhYw==", - "dev": true, - "requires": { - "find-cache-dir": "^2.0.0", - "loader-utils": "^1.0.2", - "mkdirp": "^0.5.1", - "pify": "^4.0.1" - }, - "dependencies": { - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - } - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - } - } - }, - "babel-plugin-dynamic-import-node": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", - "dev": true, - "requires": { - "object.assign": "^4.1.0" - } - }, - "babel-plugin-module-resolver": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-4.1.0.tgz", - "integrity": "sha512-MlX10UDheRr3lb3P0WcaIdtCSRlxdQsB1sBqL7W0raF070bGl1HQQq5K3T2vf2XAYie+ww+5AKC/WrkjRO2knA==", - "dev": true, - "requires": { - "find-babel-config": "^1.2.0", - "glob": "^7.1.6", - "pkg-up": "^3.1.0", - "reselect": "^4.0.0", - "resolve": "^1.13.1" - } - }, - "bach": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", - "integrity": "sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA=", - "dev": true, - "requires": { - "arr-filter": "^1.1.1", - "arr-flatten": "^1.0.1", - "arr-map": "^2.0.0", - "array-each": "^1.0.0", - "array-initial": "^1.0.0", - "array-last": "^1.1.1", - "async-done": "^1.2.2", - "async-settle": "^1.0.0", - "now-and-later": "^2.0.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true - }, - "batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "beeper": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", - "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=", - "dev": true - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==" - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - }, - "dependencies": { - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - } - } - }, - "bluebird": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", - "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=" - }, - "bluebird-lst": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.9.tgz", - "integrity": "sha512-7B1Rtx82hjnSD4PGLAjVWeYH3tHAcVUmChh85a3lltKQm6FresXh9ErQo6oAv6CqxttczC3/kEg8SY5NluPuUw==", - "dev": true, - "requires": { - "bluebird": "^3.5.5" - }, - "dependencies": { - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - } - } - }, - "bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", - "dev": true - }, - "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", - "dev": true, - "requires": { - "bytes": "3.1.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" - }, - "dependencies": { - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "dev": true - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "dev": true - } - } - }, - "bonjour": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", - "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", - "dev": true, - "requires": { - "array-flatten": "^2.1.0", - "deep-equal": "^1.0.1", - "dns-equal": "^1.0.0", - "dns-txt": "^2.0.2", - "multicast-dns": "^6.0.1", - "multicast-dns-service-types": "^1.1.0" - } - }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", - "dev": true - }, - "boolean": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.1.4.tgz", - "integrity": "sha512-3hx0kwU3uzG6ReQ3pnaFQPSktpBw6RHN3/ivDKEuU8g1XSfafowyvDnadjv1xp8IZqhtSukxlwv9bF6FhX8m0w==", - "dev": true, - "optional": true - }, - "bootstrap": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-3.4.1.tgz", - "integrity": "sha512-yN5oZVmRCwe5aKwzRj6736nSmKDX7pLYwsXiCj/EYmo16hODaBiT4En5btW/jhBF/seV+XMx3aYwukYC3A49DA==" - }, - "bower": { - "version": "1.8.12", - "resolved": "https://registry.npmjs.org/bower/-/bower-1.8.12.tgz", - "integrity": "sha512-u1xy9SrwwoPlgjuHNjhV+YUPVdqyBj2ALBxuzeIUKXaPI2i2xypGgxqXkuHcITGdi5yBj5JuXgyMvgiWiS1S3Q==", - "dev": true - }, - "boxen": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", - "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", - "dev": true, - "requires": { - "ansi-align": "^3.0.0", - "camelcase": "^6.2.0", - "chalk": "^4.1.0", - "cli-boxes": "^2.2.1", - "string-width": "^4.2.2", - "type-fest": "^0.20.2", - "widest-line": "^3.1.0", - "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - } - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "dev": true, - "requires": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - } - }, - "browserify-sign": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", - "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", - "dev": true, - "requires": { - "bn.js": "^5.1.1", - "browserify-rsa": "^4.0.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.3", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.5", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "browserslist": { - "version": "4.17.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.3.tgz", - "integrity": "sha512-59IqHJV5VGdcJZ+GZ2hU5n4Kv3YiASzW6Xk5g9tf5a/MAzGeFwgGWU39fVzNIOVcgB3+Gp+kiQu0HEfTVU/3VQ==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001264", - "electron-to-chromium": "^1.3.857", - "escalade": "^3.1.1", - "node-releases": "^1.1.77", - "picocolors": "^0.2.1" - } - }, - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "buffer-alloc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", - "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", - "dev": true, - "requires": { - "buffer-alloc-unsafe": "^1.1.0", - "buffer-fill": "^1.0.0" - } - }, - "buffer-alloc-unsafe": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", - "dev": true - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" - }, - "buffer-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", - "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=", - "dev": true - }, - "buffer-fill": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", - "dev": true - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, - "buffer-indexof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", - "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builder-util": { - "version": "22.13.1", - "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-22.13.1.tgz", - "integrity": "sha512-gMdoW9aQbWYxuQ4k4jT4An1BTo/hWzvsdv3pwNz18iNYnqn9j+xMllQOg9CHgfQYKSUd8VuMsZnbCvLO4NltYw==", - "dev": true, - "requires": { - "7zip-bin": "~5.1.1", - "@types/debug": "^4.1.6", - "@types/fs-extra": "^9.0.11", - "app-builder-bin": "3.7.1", - "bluebird-lst": "^1.0.9", - "builder-util-runtime": "8.8.1", - "chalk": "^4.1.1", - "cross-spawn": "^7.0.3", - "debug": "^4.3.2", - "fs-extra": "^10.0.0", - "is-ci": "^3.0.0", - "js-yaml": "^4.1.0", - "source-map-support": "^0.5.19", - "stat-mode": "^1.0.0", - "temp-file": "^3.4.0" - }, - "dependencies": { - "@types/fs-extra": { - "version": "9.0.13", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", - "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "fs-extra": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", - "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "builder-util-runtime": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.8.1.tgz", - "integrity": "sha512-xHxAzdsJmMV8m/N+INzYUKfyJASeKyKHnA1uGkY8Y8JKLI/c4BG+If+L0If2YETv96CiRASkvd02tIt2pvrchQ==", - "dev": true, - "requires": { - "debug": "^4.3.2", - "sax": "^1.2.4" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "builtins": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", - "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=" - }, - "bump-regex": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/bump-regex/-/bump-regex-2.9.0.tgz", - "integrity": "sha512-o4WC1mKw/kM0zScuOxZKi243lc+/h09b41u2A7HlWbxHsEDsTTZtqDZYkQj65l24J8+9Saahn5ep+EyeqpQoCg==", - "dev": true, - "requires": { - "semver": "^5.1.0", - "xtend": "^4.0.1" - } - }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "dev": true - }, - "cacache": { - "version": "11.3.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.3.tgz", - "integrity": "sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA==", - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "cacheable-lookup": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", - "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", - "dev": true - }, - "cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "dev": true, - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "dependencies": { - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true - }, - "normalize-url": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", - "dev": true - } - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", - "dev": true, - "requires": { - "callsites": "^2.0.0" - } - }, - "caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", - "dev": true, - "requires": { - "caller-callsite": "^2.0.0" - } - }, - "callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", - "dev": true - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - }, - "camelcase-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", - "dev": true, - "requires": { - "camelcase": "^2.0.0", - "map-obj": "^1.0.0" - }, - "dependencies": { - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true - } - } - }, - "caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "dev": true, - "requires": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, - "caniuse-lite": { - "version": "1.0.30001265", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001265.tgz", - "integrity": "sha512-YzBnspggWV5hep1m9Z6sZVLOt7vrju8xWooFAgN6BA5qvy98qPAPb7vNUzypFaoh2pb3vlfzbDO8tB57UPGbtw==", - "dev": true - }, - "canonical-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/canonical-path/-/canonical-path-1.0.0.tgz", - "integrity": "sha512-feylzsbDxi1gPZ1IjystzIQZagYYLvfKrSuygUCgf7z6x790VEzze5QEkdSV1U58RA7Hi0+v6fv4K54atOzATg==" - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chai": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", - "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^3.0.1", - "get-func-name": "^2.0.0", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" - } - }, - "chai-as-promised": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", - "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", - "dev": true, - "requires": { - "check-error": "^1.0.2" - } - }, - "chai-wait-for": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/chai-wait-for/-/chai-wait-for-1.0.4.tgz", - "integrity": "sha512-QvSqq6mX79HvYAPBIyE6GyehFIDhaz3Juac50dAmYP3XqyybfzQNfvOV4HZmdak97CUihWxcWyN2xvBZiB78gg==", - "dev": true, - "requires": { - "@babel/runtime": "^7.12.5" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" - }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true - }, - "chokidar": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", - "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.0", - "braces": "^2.3.0", - "fsevents": "^1.2.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "lodash.debounce": "^4.0.8", - "normalize-path": "^2.1.1", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0", - "upath": "^1.0.5" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" - }, - "chrome-launcher": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.13.4.tgz", - "integrity": "sha512-nnzXiDbGKjDSK6t2I+35OAPBy5Pw/39bgkb/ZAFwMhwJbdYBp6aH+vW28ZgtjdU890Q7D+3wN/tB8N66q5Gi2A==", - "dev": true, - "requires": { - "@types/node": "*", - "escape-string-regexp": "^1.0.5", - "is-wsl": "^2.2.0", - "lighthouse-logger": "^1.0.0", - "mkdirp": "^0.5.3", - "rimraf": "^3.0.2" - }, - "dependencies": { - "is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "requires": { - "is-docker": "^2.0.0" - } - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true - }, - "chromium-pickle-js": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz", - "integrity": "sha1-BKEGZywYsIWrd02YPfo+oTjyIgU=", - "dev": true - }, - "ci-info": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", - "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", - "dev": true - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "circular-dependency-plugin": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-5.2.0.tgz", - "integrity": "sha512-7p4Kn/gffhQaavNfyDFg7LS5S/UT1JAjyGd4UqR2+jzoYF02eDkj0Ec3+48TsIa4zghjLY87nQHIh/ecK9qLdw==", - "dev": true - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "clean-css": { - "version": "3.4.28", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-3.4.28.tgz", - "integrity": "sha1-vxlF6C/ICPVWlebd6uwBQA79A/8=", - "dev": true, - "requires": { - "commander": "2.8.x", - "source-map": "0.4.x" - }, - "dependencies": { - "commander": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", - "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", - "dev": true, - "requires": { - "graceful-readlink": ">= 1.0.0" - } - }, - "source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", - "dev": true, - "requires": { - "amdefine": ">=0.0.4" - } - } - } - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true - }, - "cli": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz", - "integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=", - "dev": true, - "optional": true, - "requires": { - "exit": "0.1.2", - "glob": "^7.1.1" - } - }, - "cli-boxes": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", - "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", - "dev": true - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "cli-truncate": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-1.1.0.tgz", - "integrity": "sha512-bAtZo0u82gCfaAGfSNxUdTI9mNyza7D8w4CVCcaOsy7sgwDzvx6ekr6cuWJqY3UGzgnQ1+4wgENup5eIhgxEYA==", - "dev": true, - "optional": true, - "requires": { - "slice-ansi": "^1.0.0", - "string-width": "^2.0.0" - } - }, - "cli-width": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", - "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==" - }, - "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", - "dev": true - }, - "clone-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", - "dev": true - }, - "clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - } - }, - "clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "clone-stats": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", - "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", - "dev": true - }, - "cloneable-readable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", - "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "process-nextick-args": "^2.0.0", - "readable-stream": "^2.3.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - } - } - }, - "coa": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", - "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", - "dev": true, - "requires": { - "@types/q": "^1.5.1", - "chalk": "^2.4.1", - "q": "^1.1.2" - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" - }, - "collection-map": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz", - "integrity": "sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw=", - "dev": true, - "requires": { - "arr-map": "^2.0.2", - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", - "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", - "dev": true, - "requires": { - "color-convert": "^1.9.3", - "color-string": "^1.6.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "color-string": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.6.0.tgz", - "integrity": "sha512-c/hGS+kRWJutUBEngKKmk4iH3sD59MBkoxVapS/0wgpCz2u7XsNloxknyvBhzwEs1IbV36D9PwqLPJ2DTu3vMA==", - "dev": true, - "requires": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, - "color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true - }, - "colors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", - "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "compare-version": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz", - "integrity": "sha1-AWLsLZNR9d3VmpICy6k1NmpyUIA=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" - }, - "compress-commons": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.1.tgz", - "integrity": "sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==", - "dev": true, - "requires": { - "buffer-crc32": "^0.2.13", - "crc32-stream": "^4.0.2", - "normalize-path": "^3.0.0", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - } - } - }, - "compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "dev": true, - "requires": { - "mime-db": ">= 1.43.0 < 2" - } - }, - "compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "dev": true, - "requires": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - } - } - }, - "concat-with-sourcemaps": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/concat-with-sourcemaps/-/concat-with-sourcemaps-1.1.0.tgz", - "integrity": "sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "config-chain": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", - "dev": true, - "optional": true, - "requires": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, - "configstore": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", - "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", - "dev": true, - "requires": { - "dot-prop": "^5.2.0", - "graceful-fs": "^4.1.2", - "make-dir": "^3.0.0", - "unique-string": "^2.0.0", - "write-file-atomic": "^3.0.0", - "xdg-basedir": "^4.0.0" - }, - "dependencies": { - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "connect-history-api-fallback": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", - "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", - "dev": true - }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", - "dev": true, - "requires": { - "safe-buffer": "5.1.2" - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "dev": true - }, - "convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", - "dev": true - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", - "dev": true - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - }, - "dependencies": { - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } - } - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" - }, - "copy-props": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.5.tgz", - "integrity": "sha512-XBlx8HSqrT0ObQwmSzM7WE5k8FxTV75h1DX1Z3n6NhQ/UYYAvInWYmG06vFt7hQZArE2fuO62aihiWIVQwh1sw==", - "dev": true, - "requires": { - "each-props": "^1.3.2", - "is-plain-object": "^5.0.0" - }, - "dependencies": { - "is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true - } - } - }, - "copy-webpack-plugin": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-6.0.3.tgz", - "integrity": "sha512-q5m6Vz4elsuyVEIUXr7wJdIdePWTubsqVbEMvf1WQnHGv0Q+9yPRu7MtYFPt+GBOXRav9lvIINifTQ1vSCs+eA==", - "dev": true, - "requires": { - "cacache": "^15.0.4", - "fast-glob": "^3.2.4", - "find-cache-dir": "^3.3.1", - "glob-parent": "^5.1.1", - "globby": "^11.0.1", - "loader-utils": "^2.0.0", - "normalize-path": "^3.0.0", - "p-limit": "^3.0.1", - "schema-utils": "^2.7.0", - "serialize-javascript": "^4.0.0", - "webpack-sources": "^1.4.3" - }, - "dependencies": { - "cacache": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", - "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", - "dev": true, - "requires": { - "@npmcli/fs": "^1.0.0", - "@npmcli/move-file": "^1.0.1", - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", - "infer-owner": "^1.0.4", - "lru-cache": "^6.0.0", - "minipass": "^3.1.1", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^1.0.3", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^8.0.1", - "tar": "^6.0.2", - "unique-filename": "^1.1.1" - } - }, - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true - }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "minipass": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.5.tgz", - "integrity": "sha512-+8NzxD82XQoNKNrl1d/FSi+X8wAEWR+sbYAfIvub4Nz0d22plFG72CEVVaufV8PNf4qSslFTD8VMOxNVhHCjTw==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, - "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "ssri": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", - "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", - "dev": true, - "requires": { - "minipass": "^3.1.1" - } - }, - "tar": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", - "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", - "dev": true, - "requires": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "core-js": { - "version": "3.6.4", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.4.tgz", - "integrity": "sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw==", - "dev": true - }, - "core-js-compat": { - "version": "3.18.2", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.18.2.tgz", - "integrity": "sha512-25VJYCJtGjZwLguj7d66oiHfmnVw3TMOZ0zV8DyMJp/aeQ3OjR519iOOeck08HMyVVRAqXxafc2Hl+5QstJrsQ==", - "dev": true, - "requires": { - "browserslist": "^4.17.3", - "semver": "7.0.0" - }, - "dependencies": { - "semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", - "dev": true - } - } - }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" - }, - "cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "dev": true, - "requires": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" - } - }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "optional": true, - "requires": { - "buffer": "^5.1.0" - }, - "dependencies": { - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "optional": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - } - } - }, - "crc-32": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.0.tgz", - "integrity": "sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==", - "dev": true, - "requires": { - "exit-on-epipe": "~1.0.1", - "printj": "~1.1.0" - } - }, - "crc32-stream": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.2.tgz", - "integrity": "sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==", - "dev": true, - "requires": { - "crc-32": "^1.2.0", - "readable-stream": "^3.4.0" - } - }, - "create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "cross-zip": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cross-zip/-/cross-zip-3.1.0.tgz", - "integrity": "sha512-aX02l0SD3KE27pMl69gkxDdDM5D3u9Ic4Je+2b1B2fP0dWnlWWY6ns2Vk5DEgCXJRhL3GasSpicNQRNbDkq0+w==", - "dev": true, - "requires": { - "rimraf": "^3.0.0" - }, - "dependencies": { - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "dev": true - }, - "css": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", - "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "source-map": "^0.6.1", - "source-map-resolve": "^0.5.2", - "urix": "^0.1.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "css-color-names": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", - "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", - "dev": true - }, - "css-declaration-sorter": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz", - "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", - "dev": true, - "requires": { - "postcss": "^7.0.1", - "timsort": "^0.3.0" - } - }, - "css-loader": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.5.1.tgz", - "integrity": "sha512-0G4CbcZzQ9D1Q6ndOfjFuMDo8uLYMu5vc9Abs5ztyHcKvmil6GJrMiNjzzi3tQvUF+mVRuDg7bE6Oc0Prolgig==", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "cssesc": "^3.0.0", - "icss-utils": "^4.1.1", - "loader-utils": "^1.2.3", - "normalize-path": "^3.0.0", - "postcss": "^7.0.27", - "postcss-modules-extract-imports": "^2.0.0", - "postcss-modules-local-by-default": "^3.0.2", - "postcss-modules-scope": "^2.2.0", - "postcss-modules-values": "^3.0.0", - "postcss-value-parser": "^4.0.3", - "schema-utils": "^2.6.5", - "semver": "^6.3.0" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "css-parse": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-2.0.0.tgz", - "integrity": "sha1-pGjuZnwW2BzPBcWMONKpfHgNv9Q=", - "dev": true, - "requires": { - "css": "^2.0.0" - } - }, - "css-select": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", - "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", - "dev": true, - "requires": { - "boolbase": "^1.0.0", - "css-what": "^3.2.1", - "domutils": "^1.7.0", - "nth-check": "^1.0.2" - } - }, - "css-select-base-adapter": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", - "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", - "dev": true - }, - "css-shorthand-properties": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/css-shorthand-properties/-/css-shorthand-properties-1.1.1.tgz", - "integrity": "sha512-Md+Juc7M3uOdbAFwOYlTrccIZ7oCFuzrhKYQjdeUEW/sE1hv17Jp/Bws+ReOPpGVBTYCBoYo+G17V5Qo8QQ75A==", - "dev": true - }, - "css-tree": { - "version": "1.0.0-alpha.37", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", - "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", - "dev": true, - "requires": { - "mdn-data": "2.0.4", - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "css-value": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/css-value/-/css-value-0.0.1.tgz", - "integrity": "sha1-Xv1sLupeof1rasV+wEJ7GEUkJOo=", - "dev": true - }, - "css-what": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", - "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", - "dev": true - }, - "cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true - }, - "csslint": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/csslint/-/csslint-1.0.5.tgz", - "integrity": "sha1-Gcw+2jIhYP0/cjKvHLKjYOiYouk=", - "dev": true, - "optional": true, - "requires": { - "clone": "~2.1.0", - "parserlib": "~1.1.1" - } - }, - "cssnano": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz", - "integrity": "sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==", - "dev": true, - "requires": { - "cosmiconfig": "^5.0.0", - "cssnano-preset-default": "^4.0.7", - "is-resolvable": "^1.0.0", - "postcss": "^7.0.0" - } - }, - "cssnano-preset-default": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.8.tgz", - "integrity": "sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ==", - "dev": true, - "requires": { - "css-declaration-sorter": "^4.0.1", - "cssnano-util-raw-cache": "^4.0.1", - "postcss": "^7.0.0", - "postcss-calc": "^7.0.1", - "postcss-colormin": "^4.0.3", - "postcss-convert-values": "^4.0.1", - "postcss-discard-comments": "^4.0.2", - "postcss-discard-duplicates": "^4.0.2", - "postcss-discard-empty": "^4.0.1", - "postcss-discard-overridden": "^4.0.1", - "postcss-merge-longhand": "^4.0.11", - "postcss-merge-rules": "^4.0.3", - "postcss-minify-font-values": "^4.0.2", - "postcss-minify-gradients": "^4.0.2", - "postcss-minify-params": "^4.0.2", - "postcss-minify-selectors": "^4.0.2", - "postcss-normalize-charset": "^4.0.1", - "postcss-normalize-display-values": "^4.0.2", - "postcss-normalize-positions": "^4.0.2", - "postcss-normalize-repeat-style": "^4.0.2", - "postcss-normalize-string": "^4.0.2", - "postcss-normalize-timing-functions": "^4.0.2", - "postcss-normalize-unicode": "^4.0.1", - "postcss-normalize-url": "^4.0.1", - "postcss-normalize-whitespace": "^4.0.2", - "postcss-ordered-values": "^4.1.2", - "postcss-reduce-initial": "^4.0.3", - "postcss-reduce-transforms": "^4.0.2", - "postcss-svgo": "^4.0.3", - "postcss-unique-selectors": "^4.0.1" - } - }, - "cssnano-util-get-arguments": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", - "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=", - "dev": true - }, - "cssnano-util-get-match": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", - "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=", - "dev": true - }, - "cssnano-util-raw-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz", - "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", - "dev": true, - "requires": { - "postcss": "^7.0.0" - } - }, - "cssnano-util-same-parent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz", - "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==", - "dev": true - }, - "csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", - "dev": true, - "requires": { - "css-tree": "^1.1.2" - }, - "dependencies": { - "css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "dev": true, - "requires": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - } - }, - "mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "cuint": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz", - "integrity": "sha1-QICG1AlVDCYxFVYZ6fp7ytw7mRs=", - "dev": true - }, - "currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", - "dev": true, - "requires": { - "array-find-index": "^1.0.1" - } - }, - "cyclist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", - "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=" - }, - "d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", - "dev": true, - "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "date-now": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", - "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", - "dev": true, - "optional": true - }, - "dateformat": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", - "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", - "dev": true, - "requires": { - "get-stdin": "^4.0.1", - "meow": "^3.3.0" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "debug-fabulous": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-1.1.0.tgz", - "integrity": "sha512-GZqvGIgKNlUnHUPQhepnUZFIMoi3dgZKQBzKDeL2g7oJF9SNAji/AAu36dusFUas0O+pae74lNeoIPHqXWDkLg==", - "dev": true, - "requires": { - "debug": "3.X", - "memoizee": "0.4.X", - "object-assign": "4.X" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - } - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" - }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "deep-equal": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", - "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", - "dev": true, - "requires": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" - } - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true - }, - "deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true - }, - "default-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz", - "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==", - "dev": true, - "requires": { - "kind-of": "^5.0.2" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "default-gateway": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", - "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", - "dev": true, - "requires": { - "execa": "^1.0.0", - "ip-regex": "^2.1.0" - } - }, - "default-resolution": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz", - "integrity": "sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ=", - "dev": true - }, - "defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", - "dev": true - }, - "define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "dev": true - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "dev": true, - "requires": { - "globby": "^5.0.0", - "is-path-cwd": "^1.0.0", - "is-path-in-cwd": "^1.0.0", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "rimraf": "^2.2.8" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", - "dev": true - }, - "is-path-in-cwd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", - "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", - "dev": true, - "requires": { - "is-path-inside": "^1.0.0" - } - }, - "is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", - "dev": true, - "requires": { - "path-is-inside": "^1.0.1" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true - }, - "dependency-graph": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.7.2.tgz", - "integrity": "sha512-KqtH4/EZdtdfWX0p6MGP9jljvxSY6msy/pRUD4jgNwVpv3v1QmNLlsB3LDSSUg79BRVSn7jI1QPRtArGABovAQ==" - }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true - }, - "detect-file": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", - "dev": true - }, - "detect-newline": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", - "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=", - "dev": true - }, - "detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "dev": true - }, - "dev-null": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/dev-null/-/dev-null-0.1.1.tgz", - "integrity": "sha1-WiBc48Ky73e2I41roXnrdMag6Bg=", - "dev": true - }, - "devtools": { - "version": "6.12.1", - "resolved": "https://registry.npmjs.org/devtools/-/devtools-6.12.1.tgz", - "integrity": "sha512-JyG46suEiZmld7/UVeogkCWM0zYGt+2ML/TI+SkEp+bTv9cs46cDb0pKF3glYZJA7wVVL2gC07Ic0iCxyJEnCQ==", - "dev": true, - "requires": { - "@wdio/config": "6.12.1", - "@wdio/logger": "6.10.10", - "@wdio/protocols": "6.12.0", - "@wdio/utils": "6.11.0", - "chrome-launcher": "^0.13.1", - "edge-paths": "^2.1.0", - "puppeteer-core": "^5.1.0", - "ua-parser-js": "^0.7.21", - "uuid": "^8.0.0" - }, - "dependencies": { - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true - } - } - }, - "devtools-protocol": { - "version": "0.0.818844", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.818844.tgz", - "integrity": "sha512-AD1hi7iVJ8OD0aMLQU5VK0XH9LDlA1+BcPIgrAxPfaibx2DbWucuyOhc4oyQCbnvDDO68nN6/LcKfqTP343Jjg==", - "dev": true - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "diff-sequences": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", - "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "dir-compare": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-2.4.0.tgz", - "integrity": "sha512-l9hmu8x/rjVC9Z2zmGzkhOEowZvW7pmYws5CWHutg8u1JgvsKWMx7Q/UODeu4djLZ4FgW5besw5yvMQnBHzuCA==", - "dev": true, - "requires": { - "buffer-equal": "1.0.0", - "colors": "1.0.3", - "commander": "2.9.0", - "minimatch": "3.0.4" - }, - "dependencies": { - "commander": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", - "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", - "dev": true, - "requires": { - "graceful-readlink": ">= 1.0.0" - } - } - } - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "dmg-builder": { - "version": "22.13.1", - "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-22.13.1.tgz", - "integrity": "sha512-qgfLN2fo4q2wIWNvbcKlZ71DLRDLvWIElOB7oxlSxUrMi6xhI+9v1Mh7E0FJ+r5UXhQzaQXaGuyMsQRbGgrSwg==", - "dev": true, - "requires": { - "app-builder-lib": "22.13.1", - "builder-util": "22.13.1", - "builder-util-runtime": "8.8.1", - "dmg-license": "^1.0.9", - "fs-extra": "^10.0.0", - "iconv-lite": "^0.6.2", - "js-yaml": "^4.1.0" - }, - "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "fs-extra": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", - "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - } - } - }, - "dmg-license": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/dmg-license/-/dmg-license-1.0.9.tgz", - "integrity": "sha512-Rq6qMDaDou2+aPN2SYy0x7LDznoJ/XaG6oDcH5wXUp+WRWQMUYE6eM+F+nex+/LSXOp1uw4HLFoed0YbfU8R/Q==", - "dev": true, - "optional": true, - "requires": { - "@types/plist": "^3.0.1", - "@types/verror": "^1.10.3", - "ajv": "^6.10.0", - "cli-truncate": "^1.1.0", - "crc": "^3.8.0", - "iconv-corefoundation": "^1.1.6", - "plist": "^3.0.1", - "smart-buffer": "^4.0.2", - "verror": "^1.10.0" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "optional": true, - "requires": { - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - } - } - }, - "dns-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", - "dev": true - }, - "dns-packet": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.4.tgz", - "integrity": "sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==", - "dev": true, - "requires": { - "ip": "^1.1.0", - "safe-buffer": "^5.0.1" - } - }, - "dns-txt": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", - "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", - "dev": true, - "requires": { - "buffer-indexof": "^1.0.0" - } - }, - "dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", - "dev": true, - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", - "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", - "dev": true - } - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", - "dev": true - }, - "domhandler": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", - "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", - "dev": true, - "optional": true, - "requires": { - "domelementtype": "1" - } - }, - "domino": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/domino/-/domino-2.1.6.tgz", - "integrity": "sha512-3VdM/SXBZX2omc9JF9nOPCtDaYQ67BGp5CoLpIQlO2KCAPETs8TcDHacF26jXadGbvUteZzRTeos2fhID5+ucQ==" - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "dev": true, - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "dev": true, - "requires": { - "is-obj": "^2.0.0" - } - }, - "dotenv": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-9.0.2.tgz", - "integrity": "sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg==", - "dev": true - }, - "dotenv-expand": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", - "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==", - "dev": true - }, - "duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "dev": true - }, - "duplexer2": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", - "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", - "dev": true, - "requires": { - "readable-stream": "~1.1.9" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } - } - }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - } - } - }, - "each-props": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz", - "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.1", - "object.defaults": "^1.1.0" - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "edge-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/edge-paths/-/edge-paths-2.2.1.tgz", - "integrity": "sha512-AI5fC7dfDmCdKo3m5y7PkYE8m6bMqR6pvVpgtrZkkhcJXFLelUgkjrhk3kXXx8Kbw2cRaTT4LkOR7hqf39KJdw==", - "dev": true, - "requires": { - "@types/which": "^1.3.2", - "which": "^2.0.2" - }, - "dependencies": { - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "ejs": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.6.tgz", - "integrity": "sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==", - "dev": true, - "requires": { - "jake": "^10.6.1" - } - }, - "electron": { - "version": "10.4.7", - "resolved": "https://registry.npmjs.org/electron/-/electron-10.4.7.tgz", - "integrity": "sha512-je+AokZfKldI5GItXOx5pwBEAnbEqTrEPhaRUm2RN0OFBPXO+7wjJ3X+HvvlOHvKtfZrlU+57Dmkg1DseSFOPA==", - "dev": true, - "requires": { - "@electron/get": "^1.0.1", - "@types/node": "^12.0.12", - "extract-zip": "^1.0.3" - } - }, - "electron-builder": { - "version": "22.13.1", - "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-22.13.1.tgz", - "integrity": "sha512-ajlI40L60qKBBxvpf770kcjxHAccMpEWpwsHAppytl3WmWgJfMut4Wz9VUFqyNtX/9a624QTatk6TqoxqewRug==", - "dev": true, - "requires": { - "@types/yargs": "^17.0.1", - "app-builder-lib": "22.13.1", - "builder-util": "22.13.1", - "builder-util-runtime": "8.8.1", - "chalk": "^4.1.1", - "dmg-builder": "22.13.1", - "fs-extra": "^10.0.0", - "is-ci": "^3.0.0", - "lazy-val": "^1.0.5", - "read-config-file": "6.2.0", - "update-notifier": "^5.1.0", - "yargs": "^17.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "fs-extra": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", - "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yargs": { - "version": "17.2.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.2.1.tgz", - "integrity": "sha512-XfR8du6ua4K6uLGm5S6fA+FIJom/MdJcFNVY8geLlp2v8GYbOXD4EB1tPNZsRn4vBzKGMgb5DRZMeWuFc2GO8Q==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - }, - "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true - } - } - }, - "electron-chromedriver": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/electron-chromedriver/-/electron-chromedriver-10.0.0.tgz", - "integrity": "sha512-6jvMnQNHsIFTnvSn8kYQk8dRXFjqtp7E4QVIP4Cc6xR7SM8QI0/EmAqfuysd8CGJOpa8wFkEYxCT2dbHGp3bDw==", - "dev": true, - "requires": { - "@electron/get": "^1.12.2", - "extract-zip": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dev": true, - "requires": { - "@types/yauzl": "^2.9.1", - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - } - }, - "fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", - "dev": true, - "requires": { - "pend": "~1.2.0" - } - }, - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", - "dev": true, - "requires": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - } - } - }, - "electron-default-menu": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/electron-default-menu/-/electron-default-menu-1.0.2.tgz", - "integrity": "sha512-YAL/UNR3kPG58wOOlmDpTG3i6+bzwhHx6NllIOaLuVrU7uYifeYGGdk5IH2Hap4wVEx2YTA8cqQ2PGSplYwDWQ==" - }, - "electron-notarize": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/electron-notarize/-/electron-notarize-0.2.1.tgz", - "integrity": "sha512-oZ6/NhKeXmEKNROiFmRNfytqu3cxqC95sjooG7kBXQVEUSQkZnbiAhxVh5jXngL881G197pbwpeVPJyM7Ikmxw==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "fs-extra": "^8.1.0" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "electron-osx-sign": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.5.0.tgz", - "integrity": "sha512-icoRLHzFz/qxzDh/N4Pi2z4yVHurlsCAYQvsCSG7fCedJ4UJXBS6PoQyGH71IfcqKupcKeK7HX/NkyfG+v6vlQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.0", - "compare-version": "^0.1.2", - "debug": "^2.6.8", - "isbinaryfile": "^3.0.2", - "minimist": "^1.2.0", - "plist": "^3.0.1" - }, - "dependencies": { - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "isbinaryfile": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.3.tgz", - "integrity": "sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw==", - "dev": true, - "requires": { - "buffer-alloc": "^1.2.0" - } - } - } - }, - "electron-packager": { - "version": "14.2.1", - "resolved": "https://registry.npmjs.org/electron-packager/-/electron-packager-14.2.1.tgz", - "integrity": "sha512-g6y3BVrAOz/iavKD+VMFbehrQcwCWuA3CZvVbmmbQuCfegGA1ytwWn0BNIDDrEdbuz31Fti7mnNHhb5L+3Wq9A==", - "dev": true, - "requires": { - "@electron/get": "^1.6.0", - "asar": "^2.0.1", - "cross-zip": "^3.0.0", - "debug": "^4.0.1", - "electron-notarize": "^0.2.0", - "electron-osx-sign": "^0.4.11", - "fs-extra": "^8.1.0", - "galactus": "^0.2.1", - "get-package-info": "^1.0.0", - "junk": "^3.1.0", - "parse-author": "^2.0.0", - "plist": "^3.0.0", - "rcedit": "^2.0.0", - "resolve": "^1.1.6", - "sanitize-filename": "^1.6.0", - "semver": "^6.0.0", - "yargs-parser": "^16.0.0" - }, - "dependencies": { - "asar": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/asar/-/asar-2.1.0.tgz", - "integrity": "sha512-d2Ovma+bfqNpvBzY/KU8oPY67ZworixTpkjSx0PCXnQi67c2cXmssaTxpFDUM0ttopXoGx/KRxNg/GDThYbXQA==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "chromium-pickle-js": "^0.2.0", - "commander": "^2.20.0", - "cuint": "^0.2.2", - "glob": "^7.1.3", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "tmp-promise": "^1.0.5" - } - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "electron-osx-sign": { - "version": "0.4.17", - "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.4.17.tgz", - "integrity": "sha512-wUJPmZJQCs1zgdlQgeIpRcvrf7M5/COQaOV68Va1J/SgmWx5KL2otgg+fAae7luw6qz9R8Gvu/Qpe9tAOu/3xQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.0", - "compare-version": "^0.1.2", - "debug": "^2.6.8", - "isbinaryfile": "^3.0.2", - "minimist": "^1.2.0", - "plist": "^3.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "isbinaryfile": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.3.tgz", - "integrity": "sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw==", - "dev": true, - "requires": { - "buffer-alloc": "^1.2.0" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "tmp": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.1.0.tgz", - "integrity": "sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==", - "dev": true, - "requires": { - "rimraf": "^2.6.3" - } - }, - "tmp-promise": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-1.1.0.tgz", - "integrity": "sha512-8+Ah9aB1IRXCnIOxXZ0uFozV1nMU5xiu7hhFVUSxZ3bYu+psD4TzagCzVbexUCgNNGJnsmNDQlS4nG3mTyoNkw==", - "dev": true, - "requires": { - "bluebird": "^3.5.0", - "tmp": "0.1.0" - } - }, - "yargs-parser": { - "version": "16.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-16.1.0.tgz", - "integrity": "sha512-H/V41UNZQPkUMIT5h5hiwg4QKIY1RPvoBV4XcjUbRM8Bk2oKqqyZ0DIEbTFZB0XjbtSPG8SAa/0DxCQmiRgzKg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, - "electron-publish": { - "version": "22.13.1", - "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-22.13.1.tgz", - "integrity": "sha512-5nCXhnsqrRxP5NsZxUKjiMkcFmQglXp7i/YY4rp3h1s1psg3utOIkM29Z93YTSXicZJU1J+8811eo5HX1vpoKg==", - "dev": true, - "requires": { - "@types/fs-extra": "^9.0.11", - "builder-util": "22.13.1", - "builder-util-runtime": "8.8.1", - "chalk": "^4.1.1", - "fs-extra": "^10.0.0", - "lazy-val": "^1.0.5", - "mime": "^2.5.2" - }, - "dependencies": { - "@types/fs-extra": { - "version": "9.0.13", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", - "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "fs-extra": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", - "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "mime": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", - "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - } - } - }, - "electron-to-chromium": { - "version": "1.3.866", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.866.tgz", - "integrity": "sha512-iYze6TpDXWxk+sfcpUUdTs6Pv/3kG45Pnjer2DxEeFw0N08bZeNLuz97s2lMgy8yObon48o0WHY2Bkg3xuAPOA==", - "dev": true - }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true - }, - "encoding": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", - "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "requires": { - "iconv-lite": "^0.6.2" - } - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", - "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - } - }, - "entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true - }, - "env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true - }, - "err-code": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz", - "integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=" - }, - "errno": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", - "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", - "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", - "is-string": "^1.0.7", - "is-weakref": "^1.0.1", - "object-inspect": "^1.11.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es5-ext": { - "version": "0.10.53", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", - "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", - "dev": true, - "requires": { - "es6-iterator": "~2.0.3", - "es6-symbol": "~3.1.3", - "next-tick": "~1.0.0" - } - }, - "es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true, - "optional": true - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, - "es6-shim": { - "version": "0.35.6", - "resolved": "https://registry.npmjs.org/es6-shim/-/es6-shim-0.35.6.tgz", - "integrity": "sha512-EmTr31wppcaIAgblChZiuN/l9Y7DPyw8Xtbg7fIVngn6zMW+IEBJDJngeKC3x6wr0V/vcA2wqeFnaw1bFJbDdA==" - }, - "es6-symbol": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", - "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", - "dev": true, - "requires": { - "d": "^1.0.1", - "ext": "^1.1.2" - } - }, - "es6-weak-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", - "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.46", - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.1" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-goat": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz", - "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==", - "dev": true - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true - }, - "event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "event-stream": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.5.tgz", - "integrity": "sha512-vyibDcu5JL20Me1fP734QBH/kenBGLZap2n0+XXM7mvuUPzJ20Ydqj1aKcIeMdri1p+PU+4yAKugjN8KCVst+g==", - "dev": true, - "requires": { - "duplexer": "^0.1.1", - "from": "^0.1.7", - "map-stream": "0.0.7", - "pause-stream": "^0.0.11", - "split": "^1.0.1", - "stream-combiner": "^0.2.2", - "through": "^2.3.8" - } - }, - "eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true - }, - "eventsource": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.0.tgz", - "integrity": "sha512-VSJjT5oCNrFvCS6igjzPAt5hBzQ2qPBFIbJ03zLI9SE0mxwZpMw6BfJrbFHm1a141AavMEB8JHmBhWAd66PfCg==", - "dev": true, - "requires": { - "original": "^1.0.0" - } - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true, - "optional": true - }, - "exit-hook": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", - "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", - "dev": true - }, - "exit-on-epipe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", - "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==", - "dev": true - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, - "expect": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.2.5.tgz", - "integrity": "sha512-ZrO0w7bo8BgGoP/bLz+HDCI+0Hfei9jUSZs5yI/Wyn9VkG9w8oJ7rHRgYj+MA7yqqFa0IwHA3flJzZtYugShJA==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "ansi-styles": "^5.0.0", - "jest-get-type": "^27.0.6", - "jest-matcher-utils": "^27.2.5", - "jest-message-util": "^27.2.5", - "jest-regex-util": "^27.0.6" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - } - } - }, - "express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", - "dev": true, - "requires": { - "accepts": "~1.3.7", - "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", - "content-type": "~1.0.4", - "cookie": "0.4.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "~1.1.2", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.1.2", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", - "dev": true - }, - "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "dev": true - } - } - }, - "ext": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz", - "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==", - "dev": true, - "requires": { - "type": "^2.5.0" - }, - "dependencies": { - "type": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/type/-/type-2.5.0.tgz", - "integrity": "sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==", - "dev": true - } - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, - "dependencies": { - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "extract-zip": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", - "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==", - "dev": true, - "requires": { - "concat-stream": "^1.6.2", - "debug": "^2.6.9", - "mkdirp": "^0.5.4", - "yauzl": "^2.10.0" - }, - "dependencies": { - "fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", - "dev": true, - "requires": { - "pend": "~1.2.0" - } - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", - "dev": true, - "requires": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - } - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fancy-log": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", - "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", - "dev": true, - "requires": { - "ansi-gray": "^0.1.1", - "color-support": "^1.1.3", - "parse-node-version": "^1.0.0", - "time-stamp": "^1.0.0" - } - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" - }, - "fast-glob": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", - "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "dependencies": { - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" - }, - "fast-levenshtein": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.1.4.tgz", - "integrity": "sha1-5qdUzI8V5YmHqpy9J69m/W9OWvk=", - "dev": true - }, - "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "faye-websocket": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", - "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", - "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "fd-slicer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", - "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", - "requires": { - "pend": "~1.2.0" - } - }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==" - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "file-loader": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.0.0.tgz", - "integrity": "sha512-/aMOAYEFXDdjG0wytpTL5YQLfZnnTmLNjn+AIrJ/6HVnTfDqLsVKUUwkDf4I4kgex36BvjuXEn/TX9B/1ESyqQ==", - "dev": true, - "requires": { - "loader-utils": "^2.0.0", - "schema-utils": "^2.6.5" - } - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "optional": true - }, - "filelist": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz", - "integrity": "sha512-z7O0IS8Plc39rTCq6i6iHxk43duYOn8uFJiWSewIq0Bww1RNybVHSCjahmcC87ZqAm4OTvFzlzeGu3XAzG1ctQ==", - "dev": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.3", - "statuses": "~1.5.0", - "unpipe": "~1.0.0" - } - }, - "find-babel-config": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-1.2.0.tgz", - "integrity": "sha512-jB2CHJeqy6a820ssiqwrKMeyC6nNdmrcgkKWJWmpoxpE8RKciYJXCcXRq1h2AzCo5I5BJeN2tkGEO3hLTuePRA==", - "dev": true, - "requires": { - "json5": "^0.5.1", - "path-exists": "^3.0.0" - }, - "dependencies": { - "json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true - } - } - }, - "find-cache-dir": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", - "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, - "findup-sync": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", - "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", - "dev": true, - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^4.0.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - } - }, - "fined": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", - "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", - "dev": true, - "requires": { - "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" - } - }, - "first-chunk-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz", - "integrity": "sha1-G97NuOCDwGZLkZRVgVd6Q6nzHXA=", - "dev": true, - "requires": { - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - } - } - }, - "flagged-respawn": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", - "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", - "dev": true - }, - "flat": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", - "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", - "dev": true - } - } - }, - "flora-colossus": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/flora-colossus/-/flora-colossus-1.0.1.tgz", - "integrity": "sha512-d+9na7t9FyH8gBJoNDSi28mE4NgQVGGvxQ4aHtFRetjyh5SXjuus+V5EZaxFmFdXVemSOrx0lsgEl/ZMjnOWJA==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "fs-extra": "^7.0.0" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - } - } - }, - "follow-redirects": { - "version": "1.14.4", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.4.tgz", - "integrity": "sha512-zwGkiSXC1MUJG/qmeIFH2HBJx9u0V46QGUe3YR1fXG8bXQxq7fLj0RjLZQ5nubr9qNJUZrH+xUcwXEoXNpfS+g==", - "dev": true - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" - }, - "for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "foreachasync": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/foreachasync/-/foreachasync-3.0.0.tgz", - "integrity": "sha1-VQKYfchxS+M5IJfzLgBxyd7gfPY=", - "dev": true - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "dev": true - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "requires": { - "map-cache": "^0.2.2" - } - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true - }, - "from": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", - "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", - "dev": true - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - } - } - }, - "fs": { - "version": "0.0.1-security", - "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz", - "integrity": "sha1-invTcYa23d84E/I4WLV+yq9eQdQ=", - "dev": true - }, - "fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true - }, - "fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, - "fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "requires": { - "minipass": "^2.6.0" - } - }, - "fs-mkdirp-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", - "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "through2": "^2.0.3" - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - } - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "galactus": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/galactus/-/galactus-0.2.1.tgz", - "integrity": "sha1-y+0tIKQMH1Z5o1kI4rlBVzPnjbk=", - "dev": true, - "requires": { - "debug": "^3.1.0", - "flora-colossus": "^1.0.0", - "fs-extra": "^4.0.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - } - } - }, - "genfun": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/genfun/-/genfun-5.0.0.tgz", - "integrity": "sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA==" - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-package-info": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-package-info/-/get-package-info-1.0.0.tgz", - "integrity": "sha1-ZDJ5ZWPigRPNlHTbvQAFKYWkmZw=", - "dev": true, - "requires": { - "bluebird": "^3.1.1", - "debug": "^2.2.0", - "lodash.get": "^4.0.0", - "read-pkg-up": "^2.0.0" - } - }, - "get-port": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz", - "integrity": "sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==", - "dev": true - }, - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "dev": true - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - } - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" - }, - "dependencies": { - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "glob-stream": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", - "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - } - } - }, - "glob-watcher": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.5.tgz", - "integrity": "sha512-zOZgGGEHPklZNjZQaZ9f41i7F2YwE+tS5ZHrDhbBCk3stwahn5vQxnFmBJZHoYdusR6R1bLSXeGUy/BhctwKzw==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-done": "^1.2.0", - "chokidar": "^2.0.0", - "is-negated-glob": "^1.0.0", - "just-debounce": "^1.0.0", - "normalize-path": "^3.0.0", - "object.defaults": "^1.1.0" - }, - "dependencies": { - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - } - } - }, - "global-agent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-2.2.0.tgz", - "integrity": "sha512-+20KpaW6DDLqhG7JDiJpD1JvNvb8ts+TNl7BPOYcURqCrXqnN1Vf+XVOrkKJAFPqfX+oEhsdzOj1hLWkBTdNJg==", - "dev": true, - "optional": true, - "requires": { - "boolean": "^3.0.1", - "core-js": "^3.6.5", - "es6-error": "^4.1.1", - "matcher": "^3.0.0", - "roarr": "^2.15.3", - "semver": "^7.3.2", - "serialize-error": "^7.0.1" - }, - "dependencies": { - "core-js": { - "version": "3.18.2", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.18.2.tgz", - "integrity": "sha512-zNhPOUoSgoizoSQFdX1MeZO16ORRb9FFQLts8gSYbZU5FcgXhp24iMWMxnOQo5uIaIG7/6FA/IqJPwev1o9ZXQ==", - "dev": true, - "optional": true - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "optional": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "optional": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "optional": true - } - } - }, - "global-dirs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", - "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", - "dev": true, - "requires": { - "ini": "2.0.0" - }, - "dependencies": { - "ini": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", - "dev": true - } - } - }, - "global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "dev": true, - "requires": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" - } - }, - "global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", - "dev": true, - "requires": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" - } - }, - "global-tunnel-ng": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz", - "integrity": "sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg==", - "dev": true, - "optional": true, - "requires": { - "encodeurl": "^1.0.2", - "lodash": "^4.17.10", - "npm-conf": "^1.1.3", - "tunnel": "^0.0.6" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, - "globalthis": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.2.tgz", - "integrity": "sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ==", - "dev": true, - "optional": true, - "requires": { - "define-properties": "^1.1.3" - } - }, - "globby": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", - "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - } - }, - "glogg": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz", - "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==", - "dev": true, - "requires": { - "sparkles": "^1.0.0" - } - }, - "got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", - "dev": true, - "requires": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" - } - }, - "graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" - }, - "graceful-readlink": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", - "dev": true - }, - "grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true - }, - "group-array": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/group-array/-/group-array-0.3.4.tgz", - "integrity": "sha512-YAmNsgsi1uQ7Ai3T4FFkMoskqbLEUPRajAmrn8FclwZQQnV98NLrNWjQ3n2+i1pANxdO3n6wsNEkKq5XrYy0Ow==", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1", - "for-own": "^0.1.4", - "get-value": "^2.0.6", - "kind-of": "^3.1.0", - "split-string": "^1.0.1", - "union-value": "^1.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "split-string": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-1.0.1.tgz", - "integrity": "sha1-vLqz9BUqzuOg1qskecDSh5w9s84=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1" - } - } - } - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "gulp": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz", - "integrity": "sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==", - "dev": true, - "requires": { - "glob-watcher": "^5.0.3", - "gulp-cli": "^2.2.0", - "undertaker": "^1.2.1", - "vinyl-fs": "^3.0.0" - }, - "dependencies": { - "ansi-colors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", - "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", - "dev": true, - "requires": { - "ansi-wrap": "^0.1.0" - } - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "gulp-cli": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.3.0.tgz", - "integrity": "sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A==", - "dev": true, - "requires": { - "ansi-colors": "^1.0.1", - "archy": "^1.0.0", - "array-sort": "^1.0.0", - "color-support": "^1.1.3", - "concat-stream": "^1.6.0", - "copy-props": "^2.0.1", - "fancy-log": "^1.3.2", - "gulplog": "^1.0.0", - "interpret": "^1.4.0", - "isobject": "^3.0.1", - "liftoff": "^3.1.0", - "matchdep": "^2.0.0", - "mute-stdout": "^1.0.0", - "pretty-hrtime": "^1.0.0", - "replace-homedir": "^1.0.0", - "semver-greatest-satisfied-range": "^1.1.0", - "v8flags": "^3.2.0", - "yargs": "^7.1.0" - } - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - } - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "dev": true, - "requires": { - "lcid": "^1.0.0" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - } - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - }, - "which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", - "dev": true - }, - "y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", - "dev": true - }, - "yargs": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.2.tgz", - "integrity": "sha512-ZEjj/dQYQy0Zx0lgLMLR8QuaqTihnxirir7EwUHp1Axq4e3+k8jXU5K0VLbNvedv1f4EWtBonDIZm0NUr+jCcA==", - "dev": true, - "requires": { - "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.1" - } - }, - "yargs-parser": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.1.tgz", - "integrity": "sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA==", - "dev": true, - "requires": { - "camelcase": "^3.0.0", - "object.assign": "^4.1.0" - } - } - } - }, - "gulp-bower": { - "version": "0.0.15", - "resolved": "https://registry.npmjs.org/gulp-bower/-/gulp-bower-0.0.15.tgz", - "integrity": "sha512-D3YOsoy49d2s/msDRfSLSDMwSpS3Q/+pe1u14x8/zO95YSpvCGAWRX26YUj219xxbTO0CVvlsek1GuSwSv5Lpg==", - "dev": true, - "requires": { - "ansi-colors": "^1.0.1", - "bower": "^1.3.12", - "fancy-log": "^1.3.2", - "inquirer": "^0.11.2", - "plugin-error": "^0.1.2", - "through2": "0.6.2", - "vinyl": "^2.1.0", - "walk": "2.3.3" - }, - "dependencies": { - "ansi-colors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", - "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", - "dev": true, - "requires": { - "ansi-wrap": "^0.1.0" - } - }, - "ansi-escapes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "cli-cursor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", - "dev": true, - "requires": { - "restore-cursor": "^1.0.1" - } - }, - "cli-width": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-1.1.1.tgz", - "integrity": "sha1-pNKT72frt7iNSk1CwMzwDE0eNm0=", - "dev": true - }, - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" - } - }, - "inquirer": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.11.4.tgz", - "integrity": "sha1-geM3ToNhvq/y2XAWIG01nQsy+k0=", - "dev": true, - "requires": { - "ansi-escapes": "^1.1.0", - "ansi-regex": "^2.0.0", - "chalk": "^1.0.0", - "cli-cursor": "^1.0.1", - "cli-width": "^1.0.1", - "figures": "^1.3.5", - "lodash": "^3.3.1", - "readline2": "^1.0.1", - "run-async": "^0.1.0", - "rx-lite": "^3.1.2", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.0", - "through": "^2.3.6" - } - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", - "dev": true - }, - "onetime": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "restore-cursor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", - "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", - "dev": true, - "requires": { - "exit-hook": "^1.0.0", - "onetime": "^1.0.0" - } - }, - "run-async": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", - "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", - "dev": true, - "requires": { - "once": "^1.3.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - }, - "through2": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.2.tgz", - "integrity": "sha1-UyZYJMVV5/zcQRHc3FLH3mRjbHU=", - "dev": true, - "requires": { - "readable-stream": ">=1.0.28 <1.1.0-0", - "xtend": ">=4.0.0 <4.1.0-0" - } - } - } - }, - "gulp-bump": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/gulp-bump/-/gulp-bump-2.4.0.tgz", - "integrity": "sha1-NukXQ58FI9GqoxBf8qRfvyziWBI=", - "dev": true, - "requires": { - "bump-regex": "^2.3.0", - "plugin-error": "^0.1.2", - "plugin-log": "^0.1.0", - "semver": "^5.3.0", - "through2": "^2.0.1" - } - }, - "gulp-clean-css": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/gulp-clean-css/-/gulp-clean-css-2.3.2.tgz", - "integrity": "sha1-dBB2nER0wSzNVemOp0sYmNQorNA=", - "dev": true, - "requires": { - "clean-css": "^3.4.23", - "gulp-util": "^3.0.7", - "object-assign": "^4.1.0", - "through2": "^2.0.3", - "vinyl-sourcemaps-apply": "^0.2.1" - } - }, - "gulp-concat": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/gulp-concat/-/gulp-concat-2.6.1.tgz", - "integrity": "sha1-Yz0WyV2IUEYorQJmVmPO5aR5M1M=", - "dev": true, - "requires": { - "concat-with-sourcemaps": "^1.0.0", - "through2": "^2.0.0", - "vinyl": "^2.0.0" - } - }, - "gulp-debug": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/gulp-debug/-/gulp-debug-2.1.2.tgz", - "integrity": "sha1-L1/l9kvNH0zxicFg4IDIrQZUMJQ=", - "dev": true, - "requires": { - "chalk": "^1.0.0", - "gulp-util": "^3.0.0", - "object-assign": "^4.0.1", - "plur": "^2.0.0", - "stringify-object": "^2.3.0", - "through2": "^2.0.0", - "tildify": "^1.1.2" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "gulp-filter": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/gulp-filter/-/gulp-filter-4.0.0.tgz", - "integrity": "sha1-OV9YolbFWc254NFX8cqvUkijjcs=", - "dev": true, - "requires": { - "gulp-util": "^3.0.6", - "multimatch": "^2.0.0", - "streamfilter": "^1.0.5" - } - }, - "gulp-git": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/gulp-git/-/gulp-git-2.10.1.tgz", - "integrity": "sha512-qiXYYDXchMZU/AWAgtphi4zbJb/0gXgfPw7TlZwu/7qPS3Bdcc3zbVe1B0xY9S8on6RQTmWoi+KaTGACIXQeNg==", - "dev": true, - "requires": { - "any-shell-escape": "^0.1.1", - "fancy-log": "^1.3.2", - "lodash.template": "^4.4.0", - "plugin-error": "^1.0.1", - "require-dir": "^1.0.0", - "strip-bom-stream": "^3.0.0", - "through2": "^2.0.3", - "vinyl": "^2.0.1" - }, - "dependencies": { - "ansi-colors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", - "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", - "dev": true, - "requires": { - "ansi-wrap": "^0.1.0" - } - }, - "lodash.template": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", - "dev": true, - "requires": { - "lodash._reinterpolate": "^3.0.0", - "lodash.templatesettings": "^4.0.0" - } - }, - "lodash.templatesettings": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", - "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", - "dev": true, - "requires": { - "lodash._reinterpolate": "^3.0.0" - } - }, - "plugin-error": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", - "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", - "dev": true, - "requires": { - "ansi-colors": "^1.0.1", - "arr-diff": "^4.0.0", - "arr-union": "^3.1.0", - "extend-shallow": "^3.0.2" - } - } - } - }, - "gulp-htmlhint": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/gulp-htmlhint/-/gulp-htmlhint-3.0.1.tgz", - "integrity": "sha512-zUdJi3SdedDjc+rZaUq8hD27jRzn6kqrxgu76NhlmfMNKYVlavrcPNEew+xA4NYEHOgyf0WW9DWYuJ/YgL0Riw==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1", - "beeper": "^2.0.0", - "fancy-log": "^1.3.2", - "htmlhint": "^0.10.1", - "plugin-error": "^1.0.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.0.1", - "through2": "^3.0.1", - "vinyl": "^2.2.0" - }, - "dependencies": { - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "beeper": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/beeper/-/beeper-2.1.0.tgz", - "integrity": "sha512-85+CcymhlP0jM4fs4ZMiMRl58VthoN9NRdvi+knXiQpP2UggkSre+A9rOZ0c2g2Vh+pEF5ZAlT+k8dsJNoanAA==", - "dev": true, - "requires": { - "yoctodelay": "^1.1.0" - } - }, - "plugin-error": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", - "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", - "dev": true, - "requires": { - "ansi-colors": "^1.0.1", - "arr-diff": "^4.0.0", - "arr-union": "^3.1.0", - "extend-shallow": "^3.0.2" - }, - "dependencies": { - "ansi-colors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", - "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", - "dev": true, - "requires": { - "ansi-wrap": "^0.1.0" - } - } - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "through2": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "2 || 3" - } - } - } - }, - "gulp-inject": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/gulp-inject/-/gulp-inject-4.1.0.tgz", - "integrity": "sha1-z+0E84S1E9SzFFj/zmuTSRSg0zs=", - "dev": true, - "requires": { - "arrify": "^1.0.1", - "escape-string-regexp": "^1.0.5", - "event-stream": "^3.1.0", - "group-array": "^0.3.0", - "gulp-util": "^3.0.0", - "stream-to-array": "^2.3.0", - "through2": "^2.0.1" - } - }, - "gulp-sourcemaps": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-2.6.5.tgz", - "integrity": "sha512-SYLBRzPTew8T5Suh2U8jCSDKY+4NARua4aqjj8HOysBh2tSgT9u4jc1FYirAdPx1akUxxDeK++fqw6Jg0LkQRg==", - "dev": true, - "requires": { - "@gulp-sourcemaps/identity-map": "1.X", - "@gulp-sourcemaps/map-sources": "1.X", - "acorn": "5.X", - "convert-source-map": "1.X", - "css": "2.X", - "debug-fabulous": "1.X", - "detect-newline": "2.X", - "graceful-fs": "4.X", - "source-map": "~0.6.0", - "strip-bom-string": "1.X", - "through2": "2.X" - }, - "dependencies": { - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "gulp-typescript": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/gulp-typescript/-/gulp-typescript-4.0.2.tgz", - "integrity": "sha512-Hhbn5Aa2l3T+tnn0KqsG6RRJmcYEsr3byTL2nBpNBeAK8pqug9Od4AwddU4JEI+hRw7mzZyjRbB8DDWR6paGVA==", - "dev": true, - "requires": { - "ansi-colors": "^1.0.1", - "plugin-error": "^0.1.2", - "source-map": "^0.6.1", - "through2": "^2.0.3", - "vinyl": "^2.1.0", - "vinyl-fs": "^3.0.0" - }, - "dependencies": { - "ansi-colors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", - "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", - "dev": true, - "requires": { - "ansi-wrap": "^0.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "gulp-uglify": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/gulp-uglify/-/gulp-uglify-3.0.2.tgz", - "integrity": "sha512-gk1dhB74AkV2kzqPMQBLA3jPoIAPd/nlNzP2XMDSG8XZrqnlCiDGAqC+rZOumzFvB5zOphlFh6yr3lgcAb/OOg==", - "dev": true, - "requires": { - "array-each": "^1.0.1", - "extend-shallow": "^3.0.2", - "gulplog": "^1.0.0", - "has-gulplog": "^0.1.0", - "isobject": "^3.0.1", - "make-error-cause": "^1.1.1", - "safe-buffer": "^5.1.2", - "through2": "^2.0.0", - "uglify-js": "^3.0.5", - "vinyl-sourcemaps-apply": "^0.2.0" - } - }, - "gulp-util": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz", - "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=", - "dev": true, - "requires": { - "array-differ": "^1.0.0", - "array-uniq": "^1.0.2", - "beeper": "^1.0.0", - "chalk": "^1.0.0", - "dateformat": "^2.0.0", - "fancy-log": "^1.1.0", - "gulplog": "^1.0.0", - "has-gulplog": "^0.1.0", - "lodash._reescape": "^3.0.0", - "lodash._reevaluate": "^3.0.0", - "lodash._reinterpolate": "^3.0.0", - "lodash.template": "^3.0.0", - "minimist": "^1.1.0", - "multipipe": "^0.1.2", - "object-assign": "^3.0.0", - "replace-ext": "0.0.1", - "through2": "^2.0.0", - "vinyl": "^0.5.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", - "dev": true - }, - "clone-stats": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", - "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", - "dev": true - }, - "dateformat": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz", - "integrity": "sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI=", - "dev": true - }, - "object-assign": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", - "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", - "dev": true - }, - "replace-ext": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", - "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - }, - "vinyl": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", - "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", - "dev": true, - "requires": { - "clone": "^1.0.0", - "clone-stats": "^0.0.1", - "replace-ext": "0.0.1" - } - } - } - }, - "gulp-zip": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/gulp-zip/-/gulp-zip-5.1.0.tgz", - "integrity": "sha512-XZr/y91IliK/SpR74g3TkZejGkGEmK7CSDjSghT1jXshgO+dFvpLIz9w9fpuwkew6i7k4F+G24TubNgq1ISzEw==", - "dev": true, - "requires": { - "get-stream": "^5.2.0", - "plugin-error": "^1.0.1", - "through2": "^3.0.1", - "vinyl": "^2.1.0", - "yazl": "^2.5.1" - }, - "dependencies": { - "ansi-colors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", - "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", - "dev": true, - "requires": { - "ansi-wrap": "^0.1.0" - } - }, - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "plugin-error": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", - "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", - "dev": true, - "requires": { - "ansi-colors": "^1.0.1", - "arr-diff": "^4.0.0", - "arr-union": "^3.1.0", - "extend-shallow": "^3.0.2" - } - }, - "through2": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "2 || 3" - } - } - } - }, - "gulplog": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", - "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", - "dev": true, - "requires": { - "glogg": "^1.0.0" - } - }, - "handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", - "dev": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - } - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - } - } - }, - "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "has-gulplog": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", - "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", - "dev": true, - "requires": { - "sparkles": "^1.0.0" - } - }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "has-yarn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", - "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", - "dev": true - }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "hex-color-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", - "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==", - "dev": true - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", - "dev": true, - "requires": { - "parse-passwd": "^1.0.0" - } - }, - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==" - }, - "hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - } - } - }, - "hsl-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", - "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=", - "dev": true - }, - "hsla-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", - "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=", - "dev": true - }, - "html-entities": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.4.0.tgz", - "integrity": "sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==", - "dev": true - }, - "htmlhint": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/htmlhint/-/htmlhint-0.10.3.tgz", - "integrity": "sha512-LZZrDZRl1u6aYacpEl10K0wGKSQMboCNBWMgsV2eR4sxYD8jbG+FVBZqp3eo7tTwxZOdc9Cmjh3nQ4Nf4G37gQ==", - "dev": true, - "requires": { - "async": "2.6.1", - "colors": "1.3.2", - "commander": "2.17.1", - "csslint": "^1.0.5", - "glob": "7.1.3", - "jshint": "^2.9.6", - "parse-glob": "3.0.4", - "path-parse": "1.0.6", - "request": "2.88.0", - "strip-json-comments": "2.0.1", - "xml": "1.0.1" - }, - "dependencies": { - "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", - "dev": true, - "requires": { - "lodash": "^4.17.10" - } - }, - "colors": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.2.tgz", - "integrity": "sha512-rhP0JSBGYvpcNQj4s5AdShMeE5ahMop96cTeDl/v9qQQm2fYClE2QXZRi8wLzc+GmXSxdIqqbOIAhyObEXDbfQ==", - "dev": true - }, - "commander": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", - "dev": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.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" - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "dev": true, - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - } - } - } - }, - "htmlparser2": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", - "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", - "dev": true, - "optional": true, - "requires": { - "domelementtype": "1", - "domhandler": "2.3", - "domutils": "1.5", - "entities": "1.0", - "readable-stream": "1.1" - }, - "dependencies": { - "domutils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", - "dev": true, - "optional": true, - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "entities": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", - "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=", - "dev": true, - "optional": true - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true, - "optional": true - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true, - "optional": true - } - } - }, - "http-cache-semantics": { - "version": "3.8.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", - "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==" - }, - "http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", - "dev": true - }, - "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - }, - "http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dev": true, - "requires": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - } - } - }, - "http-proxy-middleware": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", - "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", - "dev": true, - "requires": { - "http-proxy": "^1.17.0", - "is-glob": "^4.0.0", - "lodash": "^4.17.11", - "micromatch": "^3.1.10" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "http2-wrapper": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", - "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", - "dev": true, - "requires": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } - }, - "humanize-ms": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", - "requires": { - "ms": "^2.0.0" - } - }, - "iconv-corefoundation": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/iconv-corefoundation/-/iconv-corefoundation-1.1.6.tgz", - "integrity": "sha512-1NBe55C75bKGZaY9UHxvXG3G0gEp0ziht7quhuFrW3SPgZDw9HI6qvYXRSV5M/Eupyu8ljuJ6Cba+ec15PZ4Xw==", - "dev": true, - "optional": true, - "requires": { - "cli-truncate": "^1.1.0" - } - }, - "iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - }, - "icss-utils": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", - "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==", - "dev": true, - "requires": { - "postcss": "^7.0.14" - } - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=" - }, - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - }, - "ignore-walk": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.4.tgz", - "integrity": "sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==", - "requires": { - "minimatch": "^3.0.4" - } - }, - "image-size": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", - "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=", - "dev": true, - "optional": true - }, - "immediate": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=" - }, - "import-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", - "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", - "dev": true, - "requires": { - "import-from": "^2.1.0" - } - }, - "import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", - "dev": true, - "requires": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - } - }, - "import-from": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", - "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", - "dev": true, - "requires": { - "resolve-from": "^3.0.0" - } - }, - "import-lazy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", - "dev": true - }, - "import-local": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", - "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", - "dev": true, - "requires": { - "pkg-dir": "^3.0.0", - "resolve-cwd": "^2.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - }, - "indexes-of": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", - "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" - }, - "inquirer": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.1.tgz", - "integrity": "sha512-088kl3DRT2dLU5riVMKKr1DlImd6X7smDhpXUCkJDCKvTEJeRiXh0G132HG9u5a+6Ylw9plFRY7RuTnwohYSpg==", - "requires": { - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.0", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.0", - "figures": "^2.0.0", - "lodash": "^4.17.10", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^6.1.0", - "string-width": "^2.1.0", - "strip-ansi": "^5.0.0", - "through": "^2.3.6" - } - }, - "internal-ip": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", - "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", - "dev": true, - "requires": { - "default-gateway": "^4.2.0", - "ipaddr.js": "^1.9.0" - } - }, - "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - } - }, - "interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" - }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } - }, - "invert-kv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==" - }, - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" - }, - "ip-regex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", - "dev": true - }, - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true - }, - "irregular-plurals": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-1.4.0.tgz", - "integrity": "sha1-LKmwM2UREYVUEvFr5dd8YqRYp2Y=", - "dev": true - }, - "is-absolute": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", - "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", - "dev": true, - "requires": { - "is-relative": "^1.0.0", - "is-windows": "^1.0.1" - } - }, - "is-absolute-url": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", - "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", - "dev": true - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "requires": { - "has-bigints": "^1.0.1" - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", - "dev": true - }, - "is-ci": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz", - "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==", - "dev": true, - "requires": { - "ci-info": "^3.1.1" - } - }, - "is-color-stop": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", - "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", - "dev": true, - "requires": { - "css-color-names": "^0.0.4", - "hex-color-regex": "^1.1.0", - "hsl-regex": "^1.0.0", - "hsla-regex": "^1.0.0", - "rgb-regex": "^1.0.1", - "rgba-regex": "^1.0.0" - } - }, - "is-core-module": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.7.0.tgz", - "integrity": "sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ==", - "requires": { - "has": "^1.0.3" - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" - } - } - }, - "is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", - "dev": true - }, - "is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" - }, - "is-finite": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", - "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-installed-globally": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", - "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", - "dev": true, - "requires": { - "global-dirs": "^3.0.0", - "is-path-inside": "^3.0.2" - }, - "dependencies": { - "is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true - } - } - }, - "is-negated-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", - "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", - "dev": true - }, - "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", - "dev": true - }, - "is-npm": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz", - "integrity": "sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==", - "dev": true - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-number-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true - }, - "is-path-cwd": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", - "dev": true - }, - "is-path-in-cwd": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", - "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", - "dev": true, - "requires": { - "is-path-inside": "^2.1.0" - } - }, - "is-path-inside": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", - "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", - "dev": true, - "requires": { - "path-is-inside": "^1.0.2" - } - }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", - "dev": true - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "requires": { - "isobject": "^3.0.1" - } - }, - "is-promise": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", - "dev": true - }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", - "dev": true - }, - "is-relative": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", - "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", - "dev": true, - "requires": { - "is-unc-path": "^1.0.0" - } - }, - "is-resolvable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", - "dev": true - }, - "is-running": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-running/-/is-running-2.1.0.tgz", - "integrity": "sha1-MKc/9cw4VOT8JUkICen1q/jeCeA=" - }, - "is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-unc-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", - "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", - "dev": true, - "requires": { - "unc-path-regex": "^0.1.2" - } - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true - }, - "is-valid-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", - "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=", - "dev": true - }, - "is-weakref": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz", - "integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.0" - } - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" - }, - "is-yarn-global": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", - "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isbinaryfile": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.8.tgz", - "integrity": "sha512-53h6XFniq77YdW+spoRrebh0mnmTxRPTlcuIArO57lmMdq4uBKFKaeTjnb92oYWrSn/LVL+LT+Hap2tFQj8V+w==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "istanbul-lib-coverage": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.2.tgz", - "integrity": "sha512-o5+eTUYzCJ11/+JhW5/FUCdfsdoYVdQ/8I/OveE2XsjehYn5DdeSnNQAbjYaO8gQ6hvGTN6GM6ddQqpTVG5j8g==", - "dev": true - }, - "istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "dev": true, - "requires": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "jake": { - "version": "10.8.2", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz", - "integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==", - "dev": true, - "requires": { - "async": "0.9.x", - "chalk": "^2.4.2", - "filelist": "^1.0.1", - "minimatch": "^3.0.4" - }, - "dependencies": { - "async": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", - "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", - "dev": true - } - } - }, - "jest-diff": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", - "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-get-type": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", - "dev": true - }, - "jest-matcher-utils": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.2.5.tgz", - "integrity": "sha512-qNR/kh6bz0Dyv3m68Ck2g1fLW5KlSOUNcFQh87VXHZwWc/gY6XwnKofx76Qytz3x5LDWT09/2+yXndTkaG4aWg==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^27.2.5", - "jest-get-type": "^27.0.6", - "pretty-format": "^27.2.5" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jest-message-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", - "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.5.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "graceful-fs": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", - "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "jest-regex-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", - "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", - "dev": true - }, - "jest-worker": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.1.0.tgz", - "integrity": "sha512-ZHhHtlxOWSxCoNOKHGbiLzXnl42ga9CxDr27H36Qn+15pQZd3R/F24jrmjDelw9j/iHUIWMWs08/u2QN50HHOg==", - "dev": true, - "requires": { - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - }, - "dependencies": { - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "jpeg-js": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.3.tgz", - "integrity": "sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q==", - "dev": true - }, - "jquery": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz", - "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==" - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "jshint": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.13.1.tgz", - "integrity": "sha512-vymzfR3OysF5P774x6zYv0bD4EpH6NWRxpq54wO9mA9RuY49yb1teKSICkLx2Ryx+mfzlVVNNbTBtsRtg78t7g==", - "dev": true, - "optional": true, - "requires": { - "cli": "~1.0.0", - "console-browserify": "1.1.x", - "exit": "0.1.x", - "htmlparser2": "3.8.x", - "lodash": "~4.17.21", - "minimatch": "~3.0.2", - "shelljs": "0.3.x", - "strip-json-comments": "1.0.x" - }, - "dependencies": { - "console-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", - "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", - "dev": true, - "optional": true, - "requires": { - "date-now": "^0.1.4" - } - }, - "shelljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz", - "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=", - "dev": true, - "optional": true - }, - "strip-json-comments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", - "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=", - "dev": true, - "optional": true - } - } - }, - "json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", - "dev": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json3": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz", - "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==", - "dev": true - }, - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=" - }, - "jsonschema": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.1.1.tgz", - "integrity": "sha1-PO3o4+QR03eHLu+8n98mODy8Ptk=" - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jszip": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.7.1.tgz", - "integrity": "sha512-ghL0tz1XG9ZEmRMcEN2vt7xabrDdqHHeykgARpmZ0BiIctWxM47Vt63ZO2dnp4QYt/xJVLLy5Zv1l/xRdh2byg==", - "requires": { - "lie": "~3.3.0", - "pako": "~1.0.2", - "readable-stream": "~2.3.6", - "set-immediate-shim": "~1.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - } - } - }, - "junk": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz", - "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==", - "dev": true - }, - "just-debounce": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.1.0.tgz", - "integrity": "sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ==", - "dev": true - }, - "karma-source-map-support": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz", - "integrity": "sha512-RsBECncGO17KAoJCYXjv+ckIz+Ii9NCi+9enk+rq6XC81ezYkb4/RHE6CTXdA7IOJqoF3wcaLfVG0CPmE5ca6A==", - "dev": true, - "requires": { - "source-map-support": "^0.5.5" - } - }, - "keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", - "dev": true, - "requires": { - "json-buffer": "3.0.0" - } - }, - "killable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", - "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==", - "dev": true - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" - }, - "klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", - "requires": { - "graceful-fs": "^4.1.9" - } - }, - "last-run": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz", - "integrity": "sha1-RblpQsF7HHnHchmCWbqUO+v4yls=", - "dev": true, - "requires": { - "default-resolution": "^2.0.0", - "es6-weak-map": "^2.0.1" - } - }, - "latest-version": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", - "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", - "dev": true, - "requires": { - "package-json": "^6.3.0" - } - }, - "lazy-val": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz", - "integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==", - "dev": true - }, - "lazystream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", - "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - } - } - }, - "lcid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", - "requires": { - "invert-kv": "^2.0.0" - } - }, - "lead": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", - "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=", - "dev": true, - "requires": { - "flush-write-stream": "^1.0.2" - } - }, - "less": { - "version": "3.11.3", - "resolved": "https://registry.npmjs.org/less/-/less-3.11.3.tgz", - "integrity": "sha512-VkZiTDdtNEzXA3LgjQiC3D7/ejleBPFVvq+aRI9mIj+Zhmif5TvFPM244bT4rzkvOCvJ9q4zAztok1M7Nygagw==", - "dev": true, - "requires": { - "clone": "^2.1.2", - "errno": "^0.1.1", - "graceful-fs": "^4.1.2", - "image-size": "~0.5.0", - "make-dir": "^2.1.0", - "mime": "^1.4.1", - "promise": "^7.1.1", - "request": "^2.83.0", - "source-map": "~0.6.0", - "tslib": "^1.10.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true - } - } - }, - "less-loader": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-5.0.0.tgz", - "integrity": "sha512-bquCU89mO/yWLaUq0Clk7qCsKhsF/TZpJUzETRvJa9KSVEL9SO3ovCvdEHISBhrC81OwC8QSVX7E0bzElZj9cg==", - "dev": true, - "requires": { - "clone": "^2.1.1", - "loader-utils": "^1.1.0", - "pify": "^4.0.1" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - } - } - }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true - }, - "levenary": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.1.tgz", - "integrity": "sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ==", - "dev": true, - "requires": { - "leven": "^3.1.0" - } - }, - "license-webpack-plugin": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-2.1.4.tgz", - "integrity": "sha512-1Xq72fmPbTg5KofXs+yI5L4QqPFjQ6mZxoeI6D7gfiEDOtaEIk6PGrdLaej90bpDqKNHNxlQ/MW4tMAL6xMPJQ==", - "dev": true, - "requires": { - "@types/webpack-sources": "^0.1.5", - "webpack-sources": "^1.2.0" - } - }, - "lie": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", - "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", - "requires": { - "immediate": "~3.0.5" - } - }, - "liftoff": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", - "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==", - "dev": true, - "requires": { - "extend": "^3.0.0", - "findup-sync": "^3.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" - } - }, - "lighthouse-logger": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.3.0.tgz", - "integrity": "sha512-BbqAKApLb9ywUli+0a+PcV04SyJ/N1q/8qgCNe6U97KbPCS1BTksEuHFLYdvc8DltuhfxIUBqDZsC0bBGtl3lA==", - "dev": true, - "requires": { - "debug": "^2.6.9", - "marky": "^1.2.2" - } - }, - "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", - "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "lodash._basecopy": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", - "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", - "dev": true - }, - "lodash._basetostring": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz", - "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=", - "dev": true - }, - "lodash._basevalues": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", - "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=", - "dev": true - }, - "lodash._getnative": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", - "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", - "dev": true - }, - "lodash._isiterateecall": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", - "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", - "dev": true - }, - "lodash._reescape": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", - "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=", - "dev": true - }, - "lodash._reevaluate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", - "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=", - "dev": true - }, - "lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", - "dev": true - }, - "lodash._root": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", - "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=", - "dev": true - }, - "lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true - }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=" - }, - "lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", - "dev": true - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.escape": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", - "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", - "dev": true, - "requires": { - "lodash._root": "^3.0.0" - } - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", - "dev": true - }, - "lodash.isarguments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", - "dev": true - }, - "lodash.isarray": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", - "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", - "dev": true - }, - "lodash.isobject": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-3.0.2.tgz", - "integrity": "sha1-PI+41bW/S/kK4G4U8qUwpO2TXh0=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.keys": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", - "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", - "dev": true, - "requires": { - "lodash._getnative": "^3.0.0", - "lodash.isarguments": "^3.0.0", - "lodash.isarray": "^3.0.0" - } - }, - "lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", - "dev": true - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "lodash.restparam": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", - "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=", - "dev": true - }, - "lodash.template": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", - "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", - "dev": true, - "requires": { - "lodash._basecopy": "^3.0.0", - "lodash._basetostring": "^3.0.0", - "lodash._basevalues": "^3.0.0", - "lodash._isiterateecall": "^3.0.0", - "lodash._reinterpolate": "^3.0.0", - "lodash.escape": "^3.0.0", - "lodash.keys": "^3.0.0", - "lodash.restparam": "^3.0.0", - "lodash.templatesettings": "^3.0.0" - } - }, - "lodash.templatesettings": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz", - "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", - "dev": true, - "requires": { - "lodash._reinterpolate": "^3.0.0", - "lodash.escape": "^3.0.0" - } - }, - "lodash.union": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", - "dev": true - }, - "lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", - "dev": true - }, - "lodash.zip": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz", - "integrity": "sha1-7GZi5IlkCO1KtsVCo5kLcswIACA=", - "dev": true - }, - "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2" - } - }, - "loglevel": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.1.tgz", - "integrity": "sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw==", - "dev": true - }, - "loglevel-plugin-prefix": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/loglevel-plugin-prefix/-/loglevel-plugin-prefix-0.8.4.tgz", - "integrity": "sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g==", - "dev": true - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "loud-rejection": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", - "dev": true, - "requires": { - "currently-unhandled": "^0.4.1", - "signal-exit": "^3.0.0" - } - }, - "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "dev": true - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "requires": { - "yallist": "^3.0.2" - } - }, - "lru-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", - "integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=", - "dev": true, - "requires": { - "es5-ext": "~0.10.2" - } - }, - "magic-string": { - "version": "0.25.7", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", - "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", - "requires": { - "sourcemap-codec": "^1.4.4" - } - }, - "main-bower-files": { - "version": "2.13.3", - "resolved": "https://registry.npmjs.org/main-bower-files/-/main-bower-files-2.13.3.tgz", - "integrity": "sha512-Wfs4DJZJIifrvYx5F/JZ/GkCkpH6gx9pZ6Ep7Gb9mRqJ4mBzmEHG5j6bmLVjzYruB/ddAQgXfybAWk7qM5MV7A==", - "dev": true, - "requires": { - "chalk": "^1.0.0", - "extend": "^2.0.1", - "globby": "^2.0.0", - "multimatch": "^2.0.0", - "path-exists": "^1.0.0", - "strip-json-comments": "^1.0.2", - "vinyl-fs": "^3.0.3" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "extend": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-2.0.2.tgz", - "integrity": "sha512-AgFD4VU+lVLP6vjnlNfF7OeInLTyeyckCNPEsuxz1vi786UuK/nk6ynPuhn/h+Ju9++TQyr5EpLRI14fc1QtTQ==", - "dev": true - }, - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "globby": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-2.1.0.tgz", - "integrity": "sha1-npGSvNM/Srak+JTl5+qLcTITxII=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "async": "^1.2.1", - "glob": "^5.0.3", - "object-assign": "^3.0.0" - } - }, - "object-assign": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", - "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", - "dev": true - }, - "path-exists": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-1.0.0.tgz", - "integrity": "sha1-1aiZjrce83p0w06w2eum6HjuoIE=", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", - "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=", - "dev": true - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "make-error-cause": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/make-error-cause/-/make-error-cause-1.2.2.tgz", - "integrity": "sha1-3wOI/NCzeBbf8KX7gQiTl3fcvJ0=", - "dev": true, - "requires": { - "make-error": "^1.2.0" - } - }, - "make-fetch-happen": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-4.0.2.tgz", - "integrity": "sha512-YMJrAjHSb/BordlsDEcVcPyTbiJKkzqMf48N8dAJZT9Zjctrkb6Yg4TY9Sq2AwSIQJFn5qBBKVTYt3vP5FMIHA==", - "requires": { - "agentkeepalive": "^3.4.1", - "cacache": "^11.3.3", - "http-cache-semantics": "^3.8.1", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "node-fetch-npm": "^2.0.2", - "promise-retry": "^1.1.1", - "socks-proxy-agent": "^4.0.0", - "ssri": "^6.0.0" - } - }, - "make-iterator": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", - "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", - "dev": true, - "requires": { - "kind-of": "^6.0.2" - } - }, - "mamacro": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/mamacro/-/mamacro-0.0.3.tgz", - "integrity": "sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA==", - "dev": true - }, - "map-age-cleaner": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", - "requires": { - "p-defer": "^1.0.0" - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" - }, - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true - }, - "map-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz", - "integrity": "sha1-ih8HiW2CsQkmvTdEokIACfiJdKg=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "requires": { - "object-visit": "^1.0.0" - } - }, - "marky": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/marky/-/marky-1.2.2.tgz", - "integrity": "sha512-k1dB2HNeaNyORco8ulVEhctyEGkKHb2YWAhDsxeFlW2nROIirsctBYzKwwS3Vza+sKTS1zO4Z+n9/+9WbGLIxQ==", - "dev": true - }, - "matchdep": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", - "integrity": "sha1-xvNINKDY28OzfCfui7yyfHd1WC4=", - "dev": true, - "requires": { - "findup-sync": "^2.0.0", - "micromatch": "^3.0.4", - "resolve": "^1.4.0", - "stack-trace": "0.0.10" - }, - "dependencies": { - "findup-sync": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", - "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", - "dev": true, - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^3.1.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - } - }, - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "matcher": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", - "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", - "dev": true, - "optional": true, - "requires": { - "escape-string-regexp": "^4.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "optional": true - } - } - }, - "md5-promised": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/md5-promised/-/md5-promised-1.0.1.tgz", - "integrity": "sha1-Lj4NxXzuZUIVTULrCp7fka2Ala8=", - "requires": { - "q": "^1.4.1" - } - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "mdn-data": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", - "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", - "dev": true - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "dev": true - }, - "mem": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", - "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", - "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^2.0.0", - "p-is-promise": "^2.0.0" - }, - "dependencies": { - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" - } - } - }, - "memoizee": { - "version": "0.4.15", - "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", - "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", - "dev": true, - "requires": { - "d": "^1.0.1", - "es5-ext": "^0.10.53", - "es6-weak-map": "^2.0.3", - "event-emitter": "^0.3.5", - "is-promise": "^2.2.2", - "lru-queue": "^0.1.0", - "next-tick": "^1.1.0", - "timers-ext": "^0.1.7" - }, - "dependencies": { - "next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", - "dev": true - } - } - }, - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - } - } - }, - "meow": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", - "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - } - } - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", - "dev": true - }, - "merge-source-map": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", - "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", - "dev": true, - "requires": { - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "merge-stream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", - "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", - "dev": true, - "requires": { - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - } - } - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true - }, - "mime-db": { - "version": "1.50.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", - "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==" - }, - "mime-types": { - "version": "2.1.33", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", - "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", - "requires": { - "mime-db": "1.50.0" - } - }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" - }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true - }, - "mini-css-extract-plugin": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz", - "integrity": "sha512-lp3GeY7ygcgAmVIcRPBVhIkf8Us7FZjA+ILpal44qLdSu11wmjKQ3d9k15lfD7pO4esu9eUIAW7qiYIBppv40A==", - "dev": true, - "requires": { - "loader-utils": "^1.1.0", - "normalize-url": "1.9.1", - "schema-utils": "^1.0.0", - "webpack-sources": "^1.1.0" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "normalize-url": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", - "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", - "dev": true, - "requires": { - "object-assign": "^4.0.1", - "prepend-http": "^1.0.0", - "query-string": "^4.1.0", - "sort-keys": "^1.0.0" - } - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - } - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, - "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minipass-collect": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", - "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - }, - "dependencies": { - "minipass": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.5.tgz", - "integrity": "sha512-+8NzxD82XQoNKNrl1d/FSi+X8wAEWR+sbYAfIvub4Nz0d22plFG72CEVVaufV8PNf4qSslFTD8VMOxNVhHCjTw==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - }, - "dependencies": { - "minipass": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.5.tgz", - "integrity": "sha512-+8NzxD82XQoNKNrl1d/FSi+X8wAEWR+sbYAfIvub4Nz0d22plFG72CEVVaufV8PNf4qSslFTD8VMOxNVhHCjTw==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "minipass-pipeline": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - }, - "dependencies": { - "minipass": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.5.tgz", - "integrity": "sha512-+8NzxD82XQoNKNrl1d/FSi+X8wAEWR+sbYAfIvub4Nz0d22plFG72CEVVaufV8PNf4qSslFTD8VMOxNVhHCjTw==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "requires": { - "minipass": "^2.9.0" - } - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" - }, - "mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true - }, - "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" - }, - "dependencies": { - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", - "dev": true, - "requires": { - "anymatch": "~3.1.1", - "braces": "~3.0.2", - "fsevents": "~2.1.1", - "glob-parent": "~5.1.0", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", - "dev": true, - "requires": { - "picomatch": "^2.0.4" - } - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - } - } - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - }, - "dependencies": { - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } - } - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "multicast-dns": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", - "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", - "dev": true, - "requires": { - "dns-packet": "^1.3.1", - "thunky": "^1.0.2" - } - }, - "multicast-dns-service-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", - "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", - "dev": true - }, - "multimatch": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", - "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", - "dev": true, - "requires": { - "array-differ": "^1.0.0", - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "minimatch": "^3.0.0" - }, - "dependencies": { - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - } - } - }, - "multipipe": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", - "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", - "dev": true, - "requires": { - "duplexer2": "0.0.2" - } - }, - "mute-stdout": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz", - "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==", - "dev": true - }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" - }, - "nan": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - } - }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", - "dev": true - }, - "neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "node-fetch": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz", - "integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==", - "dev": true, - "requires": { - "whatwg-url": "^5.0.0" - } - }, - "node-fetch-npm": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/node-fetch-npm/-/node-fetch-npm-2.0.4.tgz", - "integrity": "sha512-iOuIQDWDyjhv9qSDrj9aq/klt6F9z1p2otB3AV7v3zBDcL/x+OfGsvGQZZCcMZbUf4Ujw1xGNQkjvGnVT22cKg==", - "requires": { - "encoding": "^0.1.11", - "json-parse-better-errors": "^1.0.0", - "safe-buffer": "^5.1.1" - } - }, - "node-forge": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", - "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", - "dev": true - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - } - } - }, - "node-releases": { - "version": "1.1.77", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.77.tgz", - "integrity": "sha512-rB1DUFUNAN4Gn9keO2K1efO35IDK7yKHCdCaIMvFO7yUYmmZYeDjnGKle26G4rwj+LKRQpjyUUvMkPglwGCYNQ==", - "dev": true - }, - "node-sha1": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/node-sha1/-/node-sha1-1.0.1.tgz", - "integrity": "sha1-Mu2EfYUTFXuW3sa3noxHvK63jhw=" - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "requires": { - "remove-trailing-separator": "^1.0.1" - } - }, - "normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", - "dev": true - }, - "normalize-url": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", - "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==", - "dev": true - }, - "now-and-later": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", - "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", - "dev": true, - "requires": { - "once": "^1.3.2" - } - }, - "npm-bundled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz", - "integrity": "sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==", - "requires": { - "npm-normalize-package-bin": "^1.0.1" - } - }, - "npm-conf": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz", - "integrity": "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==", - "dev": true, - "optional": true, - "requires": { - "config-chain": "^1.1.11", - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true, - "optional": true - } - } - }, - "npm-normalize-package-bin": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", - "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==" - }, - "npm-package-arg": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.0.tgz", - "integrity": "sha512-zYbhP2k9DbJhA0Z3HKUePUgdB1x7MfIfKssC+WLPFMKTBZKpZh5m13PgexJjCq6KW7j17r0jHWcCpxEqnnncSA==", - "requires": { - "hosted-git-info": "^2.6.0", - "osenv": "^0.1.5", - "semver": "^5.5.0", - "validate-npm-package-name": "^3.0.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "npm-packlist": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", - "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1", - "npm-normalize-package-bin": "^1.0.1" - } - }, - "npm-pick-manifest": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-2.2.3.tgz", - "integrity": "sha512-+IluBC5K201+gRU85vFlUwX3PFShZAbAgDNp2ewJdWMVSppdo/Zih0ul2Ecky/X7b51J7LrrUAP+XOmOCvYZqA==", - "requires": { - "figgy-pudding": "^3.5.1", - "npm-package-arg": "^6.0.0", - "semver": "^5.4.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "npm-registry-fetch": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-3.9.1.tgz", - "integrity": "sha512-VQCEZlydXw4AwLROAXWUR7QDfe2Y8Id/vpAgp6TI1/H78a4SiQ1kQrKZALm5/zxM5n4HIi+aYb+idUAV/RuY0Q==", - "requires": { - "JSONStream": "^1.3.4", - "bluebird": "^3.5.1", - "figgy-pudding": "^3.4.1", - "lru-cache": "^5.1.1", - "make-fetch-happen": "^4.0.2", - "npm-package-arg": "^6.1.0" - }, - "dependencies": { - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - } - } - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "nth-check": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", - "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", - "dev": true, - "requires": { - "boolbase": "~1.0.0" - } - }, - "num2fraction": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", - "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", - "dev": true - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "object-inspect": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", - "dev": true - }, - "object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "requires": { - "isobject": "^3.0.0" - } - }, - "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - } - }, - "object.defaults": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", - "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", - "dev": true, - "requires": { - "array-each": "^1.0.1", - "array-slice": "^1.0.0", - "for-own": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz", - "integrity": "sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - } - }, - "object.map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", - "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", - "dev": true, - "requires": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "requires": { - "isobject": "^3.0.1" - } - }, - "object.reduce": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz", - "integrity": "sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60=", - "dev": true, - "requires": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, - "object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" - } - }, - "obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "dev": true - }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "open": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/open/-/open-6.0.0.tgz", - "integrity": "sha512-/yb5mVZBz7mHLySMiSj2DcLtMBbFPJk5JBKEkHVZFxZAPzeg3L026O0T+lbdz1B2nyDnkClRSwRQJdeVUIF7zw==", - "requires": { - "is-wsl": "^1.1.0" - } - }, - "opn": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", - "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", - "dev": true, - "requires": { - "is-wsl": "^1.1.0" - } - }, - "ordered-read-streams": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", - "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=", - "dev": true, - "requires": { - "readable-stream": "^2.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - } - } - }, - "original": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", - "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", - "dev": true, - "requires": { - "url-parse": "^1.4.3" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" - }, - "os-locale": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", - "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", - "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" - }, - "osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", - "dev": true - }, - "p-defer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=" - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "p-is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", - "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==" - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "p-retry": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", - "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", - "dev": true, - "requires": { - "retry": "^0.12.0" - }, - "dependencies": { - "retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", - "dev": true - } - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "package-json": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", - "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", - "dev": true, - "requires": { - "got": "^9.6.0", - "registry-auth-token": "^4.0.0", - "registry-url": "^5.0.0", - "semver": "^6.2.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "pacote": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-9.4.0.tgz", - "integrity": "sha512-WQ1KL/phGMkedYEQx9ODsjj7xvwLSpdFJJdEXrLyw5SILMxcTNt5DTxT2Z93fXuLFYJBlZJdnwdalrQdB/rX5w==", - "requires": { - "bluebird": "^3.5.3", - "cacache": "^11.3.2", - "figgy-pudding": "^3.5.1", - "get-stream": "^4.1.0", - "glob": "^7.1.3", - "lru-cache": "^5.1.1", - "make-fetch-happen": "^4.0.1", - "minimatch": "^3.0.4", - "minipass": "^2.3.5", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "normalize-package-data": "^2.4.0", - "npm-package-arg": "^6.1.0", - "npm-packlist": "^1.1.12", - "npm-pick-manifest": "^2.2.3", - "npm-registry-fetch": "^3.8.0", - "osenv": "^0.1.5", - "promise-inflight": "^1.0.1", - "promise-retry": "^1.1.1", - "protoduck": "^5.0.1", - "rimraf": "^2.6.2", - "safe-buffer": "^5.1.2", - "semver": "^5.6.0", - "ssri": "^6.0.1", - "tar": "^4.4.8", - "unique-filename": "^1.1.1", - "which": "^1.3.1" - }, - "dependencies": { - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "requires": { - "glob": "^7.1.3" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" - }, - "parallel-transform": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", - "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", - "requires": { - "cyclist": "^1.0.1", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - } - } - }, - "parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "dev": true, - "requires": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "parse-author": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parse-author/-/parse-author-2.0.0.tgz", - "integrity": "sha1-00YL8d3Q367tQtp1QkLmX7aEqB8=", - "dev": true, - "requires": { - "author-regex": "^1.0.0" - } - }, - "parse-filepath": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", - "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", - "dev": true, - "requires": { - "is-absolute": "^1.0.0", - "map-cache": "^0.2.0", - "path-root": "^0.1.1" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" - }, - "dependencies": { - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - } - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "parse-node-version": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", - "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", - "dev": true - }, - "parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", - "dev": true - }, - "parse5": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", - "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", - "dev": true - }, - "parserlib": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/parserlib/-/parserlib-1.1.1.tgz", - "integrity": "sha1-pkz6ckBiQ0/fw1HJpOwtkrlMBvQ=", - "dev": true, - "optional": true - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "path-root": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", - "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", - "dev": true, - "requires": { - "path-root-regex": "^0.1.0" - } - }, - "path-root-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", - "dev": true - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", - "dev": true - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true - }, - "pause-stream": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", - "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", - "dev": true, - "requires": { - "through": "~2.3" - } - }, - "pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", - "dev": true - }, - "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, - "pirates": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.4.tgz", - "integrity": "sha512-ZIrVPH+A52Dw84R0L3/VS9Op04PuQ2SEoJL6bkshmiTic/HldyW9Tf7oH5mhJZBK7NmDx27vSMrYEXPXclpDKw==", - "dev": true - }, - "pixelmatch": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-5.2.1.tgz", - "integrity": "sha512-WjcAdYSnKrrdDdqTcVEY7aB7UhhwjYQKYhHiBXdJef0MOaQeYpUdQ+iVyBLa5YBKS8MPVPPMX7rpOByISLpeEQ==", - "dev": true, - "requires": { - "pngjs": "^4.0.1" - }, - "dependencies": { - "pngjs": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-4.0.1.tgz", - "integrity": "sha512-rf5+2/ioHeQxR6IxuYNYGFytUyG3lma/WW1nsmjeHlWwtb2aByla6dkVc8pmJ9nplzkTA0q2xx7mMWrOTqT4Gg==", - "dev": true - } - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "pkg-up": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "playwright": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.19.2.tgz", - "integrity": "sha512-2JmGWr/Iw/Uu27bZULeHgjn8doNrRVxIYdhspMuMlfKNpzwAe/sfm7wH8uey6jiZxnPL4bC5V4ACQcF4dAGWnw==", - "dev": true, - "requires": { - "playwright-core": "1.19.2" - }, - "dependencies": { - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "requires": { - "debug": "4" - } - }, - "commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "dev": true - }, - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dev": true, - "requires": { - "@types/yauzl": "^2.9.1", - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - } - }, - "fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", - "dev": true, - "requires": { - "pend": "~1.2.0" - } - }, - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "mime": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", - "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "playwright-core": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.19.2.tgz", - "integrity": "sha512-OsL3sJZIo1UxKNWSP7zW7sk3FyUGG06YRHxHeBw51eIOxTCQRx5t+hXd0cvXashN2CHnd3hIZTs2aKa/im4hZQ==", - "dev": true, - "requires": { - "commander": "8.3.0", - "debug": "4.3.3", - "extract-zip": "2.0.1", - "https-proxy-agent": "5.0.0", - "jpeg-js": "0.4.3", - "mime": "3.0.0", - "pngjs": "6.0.0", - "progress": "2.0.3", - "proper-lockfile": "4.1.2", - "proxy-from-env": "1.1.0", - "rimraf": "3.0.2", - "socks-proxy-agent": "6.1.1", - "stack-utils": "2.0.5", - "ws": "8.4.2", - "yauzl": "2.10.0", - "yazl": "2.5.1" - } - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "socks": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz", - "integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==", - "dev": true, - "requires": { - "ip": "^1.1.5", - "smart-buffer": "^4.2.0" - } - }, - "socks-proxy-agent": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.1.1.tgz", - "integrity": "sha512-t8J0kG3csjA4g6FTbsMOWws+7R7vuRC8aQ/wy3/1OWmsgwA68zs/+cExQ0koSitUDXqhufF/YJr9wtNMZHw5Ew==", - "dev": true, - "requires": { - "agent-base": "^6.0.2", - "debug": "^4.3.1", - "socks": "^2.6.1" - } - }, - "ws": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.4.2.tgz", - "integrity": "sha512-Kbk4Nxyq7/ZWqr/tarI9yIt/+iNNFOjBXEWgTb4ydaNHBNGgvf2QHbS9fdfsndfjFlFwEd4Al+mw83YkaD10ZA==", - "dev": true - }, - "yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", - "dev": true, - "requires": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - } - } - }, - "plist": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.4.tgz", - "integrity": "sha512-ksrr8y9+nXOxQB2osVNqrgvX/XQPOXaU4BQMKjYq8PvaY1U18mo+fKgBSwzK+luSyinOuPae956lSVcBwxlAMg==", - "dev": true, - "requires": { - "base64-js": "^1.5.1", - "xmlbuilder": "^9.0.7" - }, - "dependencies": { - "xmlbuilder": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", - "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", - "dev": true - } - } - }, - "plotly.js-dist": { - "version": "1.58.5", - "resolved": "https://registry.npmjs.org/plotly.js-dist/-/plotly.js-dist-1.58.5.tgz", - "integrity": "sha512-gy4cm5gYeem1eoXeryrSfftDm/CacQUE+W6xPRGiC5PnB/WHDPaex+HVeAGdKEek57ok1j2IkDw3lnXoB0Bfiw==" - }, - "plugin-error": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz", - "integrity": "sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=", - "dev": true, - "requires": { - "ansi-cyan": "^0.1.1", - "ansi-red": "^0.1.1", - "arr-diff": "^1.0.1", - "arr-union": "^2.0.1", - "extend-shallow": "^1.1.2" - }, - "dependencies": { - "arr-diff": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz", - "integrity": "sha1-aHwydYFjWI/vfeezb6vklesaOZo=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1", - "array-slice": "^0.2.3" - } - }, - "arr-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz", - "integrity": "sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0=", - "dev": true - }, - "array-slice": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", - "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", - "dev": true - }, - "extend-shallow": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz", - "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=", - "dev": true, - "requires": { - "kind-of": "^1.1.0" - } - }, - "kind-of": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz", - "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=", - "dev": true - } - } - }, - "plugin-log": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/plugin-log/-/plugin-log-0.1.0.tgz", - "integrity": "sha1-hgSc9qsQgzOYqTHzaJy67nteEzM=", - "dev": true, - "requires": { - "chalk": "^1.1.1", - "dateformat": "^1.0.11" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "plur": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/plur/-/plur-2.1.2.tgz", - "integrity": "sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo=", - "dev": true, - "requires": { - "irregular-plurals": "^1.0.0" - } - }, - "pngjs": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-6.0.0.tgz", - "integrity": "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==", - "dev": true - }, - "portfinder": { - "version": "1.0.28", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", - "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", - "dev": true, - "requires": { - "async": "^2.6.2", - "debug": "^3.1.1", - "mkdirp": "^0.5.5" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - } - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" - }, - "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", - "dev": true, - "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "postcss-calc": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.5.tgz", - "integrity": "sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg==", - "dev": true, - "requires": { - "postcss": "^7.0.27", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.0.2" - } - }, - "postcss-colormin": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz", - "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==", - "dev": true, - "requires": { - "browserslist": "^4.0.0", - "color": "^3.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-convert-values": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz", - "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", - "dev": true, - "requires": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-discard-comments": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz", - "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==", - "dev": true, - "requires": { - "postcss": "^7.0.0" - } - }, - "postcss-discard-duplicates": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz", - "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", - "dev": true, - "requires": { - "postcss": "^7.0.0" - } - }, - "postcss-discard-empty": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz", - "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", - "dev": true, - "requires": { - "postcss": "^7.0.0" - } - }, - "postcss-discard-overridden": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz", - "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", - "dev": true, - "requires": { - "postcss": "^7.0.0" - } - }, - "postcss-import": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-12.0.1.tgz", - "integrity": "sha512-3Gti33dmCjyKBgimqGxL3vcV8w9+bsHwO5UrBawp796+jdardbcFl4RP5w/76BwNL7aGzpKstIfF9I+kdE8pTw==", - "dev": true, - "requires": { - "postcss": "^7.0.1", - "postcss-value-parser": "^3.2.3", - "read-cache": "^1.0.0", - "resolve": "^1.1.7" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-load-config": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.2.tgz", - "integrity": "sha512-/rDeGV6vMUo3mwJZmeHfEDvwnTKKqQ0S7OHUi/kJvvtx3aWtyWG2/0ZWnzCt2keEclwN6Tf0DST2v9kITdOKYw==", - "dev": true, - "requires": { - "cosmiconfig": "^5.0.0", - "import-cwd": "^2.0.0" - } - }, - "postcss-loader": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz", - "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==", - "dev": true, - "requires": { - "loader-utils": "^1.1.0", - "postcss": "^7.0.0", - "postcss-load-config": "^2.0.0", - "schema-utils": "^1.0.0" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - } - } - }, - "postcss-merge-longhand": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz", - "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==", - "dev": true, - "requires": { - "css-color-names": "0.0.4", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "stylehacks": "^4.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-merge-rules": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz", - "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==", - "dev": true, - "requires": { - "browserslist": "^4.0.0", - "caniuse-api": "^3.0.0", - "cssnano-util-same-parent": "^4.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0", - "vendors": "^1.0.0" - }, - "dependencies": { - "postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "dev": true, - "requires": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } - } - }, - "postcss-minify-font-values": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz", - "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", - "dev": true, - "requires": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-minify-gradients": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz", - "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==", - "dev": true, - "requires": { - "cssnano-util-get-arguments": "^4.0.0", - "is-color-stop": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-minify-params": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz", - "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==", - "dev": true, - "requires": { - "alphanum-sort": "^1.0.0", - "browserslist": "^4.0.0", - "cssnano-util-get-arguments": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "uniqs": "^2.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-minify-selectors": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz", - "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==", - "dev": true, - "requires": { - "alphanum-sort": "^1.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0" - }, - "dependencies": { - "postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "dev": true, - "requires": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } - } - }, - "postcss-modules-extract-imports": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", - "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", - "dev": true, - "requires": { - "postcss": "^7.0.5" - } - }, - "postcss-modules-local-by-default": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz", - "integrity": "sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw==", - "dev": true, - "requires": { - "icss-utils": "^4.1.1", - "postcss": "^7.0.32", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.1.0" - }, - "dependencies": { - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dev": true, - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "postcss-modules-scope": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", - "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", - "dev": true, - "requires": { - "postcss": "^7.0.6", - "postcss-selector-parser": "^6.0.0" - } - }, - "postcss-modules-values": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz", - "integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==", - "dev": true, - "requires": { - "icss-utils": "^4.0.0", - "postcss": "^7.0.6" - } - }, - "postcss-normalize-charset": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", - "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", - "dev": true, - "requires": { - "postcss": "^7.0.0" - } - }, - "postcss-normalize-display-values": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz", - "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==", - "dev": true, - "requires": { - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-normalize-positions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz", - "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==", - "dev": true, - "requires": { - "cssnano-util-get-arguments": "^4.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-normalize-repeat-style": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz", - "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==", - "dev": true, - "requires": { - "cssnano-util-get-arguments": "^4.0.0", - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-normalize-string": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz", - "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==", - "dev": true, - "requires": { - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-normalize-timing-functions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz", - "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==", - "dev": true, - "requires": { - "cssnano-util-get-match": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-normalize-unicode": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz", - "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", - "dev": true, - "requires": { - "browserslist": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-normalize-url": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz", - "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", - "dev": true, - "requires": { - "is-absolute-url": "^2.0.0", - "normalize-url": "^3.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-normalize-whitespace": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz", - "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==", - "dev": true, - "requires": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-ordered-values": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz", - "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==", - "dev": true, - "requires": { - "cssnano-util-get-arguments": "^4.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-reduce-initial": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz", - "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==", - "dev": true, - "requires": { - "browserslist": "^4.0.0", - "caniuse-api": "^3.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0" - } - }, - "postcss-reduce-transforms": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz", - "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==", - "dev": true, - "requires": { - "cssnano-util-get-match": "^4.0.0", - "has": "^1.0.0", - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-selector-parser": { - "version": "6.0.6", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", - "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==", - "dev": true, - "requires": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - } - }, - "postcss-svgo": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.3.tgz", - "integrity": "sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw==", - "dev": true, - "requires": { - "postcss": "^7.0.0", - "postcss-value-parser": "^3.0.0", - "svgo": "^1.0.0" - }, - "dependencies": { - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - } - } - }, - "postcss-unique-selectors": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz", - "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", - "dev": true, - "requires": { - "alphanum-sort": "^1.0.0", - "postcss": "^7.0.0", - "uniqs": "^2.0.0" - } - }, - "postcss-value-parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", - "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", - "dev": true - }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", - "dev": true - }, - "pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - } - } - }, - "pretty-hrtime": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", - "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", - "dev": true - }, - "printj": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz", - "integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==", - "dev": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "progress-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/progress-stream/-/progress-stream-2.0.0.tgz", - "integrity": "sha1-+sY6Cz0R3qy7CWmrzJOyFLzhntU=", - "requires": { - "speedometer": "~1.0.0", - "through2": "~2.0.3" - } - }, - "promise": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", - "dev": true, - "optional": true, - "requires": { - "asap": "~2.0.3" - } - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=" - }, - "promise-retry": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-1.1.1.tgz", - "integrity": "sha1-ZznpaOMFHaIM5kl/srUPaRHfPW0=", - "requires": { - "err-code": "^1.0.0", - "retry": "^0.10.0" - } - }, - "proper-lockfile": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", - "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.4", - "retry": "^0.12.0", - "signal-exit": "^3.0.2" - }, - "dependencies": { - "retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", - "dev": true - } - } - }, - "proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", - "dev": true, - "optional": true - }, - "protoduck": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/protoduck/-/protoduck-5.0.1.tgz", - "integrity": "sha512-WxoCeDCoCBY55BMvj4cAEjdVUFGRWed9ZxPlqTKYyw1nDDTQ4pqmnIMAGfJlg7Dx35uB/M+PHJPTmGOvaCaPTg==", - "requires": { - "genfun": "^5.0.0" - } - }, - "proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dev": true, - "requires": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - } - }, - "proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "pupa": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz", - "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==", - "dev": true, - "requires": { - "escape-goat": "^2.0.0" - } - }, - "puppeteer-core": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-5.5.0.tgz", - "integrity": "sha512-tlA+1n+ziW/Db03hVV+bAecDKse8ihFRXYiEypBe9IlLRvOCzYFG6qrCMBYK34HO/Q/Ecjc+tvkHRAfLVH+NgQ==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "devtools-protocol": "0.0.818844", - "extract-zip": "^2.0.0", - "https-proxy-agent": "^4.0.0", - "node-fetch": "^2.6.1", - "pkg-dir": "^4.2.0", - "progress": "^2.0.1", - "proxy-from-env": "^1.0.0", - "rimraf": "^3.0.2", - "tar-fs": "^2.0.0", - "unbzip2-stream": "^1.3.3", - "ws": "^7.2.3" - }, - "dependencies": { - "agent-base": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", - "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==", - "dev": true - }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dev": true, - "requires": { - "@types/yauzl": "^2.9.1", - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - } - }, - "fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", - "dev": true, - "requires": { - "pend": "~1.2.0" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "https-proxy-agent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", - "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", - "dev": true, - "requires": { - "agent-base": "5", - "debug": "4" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "ws": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz", - "integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==", - "dev": true - }, - "yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", - "dev": true, - "requires": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - } - } - }, - "q": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", - "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "query-string": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", - "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", - "dev": true, - "requires": { - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" - } - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "dev": true - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true - }, - "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", - "dev": true, - "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "dependencies": { - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "dev": true - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - } - } - }, - "raw-loader": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-4.0.0.tgz", - "integrity": "sha512-iINUOYvl1cGEmfoaLjnZXt4bKfT2LJnZZib5N/LLyAphC+Dd11vNP9CNVb38j+SAJpFI1uo8j9frmih53ASy7Q==", - "dev": true, - "requires": { - "loader-utils": "^1.2.3", - "schema-utils": "^2.5.0" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - } - } - }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - } - }, - "rcedit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/rcedit/-/rcedit-2.3.0.tgz", - "integrity": "sha512-h1gNEl9Oai1oijwyJ1WYqYSXTStHnOcv1KYljg/8WM4NAg3H1KBK3azIaKkQ1WQl+d7PoJpcBMscPfLXVKgCLQ==", - "dev": true - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=", - "dev": true, - "requires": { - "pify": "^2.3.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "read-config-file": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/read-config-file/-/read-config-file-6.2.0.tgz", - "integrity": "sha512-gx7Pgr5I56JtYz+WuqEbQHj/xWo+5Vwua2jhb1VwM4Wid5PqYmZ4i00ZB0YEGIfkVBsCv9UrjgyqCiQfS/Oosg==", - "dev": true, - "requires": { - "dotenv": "^9.0.2", - "dotenv-expand": "^5.1.0", - "js-yaml": "^4.1.0", - "json5": "^2.2.0", - "lazy-val": "^1.0.4" - }, - "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - } - } - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dev": true, - "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - }, - "dependencies": { - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "requires": { - "pify": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - } - } - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdir-glob": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.1.tgz", - "integrity": "sha512-91/k1EzZwDx6HbERR+zucygRFfiPl2zkIYZtv3Jjr6Mn7SkKcVct8aVO+sSRiGMc6fLf72du3d92/uY63YPdEA==", - "dev": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - } - } - }, - "readline2": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", - "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "mute-stream": "0.0.5" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "mute-stream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", - "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", - "dev": true - } - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "requires": { - "resolve": "^1.1.6" - } - }, - "redent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", - "dev": true, - "requires": { - "indent-string": "^2.1.0", - "strip-indent": "^1.0.1" - }, - "dependencies": { - "indent-string": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - } - } - }, - "reflect-metadata": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", - "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==" - }, - "regenerate": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", - "dev": true - }, - "regenerate-unicode-properties": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz", - "integrity": "sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA==", - "dev": true, - "requires": { - "regenerate": "^1.4.2" - } - }, - "regenerator-runtime": { - "version": "0.13.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", - "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", - "dev": true - }, - "regenerator-transform": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", - "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==", - "dev": true, - "requires": { - "@babel/runtime": "^7.8.4" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "regexp.prototype.flags": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", - "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "regexpu-core": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.8.0.tgz", - "integrity": "sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg==", - "dev": true, - "requires": { - "regenerate": "^1.4.2", - "regenerate-unicode-properties": "^9.0.0", - "regjsgen": "^0.5.2", - "regjsparser": "^0.7.0", - "unicode-match-property-ecmascript": "^2.0.0", - "unicode-match-property-value-ecmascript": "^2.0.0" - } - }, - "registry-auth-token": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", - "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", - "dev": true, - "requires": { - "rc": "^1.2.8" - } - }, - "registry-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", - "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", - "dev": true, - "requires": { - "rc": "^1.2.8" - } - }, - "regjsgen": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", - "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", - "dev": true - }, - "regjsparser": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.7.0.tgz", - "integrity": "sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ==", - "dev": true, - "requires": { - "jsesc": "~0.5.0" - }, - "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true - } - } - }, - "remove-bom-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", - "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5", - "is-utf8": "^0.2.1" - } - }, - "remove-bom-stream": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", - "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=", - "dev": true, - "requires": { - "remove-bom-buffer": "^3.0.0", - "safe-buffer": "^5.1.0", - "through2": "^2.0.3" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" - }, - "repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==" - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" - }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, - "requires": { - "is-finite": "^1.0.0" - } - }, - "replace-ext": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", - "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", - "dev": true - }, - "replace-homedir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz", - "integrity": "sha1-6H9tUTuSjd6AgmDBK+f+xv9ueYw=", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1", - "is-absolute": "^1.0.0", - "remove-trailing-separator": "^1.1.0" - } - }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "request-progress": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz", - "integrity": "sha1-XTa7V5YcZzqlt4jbyBQf3yO0Tgg=", - "requires": { - "throttleit": "^1.0.0" - } - }, - "require-dir": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/require-dir/-/require-dir-1.2.0.tgz", - "integrity": "sha512-LY85DTSu+heYgDqq/mK+7zFHWkttVNRXC9NKcKGyuGLdlsfbjEPrIEYdCVrx6hqnJb+xSu3Lzaoo8VnmOhhjNA==", - "dev": true - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "reselect": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.5.tgz", - "integrity": "sha512-uVdlz8J7OO+ASpBYoz1Zypgx0KasCY20H+N8JD13oUMtPvSHQuscrHop4KbXrbsBcdB9Ds7lVK7eRkBIfO43vQ==", - "dev": true - }, - "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } - }, - "resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", - "dev": true - }, - "resolve-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", - "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", - "dev": true, - "requires": { - "resolve-from": "^3.0.0" - } - }, - "resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", - "dev": true, - "requires": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" - } - }, - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true - }, - "resolve-options": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", - "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=", - "dev": true, - "requires": { - "value-or-function": "^3.0.0" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" - }, - "responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", - "dev": true, - "requires": { - "lowercase-keys": "^1.0.0" - } - }, - "resq": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/resq/-/resq-1.10.1.tgz", - "integrity": "sha512-zhp1iyUH02MLciv3bIM2bNtTFx/fqRsK4Jk73jcPqp00d/sMTTjOtjdTMAcgjrQKGx5DvQ/HSpeqaMW0atGRJA==", - "dev": true, - "requires": { - "fast-deep-equal": "^2.0.1" - } - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" - }, - "retry": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", - "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=" - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rgb-regex": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", - "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=", - "dev": true - }, - "rgb2hex": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/rgb2hex/-/rgb2hex-0.2.3.tgz", - "integrity": "sha512-clEe0m1xv+Tva1B/TOepuIcvLAxP0U+sCDfgt1SX1HmI2Ahr5/Cd/nzJM1e78NKVtWdoo0s33YehpFA8UfIShQ==", - "dev": true - }, - "rgba-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", - "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=", - "dev": true - }, - "rimraf": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz", - "integrity": "sha1-loAAk8vxoMhr2VtGJUZ1NcKd+gQ=", - "requires": { - "glob": "^7.0.5" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "roarr": { - "version": "2.15.4", - "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", - "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", - "dev": true, - "optional": true, - "requires": { - "boolean": "^3.0.1", - "detect-node": "^2.0.4", - "globalthis": "^1.0.1", - "json-stringify-safe": "^5.0.1", - "semver-compare": "^1.0.0", - "sprintf-js": "^1.1.2" - }, - "dependencies": { - "sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", - "dev": true, - "optional": true - } - } - }, - "rollup": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.1.0.tgz", - "integrity": "sha512-gfE1455AEazVVTJoeQtcOq/U6GSxwoj4XPSWVsuWmgIxj7sBQNLDOSA82PbdMe+cP8ql8fR1jogPFe8Wg8g4SQ==", - "dev": true, - "requires": { - "fsevents": "~2.1.2" - }, - "dependencies": { - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - } - } - }, - "run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==" - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "requires": { - "aproba": "^1.1.1" - } - }, - "run-sequence": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/run-sequence/-/run-sequence-1.2.2.tgz", - "integrity": "sha1-UJWgvr6YczsBQL0I3YDsAw3azes=", - "dev": true, - "requires": { - "chalk": "*", - "gulp-util": "*" - } - }, - "rx-lite": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", - "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", - "dev": true - }, - "rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "requires": { - "tslib": "^1.9.0" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "sanitize-filename": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", - "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", - "dev": true, - "requires": { - "truncate-utf8-bytes": "^1.0.0" - } - }, - "sass": { - "version": "1.26.3", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.26.3.tgz", - "integrity": "sha512-5NMHI1+YFYw4sN3yfKjpLuV9B5l7MqQ6FlkTcC4FT+oHbBRUZoSjHrrt/mE0nFXJyY2kQtU9ou9HxvFVjLFuuw==", - "dev": true, - "requires": { - "chokidar": ">=2.0.0 <4.0.0" - } - }, - "sass-loader": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-8.0.2.tgz", - "integrity": "sha512-7o4dbSK8/Ol2KflEmSco4jTjQoV988bM82P9CZdmo9hR3RLnvNc0ufMNdMrB0caq38JQ/FgF4/7RcbcfKzxoFQ==", - "dev": true, - "requires": { - "clone-deep": "^4.0.1", - "loader-utils": "^1.2.3", - "neo-async": "^2.6.1", - "schema-utils": "^2.6.1", - "semver": "^6.3.0" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, - "schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - } - } - }, - "select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", - "dev": true - }, - "selfsigned": { - "version": "1.10.11", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.11.tgz", - "integrity": "sha512-aVmbPOfViZqOZPgRBT0+3u4yZFHpmnIghLMlAcb5/xhp5ZtB/RVnKhz5vl2M32CLXAqR4kha9zfhNg0Lf/sxKA==", - "dev": true, - "requires": { - "node-forge": "^0.10.0" - } - }, - "semver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", - "dev": true - }, - "semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", - "dev": true, - "optional": true - }, - "semver-diff": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", - "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", - "dev": true, - "requires": { - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "semver-greatest-satisfied-range": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz", - "integrity": "sha1-E+jCZYq5aRywzXEJMkAoDTb3els=", - "dev": true, - "requires": { - "sver-compat": "^1.5.0" - } - }, - "semver-intersect": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/semver-intersect/-/semver-intersect-1.4.0.tgz", - "integrity": "sha512-d8fvGg5ycKAq0+I6nfWeCx6ffaWJCsBYU0H2Rq56+/zFePYfT8mXkB3tWBSjR5BerkHNZ5eTPIk1/LBYas35xQ==", - "requires": { - "semver": "^5.0.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", - "dev": true, - "requires": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.7.2", - "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", - "range-parser": "~1.2.1", - "statuses": "~1.5.0" - }, - "dependencies": { - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - } - } - }, - "serialize-error": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", - "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", - "dev": true, - "optional": true, - "requires": { - "type-fest": "^0.13.1" - } - }, - "serialize-javascript": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", - "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", - "dev": true, - "requires": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "dependencies": { - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true - } - } - }, - "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", - "dev": true, - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.17.1" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=" - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "requires": { - "kind-of": "^6.0.2" - } - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "shelljs": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz", - "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==", - "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - } - }, - "showdown": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/showdown/-/showdown-1.9.1.tgz", - "integrity": "sha512-9cGuS382HcvExtf5AHk7Cb4pAeQQ+h0eTr33V1mu+crYWV4KvWAw6el92bDrqGEk5d46Ai/fhbEUwqJ/mTCNEA==", - "requires": { - "yargs": "^14.2" - }, - "dependencies": { - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "yargs": { - "version": "14.2.3", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.3.tgz", - "integrity": "sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==", - "requires": { - "cliui": "^5.0.0", - "decamelize": "^1.2.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": "^15.0.1" - } - }, - "yargs-parser": { - "version": "15.0.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.3.tgz", - "integrity": "sha512-/MVEVjTXy/cGAjdtQf8dW3V9b97bPN7rNn8ETj6BmAQL7ibC7O1Q9SPJbGjgh3SlwoBNXMzj/ZGIj8mBgl12YA==", - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "signal-exit": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", - "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==" - }, - "simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", - "dev": true, - "requires": { - "is-arrayish": "^0.3.1" - }, - "dependencies": { - "is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", - "dev": true - } - } - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "slice-ansi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", - "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", - "dev": true, - "optional": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0" - } - }, - "smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==" - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "sockjs": { - "version": "0.3.20", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.20.tgz", - "integrity": "sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA==", - "dev": true, - "requires": { - "faye-websocket": "^0.10.0", - "uuid": "^3.4.0", - "websocket-driver": "0.6.5" - } - }, - "sockjs-client": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.4.0.tgz", - "integrity": "sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==", - "dev": true, - "requires": { - "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" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - } - } - }, - "socks": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.3.3.tgz", - "integrity": "sha512-o5t52PCNtVdiOvzMry7wU4aOqYWL0PeCXRWBEiJow4/i/wr+wpsJQ9awEu1EonLIqsfGd5qSgDdxEOvCdmBEpA==", - "requires": { - "ip": "1.1.5", - "smart-buffer": "^4.1.0" - } - }, - "socks-proxy-agent": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz", - "integrity": "sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg==", - "requires": { - "agent-base": "~4.2.1", - "socks": "~2.3.2" - }, - "dependencies": { - "agent-base": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", - "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", - "requires": { - "es6-promisify": "^5.0.0" - } - } - } - }, - "sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", - "dev": true, - "requires": { - "is-plain-obj": "^1.0.0" - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" - }, - "source-map-loader": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-0.2.4.tgz", - "integrity": "sha512-OU6UJUty+i2JDpTItnizPrlpOIBLmQbWMuBg9q5bVtnHACqw1tn9nNwqJLbv0/00JjnJb/Ee5g5WS5vrRv7zIQ==", - "dev": true, - "requires": { - "async": "^2.5.0", - "loader-utils": "^1.1.0" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - } - } - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.20", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", - "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==" - }, - "sourcemap-codec": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", - "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==" - }, - "sparkles": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz", - "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==", - "dev": true - }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz", - "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==" - }, - "spdy": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "spectron": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/spectron/-/spectron-12.0.0.tgz", - "integrity": "sha512-ZyDFS7I+4dWa/YXSQ/trbC4s1Rd0Ks5oi4MQ6XSJHULPasJhx5q2bM93Ae7BNUvwrGrbhjk7O6f14JwqJimLyA==", - "dev": true, - "requires": { - "dev-null": "^0.1.1", - "electron-chromedriver": "^10.0.0", - "request": "^2.87.0", - "split": "^1.0.0", - "webdriverio": "^6.1.20" - } - }, - "speed-measure-webpack-plugin": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/speed-measure-webpack-plugin/-/speed-measure-webpack-plugin-1.3.1.tgz", - "integrity": "sha512-qVIkJvbtS9j/UeZumbdfz0vg+QfG/zxonAjzefZrqzkr7xOncLVXkeGbTpzd1gjCBM4PmVNkWlkeTVhgskAGSQ==", - "dev": true, - "requires": { - "chalk": "^2.0.1" - } - }, - "speedometer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/speedometer/-/speedometer-1.0.0.tgz", - "integrity": "sha1-zWccsGdSwivKM3Di8zREC+T8YuI=" - }, - "split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", - "dev": true, - "requires": { - "through": "2" - } - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "sql.js": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/sql.js/-/sql.js-0.3.2.tgz", - "integrity": "sha1-FnYyHwcWvbve+Na/cGA0JEBdOIk=" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "ssri": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", - "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "dev": true - }, - "stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", - "dev": true - }, - "stack-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - } - } - }, - "stat-mode": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-1.0.0.tgz", - "integrity": "sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==", - "dev": true - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - } - } - }, - "stream-combiner": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", - "integrity": "sha1-rsjLrBd7Vrb0+kec7YwZEs7lKFg=", - "dev": true, - "requires": { - "duplexer": "~0.1.1", - "through": "~2.3.4" - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-exhaust": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", - "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==", - "dev": true - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - } - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" - }, - "stream-to-array": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/stream-to-array/-/stream-to-array-2.3.0.tgz", - "integrity": "sha1-u/azn19D7DC8cbq8s3VXrOzzQ1M=", - "dev": true, - "requires": { - "any-promise": "^1.1.0" - } - }, - "streamfilter": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/streamfilter/-/streamfilter-1.0.7.tgz", - "integrity": "sha512-Gk6KZM+yNA1JpW0KzlZIhjo3EaBJDkYfXtYSbOwNIQ7Zd6006E6+sCFlW1NDvFG/vnXhKmw6TJJgiEQg/8lXfQ==", - "dev": true, - "requires": { - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - } - } - }, - "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "stringify-object": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-2.4.0.tgz", - "integrity": "sha1-xi0RAj6yH+LZsIe+A5om3zsioJ0=", - "dev": true, - "requires": { - "is-plain-obj": "^1.0.0", - "is-regexp": "^1.0.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - } - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "strip-bom-buf": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-buf/-/strip-bom-buf-1.0.0.tgz", - "integrity": "sha1-HLRar1dTD0yvhsf3UXnSyaUd1XI=", - "dev": true, - "requires": { - "is-utf8": "^0.2.1" - } - }, - "strip-bom-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-3.0.0.tgz", - "integrity": "sha1-lWvMXYRDD2klapDtgjdlzYWOFZw=", - "dev": true, - "requires": { - "first-chunk-stream": "^2.0.0", - "strip-bom-buf": "^1.0.0" - } - }, - "strip-bom-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", - "integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=", - "dev": true - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "strip-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", - "dev": true, - "requires": { - "get-stdin": "^4.0.1" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "style-loader": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-1.1.3.tgz", - "integrity": "sha512-rlkH7X/22yuwFYK357fMN/BxYOorfnfq0eD7+vqlemSK4wEcejFF1dg4zxP0euBW8NrYx2WZzZ8PPFevr7D+Kw==", - "dev": true, - "requires": { - "loader-utils": "^1.2.3", - "schema-utils": "^2.6.4" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - } - } - }, - "stylehacks": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", - "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==", - "dev": true, - "requires": { - "browserslist": "^4.0.0", - "postcss": "^7.0.0", - "postcss-selector-parser": "^3.0.0" - }, - "dependencies": { - "postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "dev": true, - "requires": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - } - } - }, - "stylus": { - "version": "0.54.7", - "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.7.tgz", - "integrity": "sha512-Yw3WMTzVwevT6ZTrLCYNHAFmanMxdylelL3hkWNgPMeTCpMwpV3nXjpOHuBXtFv7aiO2xRuQS6OoAdgkNcSNug==", - "dev": true, - "requires": { - "css-parse": "~2.0.0", - "debug": "~3.1.0", - "glob": "^7.1.3", - "mkdirp": "~0.5.x", - "safer-buffer": "^2.1.2", - "sax": "~1.2.4", - "semver": "^6.0.0", - "source-map": "^0.7.3" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "stylus-loader": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/stylus-loader/-/stylus-loader-3.0.2.tgz", - "integrity": "sha512-+VomPdZ6a0razP+zinir61yZgpw2NfljeSsdUF5kJuEzlo3khXhY19Fn6l8QQz1GRJGtMCo8nG5C04ePyV7SUA==", - "dev": true, - "requires": { - "loader-utils": "^1.0.2", - "lodash.clonedeep": "^4.5.0", - "when": "~3.6.x" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - } - } - }, - "sumchecker": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", - "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", - "dev": true, - "requires": { - "debug": "^4.1.0" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - }, - "sver-compat": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz", - "integrity": "sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg=", - "dev": true, - "requires": { - "es6-iterator": "^2.0.1", - "es6-symbol": "^3.1.1" - } - }, - "svgo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", - "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "coa": "^2.0.2", - "css-select": "^2.0.0", - "css-select-base-adapter": "^0.1.1", - "css-tree": "1.0.0-alpha.37", - "csso": "^4.0.2", - "js-yaml": "^3.13.1", - "mkdirp": "~0.5.1", - "object.values": "^1.1.0", - "sax": "~1.2.4", - "stable": "^0.1.8", - "unquote": "~1.1.1", - "util.promisify": "~1.0.0" - }, - "dependencies": { - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - } - } - }, - "symbol-observable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", - "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "tar": { - "version": "4.4.19", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", - "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", - "requires": { - "chownr": "^1.1.4", - "fs-minipass": "^1.2.7", - "minipass": "^2.9.0", - "minizlib": "^1.3.3", - "mkdirp": "^0.5.5", - "safe-buffer": "^5.2.1", - "yallist": "^3.1.1" - }, - "dependencies": { - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - } - } - }, - "tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", - "dev": true, - "requires": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dev": true, - "requires": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - } - }, - "temp-file": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.4.0.tgz", - "integrity": "sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==", - "dev": true, - "requires": { - "async-exit-hook": "^2.0.1", - "fs-extra": "^10.0.0" - }, - "dependencies": { - "fs-extra": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", - "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - } - } - }, - "terser": { - "version": "4.6.10", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.10.tgz", - "integrity": "sha512-qbF/3UOo11Hggsbsqm2hPa6+L4w7bkr+09FNseEe8xrcVD3APGLFqE+Oz1ZKAxjYnFsj80rLOfgAtJ0LNJjtTA==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.8.tgz", - "integrity": "sha512-/fKw3R+hWyHfYx7Bv6oPqmk4HGQcrWLtV3X6ggvPuwPNHSnzvVV51z6OaaCOus4YLjutYGOz3pEpbhe6Up2s1w==", - "dev": true, - "requires": { - "cacache": "^13.0.1", - "find-cache-dir": "^3.3.1", - "jest-worker": "^25.4.0", - "p-limit": "^2.3.0", - "schema-utils": "^2.6.6", - "serialize-javascript": "^4.0.0", - "source-map": "^0.6.1", - "terser": "^4.6.12", - "webpack-sources": "^1.4.3" - }, - "dependencies": { - "cacache": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-13.0.1.tgz", - "integrity": "sha512-5ZvAxd05HDDU+y9BVvcqYu2LLXmPnQ0hW62h32g4xBTgL/MppR4/04NHfj/ycM2y6lmTnbw6HVi+1eN0Psba6w==", - "dev": true, - "requires": { - "chownr": "^1.1.2", - "figgy-pudding": "^3.5.1", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", - "graceful-fs": "^4.2.2", - "infer-owner": "^1.0.4", - "lru-cache": "^5.1.1", - "minipass": "^3.0.0", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "p-map": "^3.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^2.7.1", - "ssri": "^7.0.0", - "unique-filename": "^1.1.1" - } - }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "jest-worker": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", - "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", - "dev": true, - "requires": { - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - } - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "minipass": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.5.tgz", - "integrity": "sha512-+8NzxD82XQoNKNrl1d/FSi+X8wAEWR+sbYAfIvub4Nz0d22plFG72CEVVaufV8PNf4qSslFTD8VMOxNVhHCjTw==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "ssri": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-7.1.1.tgz", - "integrity": "sha512-w+daCzXN89PseTL99MkA+fxJEcU3wfaE/ah0i0lnOlpG1CYLJ2ZjzEry68YBKfLs4JfoTShrTEsJkAZuNZ/stw==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1", - "minipass": "^3.1.1" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "terser": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", - "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "throttleit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", - "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=" - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - } - } - }, - "through2-filter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", - "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", - "dev": true, - "requires": { - "through2": "~2.0.0", - "xtend": "~4.0.0" - } - }, - "thunky": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", - "dev": true - }, - "tildify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz", - "integrity": "sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo=", - "dev": true, - "requires": { - "os-homedir": "^1.0.0" - } - }, - "time-stamp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", - "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=", - "dev": true - }, - "timers-browserify": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", - "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "timers-ext": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", - "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", - "dev": true, - "requires": { - "es5-ext": "~0.10.46", - "next-tick": "1" - } - }, - "timsort": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", - "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", - "dev": true - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "tmp-promise": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.2.tgz", - "integrity": "sha512-OyCLAKU1HzBjL6Ev3gxUeraJNlbNingmi8IrHHEsYH8LTmEuhvYfqvhn2F/je+mjf4N58UmZ96OMEy1JanSCpA==", - "dev": true, - "requires": { - "tmp": "^0.2.0" - }, - "dependencies": { - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "requires": { - "rimraf": "^3.0.0" - } - } - } - }, - "to-absolute-glob": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", - "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=", - "dev": true, - "requires": { - "is-absolute": "^1.0.0", - "is-negated-glob": "^1.0.0" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", - "dev": true - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "to-through": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", - "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=", - "dev": true, - "requires": { - "through2": "^2.0.3" - } - }, - "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", - "dev": true - }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", - "dev": true - }, - "tree-kill": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==" - }, - "trim-newlines": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", - "dev": true - }, - "truncate-utf8-bytes": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", - "integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=", - "dev": true, - "requires": { - "utf8-byte-length": "^1.0.1" - } - }, - "ts-loader": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.3.0.tgz", - "integrity": "sha512-MgGly4I6cStsJy27ViE32UoqxPTN9Xly4anxxVyaIWR+9BGxboV4EyJBGfR3RePV7Ksjj3rHmPZJeIt+7o4Vag==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "enhanced-resolve": "^4.0.0", - "loader-utils": "^2.0.0", - "micromatch": "^4.0.0", - "semver": "^7.3.4" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", - "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", - "dev": true, - "optional": true - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "type": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", - "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", - "dev": true - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "dev": true, - "optional": true - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "typescript": { - "version": "3.9.10", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", - "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", - "dev": true - }, - "ua-parser-js": { - "version": "0.7.28", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.28.tgz", - "integrity": "sha512-6Gurc1n//gjp9eQNXjD9O3M/sMwVtN5S8Lv9bvOYBfKfDNiIIhqiyi01vMBO45u4zkDE420w/e0se7Vs+sIg+g==", - "dev": true - }, - "uglify-js": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.2.tgz", - "integrity": "sha512-rtPMlmcO4agTUfz10CbgJ1k6UAoXM2gWb3GoMPPZB/+/Ackf8lNWk11K4rYi2D0apgoFRLtQOZhb+/iGNJq26A==", - "dev": true - }, - "uglify-save-license": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/uglify-save-license/-/uglify-save-license-0.4.1.tgz", - "integrity": "sha1-lXJsF8xv0XHDYX479NjYKqjEzOE=", - "dev": true - }, - "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - } - }, - "unbzip2-stream": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", - "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", - "dev": true, - "requires": { - "buffer": "^5.2.1", - "through": "^2.3.8" - }, - "dependencies": { - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - } - } - }, - "unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", - "dev": true - }, - "undertaker": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.3.0.tgz", - "integrity": "sha512-/RXwi5m/Mu3H6IHQGww3GNt1PNXlbeCuclF2QYR14L/2CHPz3DFZkvB5hZ0N/QUkiXWCACML2jXViIQEQc2MLg==", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1", - "arr-map": "^2.0.0", - "bach": "^1.0.0", - "collection-map": "^1.0.0", - "es6-weak-map": "^2.0.1", - "fast-levenshtein": "^1.0.0", - "last-run": "^1.1.0", - "object.defaults": "^1.0.0", - "object.reduce": "^1.0.0", - "undertaker-registry": "^1.0.0" - } - }, - "undertaker-registry": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz", - "integrity": "sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=", - "dev": true - }, - "unicode-canonical-property-names-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", - "dev": true - }, - "unicode-match-property-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", - "dev": true, - "requires": { - "unicode-canonical-property-names-ecmascript": "^2.0.0", - "unicode-property-aliases-ecmascript": "^2.0.0" - } - }, - "unicode-match-property-value-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz", - "integrity": "sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==", - "dev": true - }, - "unicode-property-aliases-ecmascript": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz", - "integrity": "sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==", - "dev": true - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "uniq": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", - "dev": true - }, - "uniqs": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", - "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", - "dev": true - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "unique-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", - "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", - "dev": true, - "requires": { - "json-stable-stringify-without-jsonify": "^1.0.1", - "through2-filter": "^3.0.0" - } - }, - "unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "dev": true, - "requires": { - "crypto-random-string": "^2.0.0" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true - }, - "unquote": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", - "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=", - "dev": true - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" - } - } - }, - "upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==" - }, - "update-notifier": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz", - "integrity": "sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==", - "dev": true, - "requires": { - "boxen": "^5.0.0", - "chalk": "^4.1.0", - "configstore": "^5.0.1", - "has-yarn": "^2.1.0", - "import-lazy": "^2.1.0", - "is-ci": "^2.0.0", - "is-installed-globally": "^0.4.0", - "is-npm": "^5.0.0", - "is-yarn-global": "^0.3.0", - "latest-version": "^5.1.0", - "pupa": "^2.1.1", - "semver": "^7.3.4", - "semver-diff": "^3.1.1", - "xdg-basedir": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, - "requires": { - "ci-info": "^2.0.0" - } - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-parse": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.3.tgz", - "integrity": "sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==", - "dev": true, - "requires": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", - "dev": true, - "requires": { - "prepend-http": "^2.0.0" - }, - "dependencies": { - "prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", - "dev": true - } - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" - }, - "utf8-byte-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", - "integrity": "sha1-9F8VDExm7uloGGUFq5P8u4rWv2E=", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "util.promisify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", - "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.2", - "has-symbols": "^1.0.1", - "object.getownpropertydescriptors": "^2.1.0" - } - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "dev": true - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "v8flags": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", - "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "validate-npm-package-name": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", - "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=", - "requires": { - "builtins": "^1.0.3" - } - }, - "value-or-function": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", - "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=", - "dev": true - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true - }, - "vendors": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", - "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==", - "dev": true - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - }, - "dependencies": { - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - } - } - }, - "vinyl": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", - "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", - "dev": true, - "requires": { - "clone": "^2.1.1", - "clone-buffer": "^1.0.0", - "clone-stats": "^1.0.0", - "cloneable-readable": "^1.0.0", - "remove-trailing-separator": "^1.0.1", - "replace-ext": "^1.0.0" - } - }, - "vinyl-fs": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", - "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", - "dev": true, - "requires": { - "fs-mkdirp-stream": "^1.0.0", - "glob-stream": "^6.1.0", - "graceful-fs": "^4.0.0", - "is-valid-glob": "^1.0.0", - "lazystream": "^1.0.0", - "lead": "^1.0.0", - "object.assign": "^4.0.4", - "pumpify": "^1.3.5", - "readable-stream": "^2.3.3", - "remove-bom-buffer": "^3.0.0", - "remove-bom-stream": "^1.2.0", - "resolve-options": "^1.1.0", - "through2": "^2.0.0", - "to-through": "^2.0.0", - "value-or-function": "^3.0.0", - "vinyl": "^2.0.0", - "vinyl-sourcemap": "^1.1.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - } - } - }, - "vinyl-sourcemap": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", - "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=", - "dev": true, - "requires": { - "append-buffer": "^1.0.2", - "convert-source-map": "^1.5.0", - "graceful-fs": "^4.1.6", - "normalize-path": "^2.1.1", - "now-and-later": "^2.0.0", - "remove-bom-buffer": "^3.0.0", - "vinyl": "^2.0.0" - } - }, - "vinyl-sourcemaps-apply": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz", - "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=", - "dev": true, - "requires": { - "source-map": "^0.5.1" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, - "walk": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/walk/-/walk-2.3.3.tgz", - "integrity": "sha1-tMDoxCRkwW274dcWZnZerAeBnl8=", - "dev": true, - "requires": { - "foreachasync": "3.x" - } - }, - "watchpack": { - "version": "1.7.5", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", - "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==", - "dev": true, - "requires": { - "chokidar": "^3.4.1", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0", - "watchpack-chokidar2": "^2.0.1" - }, - "dependencies": { - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "optional": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "optional": true - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "optional": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "chokidar": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", - "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", - "dev": true, - "optional": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "optional": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "optional": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "optional": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "optional": true - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "optional": true - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "optional": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "optional": true, - "requires": { - "is-number": "^7.0.0" - } - } - } - }, - "watchpack-chokidar2": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz", - "integrity": "sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==", - "dev": true, - "optional": true, - "requires": { - "chokidar": "^2.1.8" - }, - "dependencies": { - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "optional": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "optional": true - } - } - }, - "wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "dev": true, - "requires": { - "minimalistic-assert": "^1.0.0" - } - }, - "webdriver": { - "version": "6.12.1", - "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-6.12.1.tgz", - "integrity": "sha512-3rZgAj9o2XHp16FDTzvUYaHelPMSPbO1TpLIMUT06DfdZjNYIzZiItpIb/NbQDTPmNhzd9cuGmdI56WFBGY2BA==", - "dev": true, - "requires": { - "@wdio/config": "6.12.1", - "@wdio/logger": "6.10.10", - "@wdio/protocols": "6.12.0", - "@wdio/utils": "6.11.0", - "got": "^11.0.2", - "lodash.merge": "^4.6.1" - }, - "dependencies": { - "@sindresorhus/is": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.2.0.tgz", - "integrity": "sha512-VkE3KLBmJwcCaVARtQpfuKcKv8gcBmUubrfHGF84dXuuW6jgsRYxPtzcIhPyK9WAPpRt2/xY6zkD9MnRaJzSyw==", - "dev": true - }, - "@szmarczak/http-timer": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", - "dev": true, - "requires": { - "defer-to-connect": "^2.0.0" - } - }, - "cacheable-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", - "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", - "dev": true, - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" - } - }, - "decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, - "requires": { - "mimic-response": "^3.1.0" - } - }, - "defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "dev": true - }, - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "got": { - "version": "11.8.2", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.2.tgz", - "integrity": "sha512-D0QywKgIe30ODs+fm8wMZiAcZjypcCodPNuMz5H9Mny7RJ+IjJ10BdmGW7OM7fHXP+O7r6ZwapQ/YQmMSvB0UQ==", - "dev": true, - "requires": { - "@sindresorhus/is": "^4.0.0", - "@szmarczak/http-timer": "^4.0.5", - "@types/cacheable-request": "^6.0.1", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^5.0.3", - "cacheable-request": "^7.0.1", - "decompress-response": "^6.0.0", - "http2-wrapper": "^1.0.0-beta.5.2", - "lowercase-keys": "^2.0.0", - "p-cancelable": "^2.0.0", - "responselike": "^2.0.0" - } - }, - "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true - }, - "json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "keyv": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz", - "integrity": "sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==", - "dev": true, - "requires": { - "json-buffer": "3.0.1" - } - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true - }, - "mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true - }, - "normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "dev": true - }, - "p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", - "dev": true - }, - "responselike": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", - "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", - "dev": true, - "requires": { - "lowercase-keys": "^2.0.0" - } - } - } - }, - "webdriverio": { - "version": "6.12.1", - "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-6.12.1.tgz", - "integrity": "sha512-Nx7ge0vTWHVIRUbZCT+IuMwB5Q0Q5nLlYdgnmmJviUKLuc3XtaEBkYPTbhHWHgSBXsPZMIc023vZKNkn+6iyeQ==", - "dev": true, - "requires": { - "@types/puppeteer-core": "^5.4.0", - "@wdio/config": "6.12.1", - "@wdio/logger": "6.10.10", - "@wdio/repl": "6.11.0", - "@wdio/utils": "6.11.0", - "archiver": "^5.0.0", - "atob": "^2.1.2", - "css-shorthand-properties": "^1.1.1", - "css-value": "^0.0.1", - "devtools": "6.12.1", - "fs-extra": "^9.0.1", - "get-port": "^5.1.1", - "grapheme-splitter": "^1.0.2", - "lodash.clonedeep": "^4.5.0", - "lodash.isobject": "^3.0.2", - "lodash.isplainobject": "^4.0.6", - "lodash.zip": "^4.2.0", - "minimatch": "^3.0.4", - "puppeteer-core": "^5.1.0", - "resq": "^1.9.1", - "rgb2hex": "0.2.3", - "serialize-error": "^8.0.0", - "webdriver": "6.12.1" - }, - "dependencies": { - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "serialize-error": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-8.1.0.tgz", - "integrity": "sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - } - } - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", - "dev": true - }, - "webpack": { - "version": "4.46.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.46.0.tgz", - "integrity": "sha512-6jJuJjg8znb/xRItk7bkT0+Q7AHCYjjFnvKIWQPkNIOyRqoCGvkOs0ipeQzrqz4l5FtN5ZI/ukEHroeX/o1/5Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/wasm-edit": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0", - "acorn": "^6.4.1", - "ajv": "^6.10.2", - "ajv-keywords": "^3.4.1", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^4.5.0", - "eslint-scope": "^4.0.3", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.4.0", - "loader-utils": "^1.2.3", - "memory-fs": "^0.4.1", - "micromatch": "^3.1.10", - "mkdirp": "^0.5.3", - "neo-async": "^2.6.1", - "node-libs-browser": "^2.2.1", - "schema-utils": "^1.0.0", - "tapable": "^1.1.3", - "terser-webpack-plugin": "^1.4.3", - "watchpack": "^1.7.4", - "webpack-sources": "^1.4.1" - }, - "dependencies": { - "@webassemblyjs/ast": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", - "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", - "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", - "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", - "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", - "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.9.0" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", - "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", - "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", - "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", - "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", - "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", - "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", - "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", - "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/helper-wasm-section": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0", - "@webassemblyjs/wasm-opt": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0", - "@webassemblyjs/wast-printer": "1.9.0" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", - "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/ieee754": "1.9.0", - "@webassemblyjs/leb128": "1.9.0", - "@webassemblyjs/utf8": "1.9.0" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", - "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-buffer": "1.9.0", - "@webassemblyjs/wasm-gen": "1.9.0", - "@webassemblyjs/wasm-parser": "1.9.0" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", - "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/helper-api-error": "1.9.0", - "@webassemblyjs/helper-wasm-bytecode": "1.9.0", - "@webassemblyjs/ieee754": "1.9.0", - "@webassemblyjs/leb128": "1.9.0", - "@webassemblyjs/utf8": "1.9.0" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", - "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/floating-point-hex-parser": "1.9.0", - "@webassemblyjs/helper-api-error": "1.9.0", - "@webassemblyjs/helper-code-frame": "1.9.0", - "@webassemblyjs/helper-fsm": "1.9.0", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", - "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.9.0", - "@webassemblyjs/wast-parser": "1.9.0", - "@xtuc/long": "4.2.2" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "cacache": { - "version": "12.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", - "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - } - }, - "enhanced-resolve": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", - "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.5.0", - "tapable": "^1.0.0" - }, - "dependencies": { - "memory-fs": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", - "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", - "dev": true, - "requires": { - "errno": "^0.1.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.26.1", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.1.tgz", + "integrity": "sha512-reoQYNiAJreZNsJzyrDNzFQ+IQ5JFiIzAHJg9bn94S3l+4++J7RsIhNMoB+lgP/9tpmiAQqspv+xfdxTSzREOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.26.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz", + "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/generator": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/template": "^7.25.9", + "@babel/types": "^7.25.9", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz", + "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@develar/schema-utils": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz", + "integrity": "sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.0", + "ajv-keywords": "^3.4.1" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/@electron/asar": { + "version": "3.2.14", + "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.2.14.tgz", + "integrity": "sha512-hc52QkesULqbxTRC1vOmSBN1YndUkieoNMfvpe988h0MEoGGqbijkOqv4/2M9PufBJxiTVoDdBmBFfXPowZDQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^5.0.0", + "glob": "^7.1.6", + "minimatch": "^3.0.4" + }, + "bin": { + "asar": "bin/asar.js" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/@electron/asar/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@electron/asar/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@electron/get": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz", + "integrity": "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "env-paths": "^2.2.0", + "fs-extra": "^8.1.0", + "got": "^11.8.5", + "progress": "^2.0.3", + "semver": "^6.2.0", + "sumchecker": "^3.0.1" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "global-agent": "^3.0.0" + } + }, + "node_modules/@electron/notarize": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@electron/notarize/-/notarize-2.5.0.tgz", + "integrity": "sha512-jNT8nwH1f9X5GEITXaQ8IF/KdskvIkOFfB2CvwumsveVidzpSc+mvhhTMdAGSYF3O+Nq49lJ7y+ssODRXu06+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "fs-extra": "^9.0.1", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@electron/notarize/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@electron/notarize/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@electron/notarize/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@electron/osx-sign": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@electron/osx-sign/-/osx-sign-1.3.1.tgz", + "integrity": "sha512-BAfviURMHpmb1Yb50YbCxnOY0wfwaLXH5KJ4+80zS0gUkzDX3ec23naTlEqKsN+PwYn+a1cCzM7BJ4Wcd3sGzw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "compare-version": "^0.1.2", + "debug": "^4.3.4", + "fs-extra": "^10.0.0", + "isbinaryfile": "^4.0.8", + "minimist": "^1.2.6", + "plist": "^3.0.5" + }, + "bin": { + "electron-osx-flat": "bin/electron-osx-flat.js", + "electron-osx-sign": "bin/electron-osx-sign.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@electron/osx-sign/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron/osx-sign/node_modules/isbinaryfile": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", + "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/@electron/osx-sign/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@electron/osx-sign/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@electron/rebuild": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.6.1.tgz", + "integrity": "sha512-f6596ZHpEq/YskUd8emYvOUne89ij8mQgjYFA5ru25QwbrRO+t1SImofdDv7kKOuWCmVOuU5tvfkbgGxIl3E/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@malept/cross-spawn-promise": "^2.0.0", + "chalk": "^4.0.0", + "debug": "^4.1.1", + "detect-libc": "^2.0.1", + "fs-extra": "^10.0.0", + "got": "^11.7.0", + "node-abi": "^3.45.0", + "node-api-version": "^0.2.0", + "node-gyp": "^9.0.0", + "ora": "^5.1.0", + "read-binary-file-arch": "^1.0.6", + "semver": "^7.3.5", + "tar": "^6.0.5", + "yargs": "^17.0.1" + }, + "bin": { + "electron-rebuild": "lib/cli.js" + }, + "engines": { + "node": ">=12.13.0" + } + }, + "node_modules/@electron/rebuild/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron/rebuild/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@electron/rebuild/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@electron/rebuild/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@electron/universal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-2.0.1.tgz", + "integrity": "sha512-fKpv9kg4SPmt+hY7SVBnIYULE9QJl8L3sCfcBsnqbJwwBwAeTLokJ9TRt9y7bK0JAzIW2y78TVVjvnQEms/yyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron/asar": "^3.2.7", + "@malept/cross-spawn-promise": "^2.0.0", + "debug": "^4.3.1", + "dir-compare": "^4.2.0", + "fs-extra": "^11.1.1", + "minimatch": "^9.0.3", + "plist": "^3.1.0" + }, + "engines": { + "node": ">=16.4" + } + }, + "node_modules/@electron/universal/node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@electron/universal/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@electron/universal/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@electron/universal/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@gar/promisify": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", + "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@gulp-sourcemaps/identity-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-2.0.1.tgz", + "integrity": "sha512-Tb+nSISZku+eQ4X1lAkevcQa+jknn/OVUgZ3XCxEKIsLsqYuPoJwJOPQeaOk75X3WPftb29GWY1eqE7GLsXb1Q==", + "license": "MIT", + "dependencies": { + "acorn": "^6.4.1", + "normalize-path": "^3.0.0", + "postcss": "^7.0.16", + "source-map": "^0.6.0", + "through2": "^3.0.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/@gulp-sourcemaps/map-sources": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz", + "integrity": "sha512-o/EatdaGt8+x2qpb0vFLC/2Gug/xYPRXb6a+ET1wGYKozKN3krDWC/zZFZAtrzxJHuDL12mwdfEFKcKMNvc55A==", + "license": "MIT", + "dependencies": { + "normalize-path": "^2.0.1", + "through2": "^2.0.3" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/@gulp-sourcemaps/map-sources/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", + "license": "MIT", + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@gulp-sourcemaps/map-sources/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "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" + } + }, + "node_modules/@gulp-sourcemaps/map-sources/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/@gulp-sourcemaps/map-sources/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/@gulp-sourcemaps/map-sources/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "license": "MIT", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/@gulpjs/messages": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@gulpjs/messages/-/messages-1.1.0.tgz", + "integrity": "sha512-Ys9sazDatyTgZVb4xPlDufLweJ/Os2uHWOv+Caxvy2O85JcnT4M3vc73bi8pdLWlv3fdWQz3pdI9tVwo8rQQSg==", + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@gulpjs/to-absolute-glob": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@gulpjs/to-absolute-glob/-/to-absolute-glob-4.0.0.tgz", + "integrity": "sha512-kjotm7XJrJ6v+7knhPaRgaT6q8F8K2jiafwYdNHLzmV0uGLuZY43FK6smNSHUPrhq5kX2slCUy+RGG/xGqmIKA==", + "license": "MIT", + "dependencies": { + "is-negated-glob": "^1.0.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@malept/cross-spawn-promise": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-2.0.0.tgz", + "integrity": "sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/malept" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund" + } + ], + "license": "Apache-2.0", + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/@malept/flatpak-bundler": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@malept/flatpak-bundler/-/flatpak-bundler-0.4.0.tgz", + "integrity": "sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "fs-extra": "^9.0.0", + "lodash": "^4.17.15", + "tmp-promise": "^3.0.2" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@malept/flatpak-bundler/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@malept/flatpak-bundler/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@malept/flatpak-bundler/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@npmcli/fs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz", + "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@gar/promisify": "^1.1.3", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/@npmcli/fs/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@npmcli/move-file": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz", + "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==", + "deprecated": "This functionality has been moved to @npmcli/fs", + "dev": true, + "license": "MIT", + "dependencies": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@playwright/test": { + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.48.2.tgz", + "integrity": "sha512-54w1xCWfXuax7dz4W2M9uw0gDyh+ti/0K/MxcCUxChFh37kkdxPdfZDw5QBbuPUJHr1CiHJ1hXgSs+GgeQc5Zw==", + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.48.2" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "dev": true, + "license": "MIT", + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/fs-extra": { + "version": "9.0.13", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", + "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/jquery": { + "version": "3.5.32", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.32.tgz", + "integrity": "sha512-b9Xbf4CkMqS02YH8zACqN1xzdxc3cO735Qe5AbSUFmyOiaWAbcpqh9Wna+Uk0vgACvoQHpWDg2rGdHkYPLmCiQ==", + "license": "MIT", + "dependencies": { + "@types/sizzle": "*" + } + }, + "node_modules/@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/ms": { + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.8.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.8.1.tgz", + "integrity": "sha512-k6Gi8Yyo8EtrNtkHXutUu2corfDf9su95VYVP10aGYMMROM6SAItZi0w1XszA6RtWTHSVp5OeFof37w0IEqCQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.8" + } + }, + "node_modules/@types/plist": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/plist/-/plist-3.0.5.tgz", + "integrity": "sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*", + "xmlbuilder": ">=11.0.1" + } + }, + "node_modules/@types/responselike": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/sizzle": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.9.tgz", + "integrity": "sha512-xzLEyKB50yqCUPUJkIsrVvoWNfFUbIZI+RspLWt8u+tIW/BetMBZtgV2LY/2o+tYH8dRvQ+eoPf3NdhQCcLE2w==", + "license": "MIT" + }, + "node_modules/@types/verror": { + "version": "1.10.10", + "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.10.tgz", + "integrity": "sha512-l4MM0Jppn18hb9xmM6wwD1uTdShpf9Pn80aXTStnK1C94gtPvJcV2FrDmbOQUAQfJ1cKZHktkQUDwEqaAKXMMg==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/@types/w2ui": { + "version": "1.4.37", + "resolved": "https://registry.npmjs.org/@types/w2ui/-/w2ui-1.4.37.tgz", + "integrity": "sha512-/55RzOljbfQgQSSxkyVva8AkEP9Ugx8dUcxTGqdw9T2fKFPzGKT16tXP/3AQsuQT0bvljhxgi/6rt0zm5cuwOQ==", + "license": "MIT", + "dependencies": { + "@types/jquery": "*" + } + }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@xmldom/xmldom": { + "version": "0.8.10", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", + "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/7zip-bin": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.2.0.tgz", + "integrity": "sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A==", + "dev": true, + "license": "MIT" + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true, + "license": "ISC" + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-loose": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/acorn-loose/-/acorn-loose-8.4.0.tgz", + "integrity": "sha512-M0EUka6rb+QC4l9Z3T0nJEzNOO7JcoJlYMrBlyBCiFSXRyxjLKayd4TbQs2FDRWQU1h9FR7QVNHt+PEaoNL5rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-loose/node_modules/acorn": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.13.0.tgz", + "integrity": "sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk/node_modules/acorn": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.13.0.tgz", + "integrity": "sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/agentkeepalive": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", + "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", + "dev": true, + "license": "MIT", + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-4.0.1.tgz", + "integrity": "sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==", + "license": "MIT", + "dependencies": { + "clean-stack": "^4.0.0", + "indent-string": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "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" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-gray": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", + "integrity": "sha512-HrgGIZUl8h2EHuZaU9hTR/cU5nhKxpVE1V6kdGsQ8e4zirElJ5fvtfc8N7Q1oq1aatO275i8pUFUCpNWCAnVWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-wrap": "0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ansi-wrap": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", + "integrity": "sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/app-builder-bin": { + "version": "5.0.0-alpha.10", + "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-5.0.0-alpha.10.tgz", + "integrity": "sha512-Ev4jj3D7Bo+O0GPD2NMvJl+PGiBAfS7pUGawntBNpCbxtpncfUixqFj9z9Jme7V7s3LBGqsWZZP54fxBX3JKJw==", + "dev": true, + "license": "MIT" + }, + "node_modules/app-builder-lib": { + "version": "25.1.8", + "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-25.1.8.tgz", + "integrity": "sha512-pCqe7dfsQFBABC1jeKZXQWhGcCPF3rPCXDdfqVKjIeWBcXzyC1iOWZdfFhGl+S9MyE/k//DFmC6FzuGAUudNDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@develar/schema-utils": "~2.6.5", + "@electron/notarize": "2.5.0", + "@electron/osx-sign": "1.3.1", + "@electron/rebuild": "3.6.1", + "@electron/universal": "2.0.1", + "@malept/flatpak-bundler": "^0.4.0", + "@types/fs-extra": "9.0.13", + "async-exit-hook": "^2.0.1", + "bluebird-lst": "^1.0.9", + "builder-util": "25.1.7", + "builder-util-runtime": "9.2.10", + "chromium-pickle-js": "^0.2.0", + "config-file-ts": "0.2.8-rc1", + "debug": "^4.3.4", + "dotenv": "^16.4.5", + "dotenv-expand": "^11.0.6", + "ejs": "^3.1.8", + "electron-publish": "25.1.7", + "form-data": "^4.0.0", + "fs-extra": "^10.1.0", + "hosted-git-info": "^4.1.0", + "is-ci": "^3.0.0", + "isbinaryfile": "^5.0.0", + "js-yaml": "^4.1.0", + "json5": "^2.2.3", + "lazy-val": "^1.0.5", + "minimatch": "^10.0.0", + "resedit": "^1.7.0", + "sanitize-filename": "^1.6.3", + "semver": "^7.3.8", + "tar": "^6.1.12", + "temp-file": "^3.4.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "dmg-builder": "25.1.8", + "electron-builder-squirrel-windows": "25.1.8" + } + }, + "node_modules/app-builder-lib/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/app-builder-lib/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/app-builder-lib/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/app-builder-lib/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/append-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", + "integrity": "sha512-WLbYiXzD3y/ATLZFufV/rZvWdZOs+Z/+5v1rBZ463Jn398pa6kcde27cvozYnBoxXblGZTFfoPpsaEw0orU5BA==", + "license": "MIT", + "dependencies": { + "buffer-equal": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "default-require-extensions": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/archiver": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.2.tgz", + "integrity": "sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "archiver-utils": "^2.1.0", + "async": "^3.2.4", + "buffer-crc32": "^0.2.1", + "readable-stream": "^3.6.0", + "readdir-glob": "^1.1.2", + "tar-stream": "^2.2.0", + "zip-stream": "^4.1.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/archiver-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", + "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "glob": "^7.1.4", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^2.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/archiver-utils/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "peer": true, + "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" + } + }, + "node_modules/archiver-utils/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/archiver-utils/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", + "dev": true, + "license": "MIT" + }, + "node_modules/are-we-there-yet": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", + "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", + "deprecated": "This package is no longer supported.", + "dev": true, + "license": "ISC", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true, + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", + "integrity": "sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-slice": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", + "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "dev": true, + "license": "MIT" + }, + "node_modules/async-done": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/async-done/-/async-done-2.0.0.tgz", + "integrity": "sha512-j0s3bzYq9yKIVLKGE/tWlCpa3PfFLcrDZLTSVdnnCTGagXuXBJO4SsY9Xdk/fQBirCkH4evW5xOeJXqlAQFdsw==", + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.4.4", + "once": "^1.4.0", + "stream-exhaust": "^1.0.2" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/async-exit-hook": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz", + "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/async-settle": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-2.0.0.tgz", + "integrity": "sha512-Obu/KE8FurfQRN6ODdHN9LuXqwC+JFIM9NRyZqJJ4ZfLJmIYN9Rg0/kb+wF70VV5+fJusTMQlJ1t5rF7J/ETdg==", + "license": "MIT", + "dependencies": { + "async-done": "^2.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "license": "(MIT OR Apache-2.0)", + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/bach": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bach/-/bach-2.0.1.tgz", + "integrity": "sha512-A7bvGMGiTOxGMpNupYl9HQTf0FFDNF4VCmks4PJpFyN1AX2pdKuxuwdvUz2Hu388wcgp+OvGFNsumBfFNkR7eg==", + "license": "MIT", + "dependencies": { + "async-done": "^2.0.0", + "async-settle": "^2.0.0", + "now-and-later": "^3.0.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/bare-events": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.0.tgz", + "integrity": "sha512-/E8dDe9dsbLyh2qrZ64PEPadOQ0F4gbl1sUJOrmph7xOiIxfY8vwab/4bFLh4Y88/Hk/ujKcrQKc+ps0mv873A==", + "license": "Apache-2.0", + "optional": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/beeper": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/beeper/-/beeper-2.1.0.tgz", + "integrity": "sha512-85+CcymhlP0jM4fs4ZMiMRl58VthoN9NRdvi+knXiQpP2UggkSre+A9rOZ0c2g2Vh+pEF5ZAlT+k8dsJNoanAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "yoctodelay": "^1.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/bluebird-lst": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.9.tgz", + "integrity": "sha512-7B1Rtx82hjnSD4PGLAjVWeYH3tHAcVUmChh85a3lltKQm6FresXh9ErQo6oAv6CqxttczC3/kEg8SY5NluPuUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "bluebird": "^3.5.5" + } + }, + "node_modules/boolean": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", + "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/bootstrap": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.3.tgz", + "integrity": "sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/twbs" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/bootstrap" + } + ], + "license": "MIT", + "peerDependencies": { + "@popperjs/core": "^2.11.8" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "license": "ISC" + }, + "node_modules/browserslist": { + "version": "4.24.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001669", + "electron-to-chromium": "^1.5.41", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/buffer-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.1.tgz", + "integrity": "sha512-QoV3ptgEaQpvVwbXdSO39iqPQTCxSF7A5U99AxbHYqUdCizL/lH2Z0A2y6nbZucxMEOtNyZfG2s6gsVugGpKkg==", + "license": "MIT", + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/builder-util": { + "version": "25.1.7", + "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-25.1.7.tgz", + "integrity": "sha512-7jPjzBwEGRbwNcep0gGNpLXG9P94VA3CPAZQCzxkFXiV2GMQKlziMbY//rXPI7WKfhsvGgFXjTcXdBEwgXw9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/debug": "^4.1.6", + "7zip-bin": "~5.2.0", + "app-builder-bin": "5.0.0-alpha.10", + "bluebird-lst": "^1.0.9", + "builder-util-runtime": "9.2.10", + "chalk": "^4.1.2", + "cross-spawn": "^7.0.3", + "debug": "^4.3.4", + "fs-extra": "^10.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "is-ci": "^3.0.0", + "js-yaml": "^4.1.0", + "source-map-support": "^0.5.19", + "stat-mode": "^1.0.0", + "temp-file": "^3.4.0" + } + }, + "node_modules/builder-util-runtime": { + "version": "9.2.10", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.10.tgz", + "integrity": "sha512-6p/gfG1RJSQeIbz8TK5aPNkoztgY1q5TgmGFMAXcY8itsGW6Y2ld1ALsZ5UJn8rog7hKF3zHx5iQbNQ8uLcRlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4", + "sax": "^1.2.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/builder-util/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/builder-util/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/builder-util/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/cacache": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz", + "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^2.1.0", + "@npmcli/move-file": "^2.0.0", + "chownr": "^2.0.0", + "fs-minipass": "^2.1.0", + "glob": "^8.0.1", + "infer-owner": "^1.0.4", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "mkdirp": "^1.0.4", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^9.0.0", + "tar": "^6.1.11", + "unique-filename": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/cacache/node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacache/node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cacache/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/cacache/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cacache/node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cache-content-type": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-content-type/-/cache-content-type-1.0.1.tgz", + "integrity": "sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "^2.1.18", + "ylru": "^1.2.0" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.6.0" + } + }, + "node_modules/cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/caching-transform/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001671", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001671.tgz", + "integrity": "sha512-jocyVaSSfXg2faluE6hrWkMgDOiULBMca4QLtDT39hw1YxaIPHWc1CcTCKkPmHgGH6tKji6ZNbMSmUAvENf2/A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/chromium-pickle-js": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz", + "integrity": "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==", + "dev": true, + "license": "MIT" + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/clean-css": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz", + "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/clean-stack": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-4.2.0.tgz", + "integrity": "sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clean-stack/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", + "integrity": "sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==", + "license": "MIT" + }, + "node_modules/cloneable-readable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", + "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "process-nextick-args": "^2.0.0", + "readable-stream": "^2.3.5" + } + }, + "node_modules/cloneable-readable/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "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" + } + }, + "node_modules/cloneable-readable/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/cloneable-readable/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "dev": true, + "license": "ISC", + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", + "dev": true, + "license": "MIT" + }, + "node_modules/compare-version": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz", + "integrity": "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/compress-commons": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.2.tgz", + "integrity": "sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "buffer-crc32": "^0.2.13", + "crc32-stream": "^4.0.2", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT" + }, + "node_modules/config-file-ts": { + "version": "0.2.8-rc1", + "resolved": "https://registry.npmjs.org/config-file-ts/-/config-file-ts-0.2.8-rc1.tgz", + "integrity": "sha512-GtNECbVI82bT4RiDIzBSVuTKoSHufnU7Ce7/42bkWZJZFLjmDF2WBpVsvRkhKCfKBnTBb3qZrBwPpFBU/Myvhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob": "^10.3.12", + "typescript": "^5.4.3" + } + }, + "node_modules/config-file-ts/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/config-file-ts/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/config-file-ts/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/console-grid": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/console-grid/-/console-grid-2.2.2.tgz", + "integrity": "sha512-ohlgXexdDTKLNsZz7DSJuCAwmRc8omSS61txOk39W3NOthgKGr1a1jJpZ5BCQe4PlrwMw01OvPQ1Bl3G7Y/uFg==", + "dev": true, + "license": "MIT" + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "license": "MIT" + }, + "node_modules/cookies": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.9.1.tgz", + "integrity": "sha512-TG2hpqe4ELx54QER/S3HQ9SRVnQnGBtKUz5bLQWtYAQ+o6GpgMs6sYUvaiJjVxb+UXwhRhAEP3m7LbsIZ77Hmw==", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "keygrip": "~1.1.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/copy-props": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-4.0.0.tgz", + "integrity": "sha512-bVWtw1wQLzzKiYROtvNlbJgxgBYt2bMJpkCbKmXM3xyijvcjjWXEk5nyrrT3bgJ7ODb19ZohE2T0Y3FgNPyoTw==", + "license": "MIT", + "dependencies": { + "each-props": "^3.0.0", + "is-plain-object": "^5.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "license": "MIT" + }, + "node_modules/crc": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", + "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "buffer": "^5.1.0" + } + }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/crc32-stream": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.3.tgz", + "integrity": "sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "crc-32": "^1.2.0", + "readable-stream": "^3.4.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz", + "integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.4", + "source-map": "^0.6.1", + "source-map-resolve": "^0.6.0" + } + }, + "node_modules/d": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", + "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==", + "license": "ISC", + "dependencies": { + "es5-ext": "^0.10.64", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/debug-fabulous": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-1.1.0.tgz", + "integrity": "sha512-GZqvGIgKNlUnHUPQhepnUZFIMoi3dgZKQBzKDeL2g7oJF9SNAji/AAu36dusFUas0O+pae74lNeoIPHqXWDkLg==", + "license": "MIT", + "dependencies": { + "debug": "3.X", + "memoizee": "0.4.X", + "object-assign": "4.X" + } + }, + "node_modules/debug-fabulous/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decode-uri-component": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/default-require-extensions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.1.tgz", + "integrity": "sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "strip-bom": "^4.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defaults/node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/del": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/del/-/del-7.1.0.tgz", + "integrity": "sha512-v2KyNk7efxhlyHpjEvfyxaAihKKK0nWCuf6ZtqZcFFpQRG0bJ12Qsr0RpvsICMjAAZ8DOVCxrlqpxISlMHC4Kg==", + "license": "MIT", + "dependencies": { + "globby": "^13.1.2", + "graceful-fs": "^4.2.10", + "is-glob": "^4.0.3", + "is-path-cwd": "^3.0.0", + "is-path-inside": "^4.0.0", + "p-map": "^5.5.0", + "rimraf": "^3.0.2", + "slash": "^4.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-newline": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", + "integrity": "sha512-CwffZFvlJffUg9zZA0uqrjQayUTC8ob94pnr5sFwaVv3IOmkfUHcWH+jXaQK3askE51Cqe8/9Ql/0uXNwqZ8Zg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dir-compare": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-4.2.0.tgz", + "integrity": "sha512-2xMCmOoMrdQIPHdsTawECdNPwlVFB9zGcz3kuhmBO6U3oU+UQjsue0i8ayLKpgBcm+hcXPMVSGUN9d+pvJ6+VQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimatch": "^3.0.5", + "p-limit": "^3.1.0 " + } + }, + "node_modules/dir-compare/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/dir-compare/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dmg-builder": { + "version": "25.1.8", + "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-25.1.8.tgz", + "integrity": "sha512-NoXo6Liy2heSklTI5OIZbCgXC1RzrDQsZkeEwXhdOro3FT1VBOvbubvscdPnjVuQ4AMwwv61oaH96AbiYg9EnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "app-builder-lib": "25.1.8", + "builder-util": "25.1.7", + "builder-util-runtime": "9.2.10", + "fs-extra": "^10.1.0", + "iconv-lite": "^0.6.2", + "js-yaml": "^4.1.0" + }, + "optionalDependencies": { + "dmg-license": "^1.0.11" + } + }, + "node_modules/dmg-builder/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/dmg-builder/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/dmg-builder/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/dmg-license": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/dmg-license/-/dmg-license-1.0.11.tgz", + "integrity": "sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q==", + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "@types/plist": "^3.0.1", + "@types/verror": "^1.10.3", + "ajv": "^6.10.0", + "crc": "^3.8.0", + "iconv-corefoundation": "^1.1.7", + "plist": "^3.0.4", + "smart-buffer": "^4.0.2", + "verror": "^1.10.0" + }, + "bin": { + "dmg-license": "bin/dmg-license.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dotenv-expand": { + "version": "11.0.6", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-11.0.6.tgz", + "integrity": "sha512-8NHi73otpWsZGBSZwwknTXS5pqMOrk9+Ssrna8xCaxkzEpU9OTf9R5ArQGVw03//Zmk9MOwLPng9WwndvpAJ5g==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dotenv": "^16.4.4" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "node_modules/duplexify/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "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" + } + }, + "node_modules/duplexify/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/duplexify/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/each-props": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/each-props/-/each-props-3.0.0.tgz", + "integrity": "sha512-IYf1hpuWrdzse/s/YJOrFmU15lyhSzxelNVAHTEG3DtP4QsLTWZUzcUL3HMXmKQxXpa4EIrBPpwRgj0aehdvAw==", + "license": "MIT", + "dependencies": { + "is-plain-object": "^5.0.0", + "object.defaults": "^1.1.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true, + "license": "MIT" + }, + "node_modules/eight-colors": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/eight-colors/-/eight-colors-1.3.1.tgz", + "integrity": "sha512-7nXPYDeKh6DgJDR/mpt2G7N/hCNSGwwoPVmoI3+4TEwOb07VFN1WMPG0DFf6nMEjrkgdj8Og7l7IaEEk3VE6Zg==", + "dev": true, + "license": "MIT" + }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron": { + "version": "32.2.2", + "resolved": "https://registry.npmjs.org/electron/-/electron-32.2.2.tgz", + "integrity": "sha512-c7TRE42JcgEmJ4elJyCdKk/2os0UX7YMkRDeXBkxFEoM34iX1/2x+c5T9PgeroKz8FEG7omRU5TvjulqVtXvdw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@electron/get": "^2.0.0", + "@types/node": "^20.9.0", + "extract-zip": "^2.0.1" + }, + "bin": { + "electron": "cli.js" + }, + "engines": { + "node": ">= 12.20.55" + } + }, + "node_modules/electron-builder": { + "version": "25.1.8", + "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-25.1.8.tgz", + "integrity": "sha512-poRgAtUHHOnlzZnc9PK4nzG53xh74wj2Jy7jkTrqZ0MWPoHGh1M2+C//hGeYdA+4K8w4yiVCNYoLXF7ySj2Wig==", + "dev": true, + "license": "MIT", + "dependencies": { + "app-builder-lib": "25.1.8", + "builder-util": "25.1.7", + "builder-util-runtime": "9.2.10", + "chalk": "^4.1.2", + "dmg-builder": "25.1.8", + "fs-extra": "^10.1.0", + "is-ci": "^3.0.0", + "lazy-val": "^1.0.5", + "simple-update-notifier": "2.0.0", + "yargs": "^17.6.2" + }, + "bin": { + "electron-builder": "cli.js", + "install-app-deps": "install-app-deps.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/electron-builder-squirrel-windows": { + "version": "25.1.8", + "resolved": "https://registry.npmjs.org/electron-builder-squirrel-windows/-/electron-builder-squirrel-windows-25.1.8.tgz", + "integrity": "sha512-2ntkJ+9+0GFP6nAISiMabKt6eqBB0kX1QqHNWFWAXgi0VULKGisM46luRFpIBiU3u/TDmhZMM8tzvo2Abn3ayg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "app-builder-lib": "25.1.8", + "archiver": "^5.3.1", + "builder-util": "25.1.7", + "fs-extra": "^10.1.0" + } + }, + "node_modules/electron-builder-squirrel-windows/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/electron-builder-squirrel-windows/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/electron-builder-squirrel-windows/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/electron-builder/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/electron-builder/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/electron-builder/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/electron-playwright-helpers": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/electron-playwright-helpers/-/electron-playwright-helpers-1.7.1.tgz", + "integrity": "sha512-S9mo7LfpERgub2WIuYVPpib4XKFeAqBP+mxYf5Bv7E0B5GUB+LUbSj6Fpu39h18Ar635Nf9nQYTmypjuvaYJng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@electron/asar": "^3.2.4" + } + }, + "node_modules/electron-publish": { + "version": "25.1.7", + "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-25.1.7.tgz", + "integrity": "sha512-+jbTkR9m39eDBMP4gfbqglDd6UvBC7RLh5Y0MhFSsc6UkGHj9Vj9TWobxevHYMMqmoujL11ZLjfPpMX+Pt6YEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/fs-extra": "^9.0.11", + "builder-util": "25.1.7", + "builder-util-runtime": "9.2.10", + "chalk": "^4.1.2", + "fs-extra": "^10.1.0", + "lazy-val": "^1.0.5", + "mime": "^2.5.2" + } + }, + "node_modules/electron-publish/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/electron-publish/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/electron-publish/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.47", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.47.tgz", + "integrity": "sha512-zS5Yer0MOYw4rtK2iq43cJagHZ8sXN0jDHDKzB+86gSBSAI4v07S97mcq+Gs2vclAxSh1j7vOAHxSVgduiiuVQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/electron/node_modules/@types/node": { + "version": "20.17.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.1.tgz", + "integrity": "sha512-j2VlPv1NnwPJbaCNv69FO/1z4lId0QmGvpT41YxitRtWlg96g/j8qcv2RKsLKe2F6OJgyXhupN1Xo17b2m139Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es5-ext": { + "version": "0.10.64", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", + "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", + "hasInstallScript": true, + "license": "ISC", + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "esniff": "^2.0.1", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "license": "MIT", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-symbol": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz", + "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==", + "license": "ISC", + "dependencies": { + "d": "^1.0.2", + "ext": "^1.7.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "license": "ISC", + "dependencies": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true, + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/esniff": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", + "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", + "license": "ISC", + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "event-emitter": "^0.3.5", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "license": "MIT", + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "node_modules/expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==", + "license": "MIT", + "dependencies": { + "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", + "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "license": "ISC", + "dependencies": { + "type": "^2.7.2" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "license": "MIT", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/extsprintf": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz", + "integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "optional": true + }, + "node_modules/fancy-log": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", + "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-gray": "^0.1.1", + "color-support": "^1.1.3", + "parse-node-version": "^1.0.0", + "time-stamp": "^1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz", + "integrity": "sha512-hKKNajm46uNmTlhHSyZkmToAc56uZJwYq7yrciZjqOxnlfQwERDQJmHPUp7m1m9wx8vgOe8IaCKZ5Kv2k1DdCQ==", + "license": "MIT", + "dependencies": { + "fastest-levenshtein": "^1.0.7" + } + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "license": "MIT", + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "license": "MIT", + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/find-cache-dir/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/findup-sync": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-5.0.0.tgz", + "integrity": "sha512-MzwXju70AuyflbgeOhzvQWAvvQdo1XL0A9bVvlXsYcFEBM87WR4OakL4OfZq+QRmr+duJubio+UtNQCPsVESzQ==", + "license": "MIT", + "dependencies": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.3", + "micromatch": "^4.0.4", + "resolve-dir": "^1.0.1" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/fined": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fined/-/fined-2.0.0.tgz", + "integrity": "sha512-OFRzsL6ZMHz5s0JrsEr+TpdGNCtrVtnuG3x1yzGNiQHT0yaDnXAj8V/lWcpJVrnoDpcwXcASxAZYbuXda2Y82A==", + "license": "MIT", + "dependencies": { + "expand-tilde": "^2.0.2", + "is-plain-object": "^5.0.0", + "object.defaults": "^1.1.0", + "object.pick": "^1.3.0", + "parse-filepath": "^1.0.2" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/flagged-respawn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-2.0.0.tgz", + "integrity": "sha512-Gq/a6YCi8zexmGHMuJwahTGzXlAZAOsbCVKduWXC6TlLCjjFRlExMJc4GC2NYPYZ0r/brw9P7CpRgQmlPVeOoA==", + "license": "MIT", + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "node_modules/flush-write-stream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "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" + } + }, + "node_modules/flush-write-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/flush-write-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg==", + "license": "MIT", + "dependencies": { + "for-in": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/foreground-child": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", + "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/form-data": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fromentries": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-mkdirp-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-2.0.1.tgz", + "integrity": "sha512-UTOY+59K6IA94tec8Wjqm0FSh5OVudGNB0NL/P6fB3HiE3bYOY3VYBGijsnOHNkQSwC1FKkU77pmq7xp9CskLw==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.8", + "streamx": "^2.12.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gauge": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", + "deprecated": "This package is no longer supported.", + "dev": true, + "license": "ISC", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^3.0.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/gauge/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-stream": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-8.0.2.tgz", + "integrity": "sha512-R8z6eTB55t3QeZMmU1C+Gv+t5UnNRkA55c5yo67fAVfxODxieTwsjNG7utxS/73NdP1NbDgCrhVEg2h00y4fFw==", + "license": "MIT", + "dependencies": { + "@gulpjs/to-absolute-glob": "^4.0.0", + "anymatch": "^3.1.3", + "fastq": "^1.13.0", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "is-negated-glob": "^1.0.0", + "normalize-path": "^3.0.0", + "streamx": "^2.12.5" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-stream/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-watcher": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-6.0.0.tgz", + "integrity": "sha512-wGM28Ehmcnk2NqRORXFOTOR064L4imSw3EeOqU5bIwUf62eXGwg89WivH6VMahL8zlQHeodzvHpXplrqzrz3Nw==", + "license": "MIT", + "dependencies": { + "async-done": "^2.0.0", + "chokidar": "^3.5.3" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/global-agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", + "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "boolean": "^3.0.1", + "es6-error": "^4.1.1", + "matcher": "^3.0.0", + "roarr": "^2.15.3", + "semver": "^7.3.2", + "serialize-error": "^7.0.1" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/global-agent/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "license": "MIT", + "dependencies": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==", + "license": "MIT", + "dependencies": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", + "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", + "license": "MIT", + "dependencies": { + "dir-glob": "^3.0.1", + "fast-glob": "^3.3.0", + "ignore": "^5.2.4", + "merge2": "^1.4.1", + "slash": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glogg": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/glogg/-/glogg-2.2.0.tgz", + "integrity": "sha512-eWv1ds/zAlz+M1ioHsyKJomfY7jbDDPpwSkv14KQj89bycx1nvK5/2Cj/T9g7kzJcX5Bc7Yv22FjfBZS/jl94A==", + "license": "MIT", + "dependencies": { + "sparkles": "^2.1.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/gulp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/gulp/-/gulp-5.0.0.tgz", + "integrity": "sha512-S8Z8066SSileaYw1S2N1I64IUc/myI2bqe2ihOBzO6+nKpvNSg7ZcWJt/AwF8LC/NVN+/QZ560Cb/5OPsyhkhg==", + "license": "MIT", + "dependencies": { + "glob-watcher": "^6.0.0", + "gulp-cli": "^3.0.0", + "undertaker": "^2.0.0", + "vinyl-fs": "^4.0.0" + }, + "bin": { + "gulp": "bin/gulp.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/gulp-clean-css": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/gulp-clean-css/-/gulp-clean-css-4.3.0.tgz", + "integrity": "sha512-mGyeT3qqFXTy61j0zOIciS4MkYziF2U594t2Vs9rUnpkEHqfu6aDITMp8xOvZcvdX61Uz3y1mVERRYmjzQF5fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "clean-css": "4.2.3", + "plugin-error": "1.0.1", + "through2": "3.0.1", + "vinyl-sourcemaps-apply": "0.2.1" + } + }, + "node_modules/gulp-cli": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-3.0.0.tgz", + "integrity": "sha512-RtMIitkT8DEMZZygHK2vEuLPqLPAFB4sntSxg4NoDta7ciwGZ18l7JuhCTiS5deOJi2IoK0btE+hs6R4sfj7AA==", + "license": "MIT", + "dependencies": { + "@gulpjs/messages": "^1.1.0", + "chalk": "^4.1.2", + "copy-props": "^4.0.0", + "gulplog": "^2.2.0", + "interpret": "^3.1.1", + "liftoff": "^5.0.0", + "mute-stdout": "^2.0.0", + "replace-homedir": "^2.0.0", + "semver-greatest-satisfied-range": "^2.0.0", + "string-width": "^4.2.3", + "v8flags": "^4.0.0", + "yargs": "^16.2.0" + }, + "bin": { + "gulp": "bin/gulp.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/gulp-cli/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/gulp-cli/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gulp-htmlhint": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/gulp-htmlhint/-/gulp-htmlhint-4.0.2.tgz", + "integrity": "sha512-ca65RbcptmVqmmZHvzMUkd5JeV7k9KagtKECDGKzLGz3061e1wS8OsyYy73WDAC4k73drypRxURWaCjAKX/3Lw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.1", + "beeper": "^2.0.0", + "fancy-log": "^1.3.2", + "htmlhint": "^1.1.2", + "plugin-error": "^1.0.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.1", + "through2": "^3.0.1", + "vinyl": "^2.2.1" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "htmlhint": "^0.14.0 || ^1.0.0" + } + }, + "node_modules/gulp-sourcemaps": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-3.0.0.tgz", + "integrity": "sha512-RqvUckJkuYqy4VaIH60RMal4ZtG0IbQ6PXMNkNsshEGJ9cldUPRb/YCgboYae+CLAs1HQNb4ADTKCx65HInquQ==", + "license": "ISC", + "dependencies": { + "@gulp-sourcemaps/identity-map": "^2.0.1", + "@gulp-sourcemaps/map-sources": "^1.0.0", + "acorn": "^6.4.1", + "convert-source-map": "^1.0.0", + "css": "^3.0.0", + "debug-fabulous": "^1.0.0", + "detect-newline": "^2.0.0", + "graceful-fs": "^4.0.0", + "source-map": "^0.6.0", + "strip-bom-string": "^1.0.0", + "through2": "^2.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/gulp-sourcemaps/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "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" + } + }, + "node_modules/gulp-sourcemaps/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/gulp-sourcemaps/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/gulp-sourcemaps/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "license": "MIT", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/gulp-typescript": { + "version": "6.0.0-alpha.1", + "resolved": "https://registry.npmjs.org/gulp-typescript/-/gulp-typescript-6.0.0-alpha.1.tgz", + "integrity": "sha512-KoT0TTfjfT7w3JItHkgFH1T/zK4oXWC+a8xxKfniRfVcA0Fa1bKrIhztYelYmb+95RB80OLMBreknYkdwzdi2Q==", + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.1", + "plugin-error": "^1.0.1", + "source-map": "^0.7.3", + "through2": "^3.0.1", + "vinyl": "^2.2.0", + "vinyl-fs": "^3.0.3" + }, + "engines": { + "node": ">= 8" + }, + "peerDependencies": { + "typescript": "~2.7.1 || >=2.8.0-dev || >=2.9.0-dev || ~3.0.0 || >=3.0.0-dev || >=3.1.0-dev || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.7.0-dev " + } + }, + "node_modules/gulp-typescript/node_modules/fs-mkdirp-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", + "integrity": "sha512-+vSd9frUnapVC2RZYfL3FCB2p3g4TBhaUmrsWlSudsGdnxIuUvBB2QM1VZeBtc49QFwrp+wQLrDs3+xxDgI5gQ==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.11", + "through2": "^2.0.3" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-typescript/node_modules/fs-mkdirp-stream/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "license": "MIT", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/gulp-typescript/node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", + "license": "ISC", + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/gulp-typescript/node_modules/glob-stream": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", + "integrity": "sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw==", + "license": "MIT", + "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" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-typescript/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-typescript/node_modules/lead": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", + "integrity": "sha512-IpSVCk9AYvLHo5ctcIXxOBpMWUe+4TKN3VPWAKUbJikkmsGp0VrSM8IttVc32D6J4WUsiPE6aEFRNmIoF/gdow==", + "license": "MIT", + "dependencies": { + "flush-write-stream": "^1.0.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-typescript/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", + "license": "MIT", + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-typescript/node_modules/now-and-later": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", + "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", + "license": "MIT", + "dependencies": { + "once": "^1.3.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-typescript/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "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" + } + }, + "node_modules/gulp-typescript/node_modules/resolve-options": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", + "integrity": "sha512-NYDgziiroVeDC29xq7bp/CacZERYsA9bXYd1ZmcJlF3BcrZv5pTb4NG7SjdyKDnXZ84aC4vo2u6sNKIA1LCu/A==", + "license": "MIT", + "dependencies": { + "value-or-function": "^3.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-typescript/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/gulp-typescript/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 8" + } + }, + "node_modules/gulp-typescript/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/gulp-typescript/node_modules/to-through": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", + "integrity": "sha512-+QIz37Ly7acM4EMdw2PRN389OneM5+d844tirkGp4dPKzI5OE72V9OsbFp+CIYJDahZ41ZV05hNtcPAQUAm9/Q==", + "license": "MIT", + "dependencies": { + "through2": "^2.0.3" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-typescript/node_modules/to-through/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "license": "MIT", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/gulp-typescript/node_modules/value-or-function": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", + "integrity": "sha512-jdBB2FrWvQC/pnPtIqcLsMaQgjhdb6B7tk1MMyTKapox+tQZbdRP4uLxu/JY0t7fbfDCUMnuelzEYv5GsxHhdg==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-typescript/node_modules/vinyl-fs": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", + "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", + "license": "MIT", + "dependencies": { + "fs-mkdirp-stream": "^1.0.0", + "glob-stream": "^6.1.0", + "graceful-fs": "^4.0.0", + "is-valid-glob": "^1.0.0", + "lazystream": "^1.0.0", + "lead": "^1.0.0", + "object.assign": "^4.0.4", + "pumpify": "^1.3.5", + "readable-stream": "^2.3.3", + "remove-bom-buffer": "^3.0.0", + "remove-bom-stream": "^1.2.0", + "resolve-options": "^1.1.0", + "through2": "^2.0.0", + "to-through": "^2.0.0", + "value-or-function": "^3.0.0", + "vinyl": "^2.0.0", + "vinyl-sourcemap": "^1.1.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulp-typescript/node_modules/vinyl-fs/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "license": "MIT", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/gulp-typescript/node_modules/vinyl-sourcemap": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", + "integrity": "sha512-NiibMgt6VJGJmyw7vtzhctDcfKch4e4n9TBeoWlirb7FMg9/1Ov9k+A5ZRAtywBpRPiyECvQRQllYM8dECegVA==", + "license": "MIT", + "dependencies": { + "append-buffer": "^1.0.2", + "convert-source-map": "^1.5.0", + "graceful-fs": "^4.1.6", + "normalize-path": "^2.1.1", + "now-and-later": "^2.0.0", + "remove-bom-buffer": "^3.0.0", + "vinyl": "^2.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/gulplog": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-2.2.0.tgz", + "integrity": "sha512-V2FaKiOhpR3DRXZuYdRLn/qiY0yI5XmqbTKrYbdemJ+xOh2d2MOweI/XFgMzd/9+1twdvMwllnZbWZNJ+BOm4A==", + "license": "MIT", + "dependencies": { + "glogg": "^2.2.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/hasha": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "license": "MIT", + "dependencies": { + "parse-passwd": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/htmlhint": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/htmlhint/-/htmlhint-1.1.4.tgz", + "integrity": "sha512-tSKPefhIaaWDk/vKxAOQbN+QwZmDeJCq3bZZGbJMoMQAfTjepudC+MkuT9MOBbuQI3dLLzDWbmU7fLV3JASC7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "async": "3.2.3", + "chalk": "^4.1.2", + "commander": "^9.1.0", + "glob": "^7.2.0", + "is-glob": "^4.0.3", + "node-fetch": "^2.6.2", + "strip-json-comments": "3.1.0", + "xml": "1.0.1" + }, + "bin": { + "htmlhint": "bin/htmlhint" + } + }, + "node_modules/htmlhint/node_modules/async": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", + "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==", + "dev": true, + "license": "MIT" + }, + "node_modules/htmlhint/node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/htmlhint/node_modules/strip-json-comments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.0.tgz", + "integrity": "sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/http-assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/http-assert/-/http-assert-1.5.0.tgz", + "integrity": "sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-equal": "~1.0.1", + "http-errors": "~1.8.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/http-errors": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", + "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-errors/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.0.0" + } + }, + "node_modules/iconv-corefoundation": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/iconv-corefoundation/-/iconv-corefoundation-1.1.7.tgz", + "integrity": "sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==", + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "cli-truncate": "^2.1.0", + "node-addon-api": "^1.6.3" + }, + "engines": { + "node": "^8.11.2 || >=10" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true, + "license": "ISC" + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "license": "MIT", + "dependencies": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "license": "MIT" + }, + "node_modules/is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extendable/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-negated-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", + "integrity": "sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-path-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-3.0.0.tgz", + "integrity": "sha512-kyiNFFLU0Ampr6SDZitD/DwUo4Zs1nSdnygUBqsu3LooL00Qvb5j+UnvApUn/TTj1J3OuE6BTdQ5rudKmU2ZaA==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-path-inside": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz", + "integrity": "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "license": "MIT" + }, + "node_modules/is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "license": "MIT", + "dependencies": { + "is-unc-path": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "license": "MIT", + "dependencies": { + "unc-path-regex": "^0.1.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", + "license": "MIT" + }, + "node_modules/is-valid-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", + "integrity": "sha512-AhiROmoEFDSsjx8hW+5sGwgKVIORcXnrlAx/R0ZSeaPw70Vw0CqkGBBhHGL58Uox2eXnU1AnvXJl1XlyedO5bA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/isbinaryfile": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.4.tgz", + "integrity": "sha512-YKBKVkKhty7s8rxddb40oOkuP0NbaeXrQvLin6QMHL7Ypiy2RW9LwOVrVgZRyOrhQlayMd9t+D8yDy8MKFTSDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-hook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", + "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "append-transform": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-processinfo": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz", + "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==", + "dev": true, + "license": "ISC", + "dependencies": { + "archy": "^1.0.0", + "cross-spawn": "^7.0.3", + "istanbul-lib-coverage": "^3.2.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^8.3.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-processinfo/node_modules/p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jake": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", + "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jake/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/jake/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/jquery": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", + "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==", + "license": "MIT" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "license": "MIT" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/keygrip": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz", + "integrity": "sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tsscmp": "1.0.6" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/koa": { + "version": "2.15.3", + "resolved": "https://registry.npmjs.org/koa/-/koa-2.15.3.tgz", + "integrity": "sha512-j/8tY9j5t+GVMLeioLaxweJiKUayFhlGqNTzf2ZGwL0ZCQijd2RLHK0SLW5Tsko8YyyqCZC2cojIb0/s62qTAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "^1.3.5", + "cache-content-type": "^1.0.0", + "content-disposition": "~0.5.2", + "content-type": "^1.0.4", + "cookies": "~0.9.0", + "debug": "^4.3.2", + "delegates": "^1.0.0", + "depd": "^2.0.0", + "destroy": "^1.0.4", + "encodeurl": "^1.0.2", + "escape-html": "^1.0.3", + "fresh": "~0.5.2", + "http-assert": "^1.3.0", + "http-errors": "^1.6.3", + "is-generator-function": "^1.0.7", + "koa-compose": "^4.1.0", + "koa-convert": "^2.0.0", + "on-finished": "^2.3.0", + "only": "~0.0.2", + "parseurl": "^1.3.2", + "statuses": "^1.5.0", + "type-is": "^1.6.16", + "vary": "^1.1.2" + }, + "engines": { + "node": "^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4" + } + }, + "node_modules/koa-compose": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/koa-compose/-/koa-compose-4.1.0.tgz", + "integrity": "sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==", + "dev": true, + "license": "MIT" + }, + "node_modules/koa-convert": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/koa-convert/-/koa-convert-2.0.0.tgz", + "integrity": "sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA==", + "dev": true, + "license": "MIT", + "dependencies": { + "co": "^4.6.0", + "koa-compose": "^4.1.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/koa-static-resolver": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/koa-static-resolver/-/koa-static-resolver-1.0.6.tgz", + "integrity": "sha512-ZX5RshSzH8nFn05/vUNQzqw32nEigsPa67AVUr6ZuQxuGdnCcTLcdgr4C81+YbJjpgqKHfacMBd7NmJIbj7fXw==", + "dev": true, + "license": "MIT" + }, + "node_modules/last-run": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/last-run/-/last-run-2.0.0.tgz", + "integrity": "sha512-j+y6WhTLN4Itnf9j5ZQos1BGPCS8DAwmgMroR3OzfxAsBxam0hMw7J8M3KqZl0pLQJ1jNnwIexg5DYpC/ctwEQ==", + "license": "MIT", + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/lazy-val": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz", + "integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/lazystream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "license": "MIT", + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, + "node_modules/lazystream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "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" + } + }, + "node_modules/lazystream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/lazystream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/lead": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/lead/-/lead-4.0.0.tgz", + "integrity": "sha512-DpMa59o5uGUWWjruMp71e6knmwKU3jRBBn1kjuLWN9EeIOxNeSAwvHf03WIl8g/ZMR2oSQC9ej3yeLBwdDc/pg==", + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/liftoff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-5.0.0.tgz", + "integrity": "sha512-a5BQjbCHnB+cy+gsro8lXJ4kZluzOijzJ1UVVfyJYZC+IP2pLv1h4+aysQeKuTmyO8NAqfyQAk4HWaP/HjcKTg==", + "license": "MIT", + "dependencies": { + "extend": "^3.0.2", + "findup-sync": "^5.0.0", + "fined": "^2.0.0", + "flagged-respawn": "^2.0.0", + "is-plain-object": "^5.0.0", + "rechoir": "^0.8.0", + "resolve": "^1.20.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/lodash.difference": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/lodash.union": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", + "integrity": "sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lru-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", + "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", + "license": "MIT", + "dependencies": { + "es5-ext": "~0.10.2" + } + }, + "node_modules/lz-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lz-utils/-/lz-utils-2.1.0.tgz", + "integrity": "sha512-CMkfimAypidTtWjNDxY8a1bc1mJdyEh04V2FfEQ5Zh8Nx4v7k850EYa+dOWGn9hKG5xOyHP5MkuduAZCTHRvJw==", + "dev": true, + "license": "MIT" + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true, + "license": "ISC" + }, + "node_modules/make-fetch-happen": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz", + "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==", + "dev": true, + "license": "ISC", + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^16.1.0", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^2.0.3", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^9.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/make-fetch-happen/node_modules/http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/make-fetch-happen/node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/make-fetch-happen/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/matcher": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "escape-string-regexp": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memoizee": { + "version": "0.4.17", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.17.tgz", + "integrity": "sha512-DGqD7Hjpi/1or4F/aYAspXKNm5Yili0QDAFAY4QYvpqpgiY6+1jOfqpmByzjxbWd/T9mChbCArXAbDAsTm5oXA==", + "license": "ISC", + "dependencies": { + "d": "^1.0.2", + "es5-ext": "^0.10.64", + "es6-weak-map": "^2.0.3", + "event-emitter": "^0.3.5", + "is-promise": "^2.2.2", + "lru-queue": "^0.1.0", + "next-tick": "^1.1.0", + "timers-ext": "^0.1.7" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz", + "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-fetch": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz", + "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.1.6", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.3.tgz", + "integrity": "sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A==", + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/mocha/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/mocha/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/mocha/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/monocart-coverage-reports": { + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/monocart-coverage-reports/-/monocart-coverage-reports-2.11.1.tgz", + "integrity": "sha512-h4rc2i/A/aKuQ66EpswJ4y/dxXO6GDt0yuU9dt4MUsbbEXD1EoldFWvHszdo8M2dwVbAjDcAzHrQKBCs2ydfzA==", + "dev": true, + "license": "MIT", + "workspaces": [ + "test" + ], + "dependencies": { + "acorn": "^8.12.1", + "acorn-loose": "^8.4.0", + "acorn-walk": "^8.3.4", + "commander": "^12.1.0", + "console-grid": "^2.2.2", + "eight-colors": "^1.3.1", + "foreground-child": "^3.3.0", + "istanbul-lib-coverage": "^3.2.2", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.1.7", + "lz-utils": "^2.1.0", + "monocart-locator": "^1.0.2" + }, + "bin": { + "mcr": "lib/cli.js" + } + }, + "node_modules/monocart-coverage-reports/node_modules/acorn": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.13.0.tgz", + "integrity": "sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/monocart-coverage-reports/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/monocart-locator": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/monocart-locator/-/monocart-locator-1.0.2.tgz", + "integrity": "sha512-v8W5hJLcWMIxLCcSi/MHh+VeefI+ycFmGz23Froer9QzWjrbg4J3gFJBuI/T1VLNoYxF47bVPPxq8ZlNX4gVCw==", + "dev": true, + "license": "MIT" + }, + "node_modules/monocart-reporter": { + "version": "2.9.7", + "resolved": "https://registry.npmjs.org/monocart-reporter/-/monocart-reporter-2.9.7.tgz", + "integrity": "sha512-3GeabQMGQGLN/qnqGOp4uaWabnpxkWgAzlEa8wGbXKrlN1fvslbILhKKybX+NxDuigluf8Qx5swTTjZfvWk0vg==", + "dev": true, + "license": "MIT", + "dependencies": { + "console-grid": "^2.2.2", + "eight-colors": "^1.3.1", + "koa": "^2.15.3", + "koa-static-resolver": "^1.0.6", + "lz-utils": "^2.1.0", + "monocart-coverage-reports": "^2.11.1", + "monocart-locator": "^1.0.2", + "nodemailer": "^6.9.15" + }, + "bin": { + "monocart": "lib/cli.js" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/mute-stdout": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-2.0.0.tgz", + "integrity": "sha512-32GSKM3Wyc8dg/p39lWPKYu8zci9mJFzV1Np9Of0ZEpe6Fhssn/FbI7ywAMd40uX+p3ZKh3T5EeCFv81qS3HmQ==", + "license": "MIT", + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", + "license": "ISC" + }, + "node_modules/node-abi": { + "version": "3.71.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.71.0.tgz", + "integrity": "sha512-SZ40vRiy/+wRTf21hxkkEjPJZpARzUMVcJoQse2EF8qkUWbbO2z7vd5oA/H6bVH6SZQ5STGcu0KRDS7biNRfxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-abi/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-addon-api": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", + "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/node-api-version": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/node-api-version/-/node-api-version-0.2.0.tgz", + "integrity": "sha512-fthTTsi8CxaBXMaBAD7ST2uylwvsnYxh2PfaScwpMhos6KlSFajXQPcM4ogNE1q2s3Lbz9GCGqeIHC+C6OZnKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + } + }, + "node_modules/node-api-version/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-gyp": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.4.1.tgz", + "integrity": "sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^7.1.4", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^10.0.3", + "nopt": "^6.0.0", + "npmlog": "^6.0.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^12.13 || ^14.13 || >=16" + } + }, + "node_modules/node-gyp/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "process-on-spawn": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/node-releases": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true, + "license": "MIT" + }, + "node_modules/nodemailer": { + "version": "6.9.15", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.15.tgz", + "integrity": "sha512-AHf04ySLC6CIfuRtRiEYtGEXgRfa6INgWGluDhnxTZhHSKvrBu7lc1VVchQ0d8nPc4cFaZoPq8vkyNoZr0TpGQ==", + "dev": true, + "license": "MIT-0", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/nopt": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", + "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", + "dev": true, + "license": "ISC", + "dependencies": { + "abbrev": "^1.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/now-and-later": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-3.0.0.tgz", + "integrity": "sha512-pGO4pzSdaxhWTGkfSfHx3hVzJVslFPwBp2Myq9MYN/ChfJZF87ochMAXnvz6/58RJSf5ik2q9tXprBBrk2cpcg==", + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/npmlog": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", + "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", + "deprecated": "This package is no longer supported.", + "dev": true, + "license": "ISC", + "dependencies": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.3", + "set-blocking": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/nyc": { + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-17.1.0.tgz", + "integrity": "sha512-U42vQ4czpKa0QdI1hu950XuNhYqgoM+ZF1HT+VuUHL9hPfDPVvNQyltmMqdE9bUHMVa+8yNbc3QKTj8zQhlVxQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^3.3.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^6.0.2", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" + }, + "bin": { + "nyc": "bin/nyc.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/nyc/node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/nyc/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/nyc/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nyc/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nyc/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/nyc/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/nyc/node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "license": "MIT", + "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.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.defaults": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", + "integrity": "sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA==", + "license": "MIT", + "dependencies": { + "array-each": "^1.0.1", + "array-slice": "^1.0.0", + "for-own": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/only": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/only/-/only-0.0.2.tgz", + "integrity": "sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ==", + "dev": true + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ordered-read-streams": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", + "integrity": "sha512-Z87aSjx3r5c0ZB7bcJqIgIRX5bxR7A4aSzvIbaxd0oTkWBCOoKfuGHiKj60CHVUgg1Phm5yMZzBdt8XqRs73Mw==", + "license": "MIT", + "dependencies": { "readable-stream": "^2.0.1" - } - } - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - } - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "terser-webpack-plugin": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", - "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", - "dev": true, - "requires": { - "cacache": "^12.0.2", - "find-cache-dir": "^2.1.0", - "is-wsl": "^1.1.0", - "schema-utils": "^1.0.0", - "serialize-javascript": "^4.0.0", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - } - } - } - }, - "webpack-cli": { - "version": "3.3.12", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.12.tgz", - "integrity": "sha512-NVWBaz9k839ZH/sinurM+HcDvJOTXwSjYp1ku+5XKeOC03z8v5QitnK/x+lAxGXFyhdayoIf/GOpv85z3/xPag==", - "dev": true, - "requires": { - "chalk": "^2.4.2", - "cross-spawn": "^6.0.5", - "enhanced-resolve": "^4.1.1", - "findup-sync": "^3.0.0", - "global-modules": "^2.0.0", - "import-local": "^2.0.0", - "interpret": "^1.4.0", - "loader-utils": "^1.4.0", - "supports-color": "^6.1.0", - "v8-compile-cache": "^2.1.1", - "yargs": "^13.3.2" - }, - "dependencies": { - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "dev": true, - "requires": { - "global-prefix": "^3.0.0" - } - }, - "global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "dev": true, - "requires": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - } - }, - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - } - } - }, - "webpack-dev-middleware": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz", - "integrity": "sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw==", - "dev": true, - "requires": { - "memory-fs": "^0.4.1", - "mime": "^2.4.4", - "mkdirp": "^0.5.1", - "range-parser": "^1.2.1", - "webpack-log": "^2.0.0" - }, - "dependencies": { - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "mime": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", - "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", - "dev": true - }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - } - } - }, - "webpack-dev-server": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz", - "integrity": "sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg==", - "dev": true, - "requires": { - "ansi-html": "0.0.7", - "bonjour": "^3.5.0", - "chokidar": "^2.1.8", - "compression": "^1.7.4", - "connect-history-api-fallback": "^1.6.0", - "debug": "^4.1.1", - "del": "^4.1.1", - "express": "^4.17.1", - "html-entities": "^1.3.1", - "http-proxy-middleware": "0.19.1", - "import-local": "^2.0.0", - "internal-ip": "^4.3.0", - "ip": "^1.1.5", - "is-absolute-url": "^3.0.3", - "killable": "^1.0.1", - "loglevel": "^1.6.8", - "opn": "^5.5.0", - "p-retry": "^3.0.1", - "portfinder": "^1.0.26", - "schema-utils": "^1.0.0", - "selfsigned": "^1.10.7", - "semver": "^6.3.0", - "serve-index": "^1.9.1", - "sockjs": "0.3.20", - "sockjs-client": "1.4.0", - "spdy": "^4.0.2", - "strip-ansi": "^3.0.1", - "supports-color": "^6.1.0", - "url": "^0.11.0", - "webpack-dev-middleware": "^3.7.2", - "webpack-log": "^2.0.0", - "ws": "^6.2.1", - "yargs": "^13.3.2" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "del": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", - "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "globby": "^6.1.0", - "is-path-cwd": "^2.0.0", - "is-path-in-cwd": "^2.0.0", - "p-map": "^2.0.0", - "pify": "^4.0.1", - "rimraf": "^2.6.3" - } - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "is-absolute-url": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", - "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "p-map": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - } - } - }, - "webpack-log": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", - "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", - "dev": true, - "requires": { - "ansi-colors": "^3.0.0", - "uuid": "^3.3.2" - } - }, - "webpack-merge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", - "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", - "dev": true, - "requires": { - "lodash": "^4.17.15" - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "webpack-subresource-integrity": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-1.4.0.tgz", - "integrity": "sha512-GB1kB/LwAWC3CxwcedGhMkxGpNZxSheCe1q+KJP1bakuieAdX/rGHEcf5zsEzhKXpqsGqokgsDoD9dIkr61VDQ==", - "dev": true, - "requires": { - "webpack-sources": "^1.3.0" - } - }, - "websocket-driver": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz", - "integrity": "sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=", - "dev": true, - "requires": { - "websocket-extensions": ">=0.1.1" - } - }, - "websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "dev": true - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", - "dev": true, - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "when": { - "version": "3.6.4", - "resolved": "https://registry.npmjs.org/when/-/when-3.6.4.tgz", - "integrity": "sha1-RztRfsFZ4rhQBUl6E5g/CVQS404=", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "widest-line": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "dev": true, - "requires": { - "string-width": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - } - } - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "worker-plugin": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/worker-plugin/-/worker-plugin-4.0.3.tgz", - "integrity": "sha512-7hFDYWiKcE3yHZvemsoM9lZis/PzurHAEX1ej8PLCu818Rt6QqUAiDdxHPCKZctzmhqzPpcFSgvMCiPbtooqAg==", - "dev": true, - "requires": { - "loader-utils": "^1.1.0" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "loader-utils": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", - "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } - } - } - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "ws": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", - "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0" - } - }, - "xdg-basedir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", - "dev": true - }, - "xhr2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/xhr2/-/xhr2-0.1.4.tgz", - "integrity": "sha1-f4dliEdxbbUCYyOBL4GMras4el8=" - }, - "xml": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", - "integrity": "sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=", - "dev": true - }, - "xml2js": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", - "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", - "requires": { - "sax": ">=0.6.0", - "xmlbuilder": "~11.0.0" - } - }, - "xmlbuilder": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - }, - "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - }, - "yargs": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.1.0.tgz", - "integrity": "sha512-1UhJbXfzHiPqkfXNHYhiz79qM/kZqjTE8yGlEjZa85Q+3+OwcV6NRkV7XOV1W2Eom2bzILeUn55pQYffjVOLAg==", - "requires": { - "cliui": "^4.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "os-locale": "^3.1.0", - "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.0.0" - }, - "dependencies": { - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - } - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" - }, - "dependencies": { - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } + } + }, + "node_modules/ordered-read-streams/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "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" + } + }, + "node_modules/ordered-read-streams/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/ordered-read-streams/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-5.5.0.tgz", + "integrity": "sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==", + "license": "MIT", + "dependencies": { + "aggregate-error": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-hash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", + "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/parse-filepath": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==", + "license": "MIT", + "dependencies": { + "is-absolute": "^1.0.0", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==", + "license": "MIT" + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==", + "license": "MIT", + "dependencies": { + "path-root-regex": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/path-scurry/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pe-library": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/pe-library/-/pe-library-0.4.1.tgz", + "integrity": "sha512-eRWB5LBz7PpDu4PUlwT0PhnQfTQJlDDdPa35urV4Osrm0t0AqQFGn+UIkU3klZvwJ8KPO3VbBFsXquA6p6kqZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/jet2jet" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/playwright": { + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.48.2.tgz", + "integrity": "sha512-NjYvYgp4BPmiwfe31j4gHLa3J7bD2WiBz8Lk2RoSsmX38SVIARZ18VYjxLjAcDsAhA+F4iSEXTSGgjua0rrlgQ==", + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.48.2" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.48.2.tgz", + "integrity": "sha512-sjjw+qrLFlriJo64du+EK0kJgZzoQPsabGF4lBvsid+3CNIZIYLgnMj9V6JY5VhM2Peh20DJWIVpVljLLnlawA==", + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/playwright/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/plist": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.0.tgz", + "integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@xmldom/xmldom": "^0.8.8", + "base64-js": "^1.5.1", + "xmlbuilder": "^15.1.1" + }, + "engines": { + "node": ">=10.4.0" + } + }, + "node_modules/plugin-error": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", + "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", + "license": "MIT", + "dependencies": { + "ansi-colors": "^1.0.1", + "arr-diff": "^4.0.0", + "arr-union": "^3.1.0", + "extend-shallow": "^3.0.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/plugin-error/node_modules/ansi-colors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", + "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", + "license": "MIT", + "dependencies": { + "ansi-wrap": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "license": "MIT", + "dependencies": { + "picocolors": "^0.2.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/postcss/node_modules/picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "license": "ISC" + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" + }, + "node_modules/process-on-spawn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", + "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fromentries": "^1.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pump": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", + "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "license": "MIT", + "dependencies": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + } + }, + "node_modules/pumpify/node_modules/pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", + "license": "MIT" + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/read-binary-file-arch": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/read-binary-file-arch/-/read-binary-file-arch-1.0.6.tgz", + "integrity": "sha512-BNg9EN3DD3GsDXX7Aa8O4p92sryjkmzYYgmgTAc6CA4uGLEDzFfxOxugu21akOxpcXHiEgsYkC6nPsQvLLLmEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, + "bin": { + "read-binary-file-arch": "cli.js" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdir-glob": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", + "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "minimatch": "^5.1.0" + } + }, + "node_modules/readdir-glob/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "license": "MIT", + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", + "dev": true, + "license": "ISC", + "dependencies": { + "es6-error": "^4.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/remove-bom-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", + "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5", + "is-utf8": "^0.2.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/remove-bom-stream": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", + "integrity": "sha512-wigO8/O08XHb8YPzpDDT+QmRANfW6vLqxfaXm1YXhnFf3AkSLyjfG3GEFg4McZkmgL7KvCj5u2KczkvSP6NfHA==", + "license": "MIT", + "dependencies": { + "remove-bom-buffer": "^3.0.0", + "safe-buffer": "^5.1.0", + "through2": "^2.0.3" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/remove-bom-stream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "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" + } + }, + "node_modules/remove-bom-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/remove-bom-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/remove-bom-stream/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "license": "MIT", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", + "license": "ISC" + }, + "node_modules/replace-ext": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", + "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/replace-homedir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-2.0.0.tgz", + "integrity": "sha512-bgEuQQ/BHW0XkkJtawzrfzHFSN70f/3cNOiHa2QsYxqrjaC30X1k74FJ6xswVBP0sr0SpGIdVFuPwfrYziVeyw==", + "license": "MIT", + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true, + "license": "ISC" + }, + "node_modules/resedit": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/resedit/-/resedit-1.7.2.tgz", + "integrity": "sha512-vHjcY2MlAITJhC0eRD/Vv8Vlgmu9Sd3LX9zZvtGzU5ZImdTN3+d6e/4mnTyV8vEbyf1sgNIrWxhWlrys52OkEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pe-library": "^0.4.1" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/jet2jet" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==", + "license": "MIT", + "dependencies": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-options": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-2.0.0.tgz", + "integrity": "sha512-/FopbmmFOQCfsCx77BRFdKOniglTiHumLgwvd6IDPihy1GKkadZbgQJBcTb2lMzSR1pndzd96b1nZrreZ7+9/A==", + "license": "MIT", + "dependencies": { + "value-or-function": "^4.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/restore-cursor/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/roarr": { + "version": "2.15.4", + "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", + "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "dependencies": { + "boolean": "^3.0.1", + "detect-node": "^2.0.4", + "globalthis": "^1.0.1", + "json-stringify-safe": "^5.0.1", + "semver-compare": "^1.0.0", + "sprintf-js": "^1.1.2" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/sanitize-filename": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", + "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", + "dev": true, + "license": "WTFPL OR ISC", + "dependencies": { + "truncate-utf8-bytes": "^1.0.0" + } + }, + "node_modules/sax": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", + "dev": true, + "license": "ISC" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "devOptional": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/semver-greatest-satisfied-range": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-2.0.0.tgz", + "integrity": "sha512-lH3f6kMbwyANB7HuOWRMlLCa2itaCrZJ+SAqqkSZrZKO/cAsk2EOyaKHUtNkVLFyFW9pct22SFesFp3Z7zpA0g==", + "license": "MIT", + "dependencies": { + "sver": "^1.8.3" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/serialize-error": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", + "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "type-fest": "^0.13.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serialize-error/node_modules/type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true, + "license": "ISC" + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true, + "license": "ISC" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/simple-update-notifier": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz", + "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/simple-update-notifier/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/slash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", + "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", + "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/socks-proxy-agent/node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-resolve": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz", + "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", + "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", + "license": "MIT", + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sparkles": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-2.1.0.tgz", + "integrity": "sha512-r7iW1bDw8R/cFifrD3JnQJX0K1jqT0kprL48BiBpLZLJPmAm34zsVBsK5lc7HirZYZqMW65dOXZgbAGt/I6frg==", + "license": "MIT", + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/spawn-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", + "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "which": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/spawn-wrap/node_modules/foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/spawn-wrap/node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/spawn-wrap/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/ssri": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz", + "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.1.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/stat-mode": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-1.0.0.tgz", + "integrity": "sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/stream-composer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stream-composer/-/stream-composer-1.0.2.tgz", + "integrity": "sha512-bnBselmwfX5K10AH6L4c8+S5lgZMWI7ZYrz2rvYjCPB2DIMC4Ig8OpxGpNJSxRZ58oti7y1IcNvjBAz9vW5m4w==", + "license": "MIT", + "dependencies": { + "streamx": "^2.13.2" + } + }, + "node_modules/stream-exhaust": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", + "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==", + "license": "MIT" + }, + "node_modules/stream-shift": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", + "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", + "license": "MIT" + }, + "node_modules/streamx": { + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.1.tgz", + "integrity": "sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA==", + "license": "MIT", + "dependencies": { + "fast-fifo": "^1.3.2", + "queue-tick": "^1.0.1", + "text-decoder": "^1.1.0" + }, + "optionalDependencies": { + "bare-events": "^2.2.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/sumchecker": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", + "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "debug": "^4.1.0" + }, + "engines": { + "node": ">= 8.0" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/sver": { + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/sver/-/sver-1.8.4.tgz", + "integrity": "sha512-71o1zfzyawLfIWBOmw8brleKyvnbn73oVHNCsu51uPMz/HWiKkkXsI31JjHW5zqXEqnPYkIiHd8ZmL7FCimLEA==", + "license": "MIT", + "optionalDependencies": { + "semver": "^6.3.0" + } + }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dev": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/teex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", + "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==", + "license": "MIT", + "dependencies": { + "streamx": "^2.12.5" + } + }, + "node_modules/temp-file": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.4.0.tgz", + "integrity": "sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-exit-hook": "^2.0.1", + "fs-extra": "^10.0.0" + } + }, + "node_modules/temp-file/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/temp-file/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/temp-file/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/test-exclude/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/text-decoder": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.1.tgz", + "integrity": "sha512-x9v3H/lTKIJKQQe7RPQkLfKAnc9lUTkWDypIQgTzPJAq+5/GCDHonmshfvlsNSj58yyshbIJJDLmU15qNERrXQ==", + "license": "Apache-2.0" + }, + "node_modules/through2": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz", + "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==", + "license": "MIT", + "dependencies": { + "readable-stream": "2 || 3" + } + }, + "node_modules/through2-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", + "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", + "license": "MIT", + "dependencies": { + "through2": "~2.0.0", + "xtend": "~4.0.0" + } + }, + "node_modules/through2-filter/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "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" + } + }, + "node_modules/through2-filter/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/through2-filter/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/through2-filter/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "license": "MIT", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/time-stamp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", + "integrity": "sha512-gLCeArryy2yNTRzTGKbZbloctj64jkZ57hj5zdraXue6aFgd6PmvVtEyiUU+hvU0v7q08oVv8r8ev0tRo6bvgw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/timers-ext": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.8.tgz", + "integrity": "sha512-wFH7+SEAcKfJpfLPkrgMPvvwnEtj8W4IurvEyrKsDleXnKLCDw71w8jltvfLa8Rm4qQxxT4jmDBYbJG/z7qoww==", + "license": "ISC", + "dependencies": { + "es5-ext": "^0.10.64", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "node_modules/tmp-promise": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", + "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tmp": "^0.2.0" + } + }, + "node_modules/to-absolute-glob": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", + "integrity": "sha512-rtwLUQEwT8ZeKQbyFJyomBRYXyE16U5VKuy0ftxLMK/PZb2fkOsg5r9kHdauuVDbsNdIBoC/HCthpidamQFXYA==", + "license": "MIT", + "dependencies": { + "is-absolute": "^1.0.0", + "is-negated-glob": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/to-through": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/to-through/-/to-through-3.0.0.tgz", + "integrity": "sha512-y8MN937s/HVhEoBU1SxfHC+wxCHkV1a9gW8eAdTadYh/bGyesZIVcbjI+mSpFbSVwQici/XjBjuUyri1dnXwBw==", + "license": "MIT", + "dependencies": { + "streamx": "^2.12.5" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true, + "license": "MIT" + }, + "node_modules/truncate-utf8-bytes": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", + "integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==", + "dev": true, + "license": "WTFPL", + "dependencies": { + "utf8-byte-length": "^1.0.1" + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/acorn": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.13.0.tgz", + "integrity": "sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ts-node/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/tsscmp": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz", + "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6.x" + } + }, + "node_modules/type": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz", + "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==", + "license": "ISC" + }, + "node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/undertaker": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-2.0.0.tgz", + "integrity": "sha512-tO/bf30wBbTsJ7go80j0RzA2rcwX6o7XPBpeFcb+jzoeb4pfMM2zUeSDIkY1AWqeZabWxaQZ/h8N9t35QKDLPQ==", + "license": "MIT", + "dependencies": { + "bach": "^2.0.1", + "fast-levenshtein": "^3.0.0", + "last-run": "^2.0.0", + "undertaker-registry": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/undertaker-registry": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-2.0.0.tgz", + "integrity": "sha512-+hhVICbnp+rlzZMgxXenpvTxpuvA67Bfgtt+O9WOE5jo7w/dyiF1VmoZVIHvP2EkUjsyKyTwYKlLhA+j47m1Ew==", + "license": "MIT", + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "license": "MIT" + }, + "node_modules/unique-filename": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz", + "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==", + "dev": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/unique-slug": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz", + "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/unique-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", + "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", + "license": "MIT", + "dependencies": { + "json-stable-stringify-without-jsonify": "^1.0.1", + "through2-filter": "^3.0.0" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/utf8-byte-length": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz", + "integrity": "sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==", + "dev": true, + "license": "(WTFPL OR MIT)" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true, + "license": "MIT" + }, + "node_modules/v8flags": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-4.0.1.tgz", + "integrity": "sha512-fcRLaS4H/hrZk9hYwbdRM35D0U8IYMfEClhXxCivOojl+yTRAZH3Zy2sSy6qVCiGbV9YAtPssP6jaChqC9vPCg==", + "license": "MIT", + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/value-or-function": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-4.0.0.tgz", + "integrity": "sha512-aeVK81SIuT6aMJfNo9Vte8Dw0/FZINGBV8BfCraGtqVxIeLAEhJyoWs8SmvRVmXfGss2PmmOwZCuBPbZR+IYWg==", + "license": "MIT", + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/verror": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz", + "integrity": "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/vinyl": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", + "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", + "license": "MIT", + "dependencies": { + "clone": "^2.1.1", + "clone-buffer": "^1.0.0", + "clone-stats": "^1.0.0", + "cloneable-readable": "^1.0.0", + "remove-trailing-separator": "^1.0.1", + "replace-ext": "^1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vinyl-contents": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/vinyl-contents/-/vinyl-contents-2.0.0.tgz", + "integrity": "sha512-cHq6NnGyi2pZ7xwdHSW1v4Jfnho4TEGtxZHw01cmnc8+i7jgR6bRnED/LbrKan/Q7CvVLbnvA5OepnhbpjBZ5Q==", + "license": "MIT", + "dependencies": { + "bl": "^5.0.0", + "vinyl": "^3.0.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/vinyl-contents/node_modules/bl": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", + "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", + "license": "MIT", + "dependencies": { + "buffer": "^6.0.3", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/vinyl-contents/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/vinyl-contents/node_modules/replace-ext": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz", + "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/vinyl-contents/node_modules/vinyl": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz", + "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==", + "license": "MIT", + "dependencies": { + "clone": "^2.1.2", + "clone-stats": "^1.0.0", + "remove-trailing-separator": "^1.1.0", + "replace-ext": "^2.0.0", + "teex": "^1.0.1" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/vinyl-fs": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-4.0.0.tgz", + "integrity": "sha512-7GbgBnYfaquMk3Qu9g22x000vbYkOex32930rBnc3qByw6HfMEAoELjCjoJv4HuEQxHAurT+nvMHm6MnJllFLw==", + "license": "MIT", + "dependencies": { + "fs-mkdirp-stream": "^2.0.1", + "glob-stream": "^8.0.0", + "graceful-fs": "^4.2.11", + "iconv-lite": "^0.6.3", + "is-valid-glob": "^1.0.0", + "lead": "^4.0.0", + "normalize-path": "3.0.0", + "resolve-options": "^2.0.0", + "stream-composer": "^1.0.2", + "streamx": "^2.14.0", + "to-through": "^3.0.0", + "value-or-function": "^4.0.0", + "vinyl": "^3.0.0", + "vinyl-sourcemap": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/vinyl-fs/node_modules/replace-ext": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz", + "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/vinyl-fs/node_modules/vinyl": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz", + "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==", + "license": "MIT", + "dependencies": { + "clone": "^2.1.2", + "clone-stats": "^1.0.0", + "remove-trailing-separator": "^1.1.0", + "replace-ext": "^2.0.0", + "teex": "^1.0.1" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/vinyl-sourcemap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-2.0.0.tgz", + "integrity": "sha512-BAEvWxbBUXvlNoFQVFVHpybBbjW1r03WhohJzJDSfgrrK5xVYIDTan6xN14DlyImShgDRv2gl9qhM6irVMsV0Q==", + "license": "MIT", + "dependencies": { + "convert-source-map": "^2.0.0", + "graceful-fs": "^4.2.10", + "now-and-later": "^3.0.0", + "streamx": "^2.12.5", + "vinyl": "^3.0.0", + "vinyl-contents": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/vinyl-sourcemap/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "license": "MIT" + }, + "node_modules/vinyl-sourcemap/node_modules/replace-ext": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz", + "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/vinyl-sourcemap/node_modules/vinyl": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz", + "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==", + "license": "MIT", + "dependencies": { + "clone": "^2.1.2", + "clone-stats": "^1.0.0", + "remove-trailing-separator": "^1.1.0", + "replace-ext": "^2.0.0", + "teex": "^1.0.1" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/vinyl-sourcemaps-apply": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz", + "integrity": "sha512-+oDh3KYZBoZC8hfocrbrxbLUeaYtQK7J5WU5Br9VqWqmCll3tFJqKp97GC9GmMsVIL0qnx2DgEDVxdo5EZ5sSw==", + "dev": true, + "license": "ISC", + "dependencies": { + "source-map": "^0.5.1" + } + }, + "node_modules/vinyl-sourcemaps-apply/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/workerpool": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", + "license": "Apache-2.0" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/write-file-atomic/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/xml": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", + "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==", + "dev": true, + "license": "MIT" + }, + "node_modules/xmlbuilder": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "license": "MIT", + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs-unparser/node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/ylru": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ylru/-/ylru-1.4.0.tgz", + "integrity": "sha512-2OQsPNEmBCvXuFlIni/a+Rn+R2pHW9INm0BxXJ4hVDA8TirqMj+J/Rp9ItLatT/5pZqWwefVrTQcHpixsxnVlA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctodelay": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/yoctodelay/-/yoctodelay-1.2.0.tgz", + "integrity": "sha512-12y/P9MSig9/5BEhBgylss+fkHiCRZCvYR81eH35NW9uw801cvJt31EAV+WOLcwZRZbLiIQl/hxcdXXXFmGvXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/zip-stream": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.1.tgz", + "integrity": "sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "archiver-utils": "^3.0.4", + "compress-commons": "^4.1.2", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/zip-stream/node_modules/archiver-utils": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-3.0.4.tgz", + "integrity": "sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "glob": "^7.2.3", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">= 10" + } } - } - }, - "yauzl": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.6.0.tgz", - "integrity": "sha1-QIlNRYe7ElUA0F30VHHNXhFKdvk=", - "requires": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.0.1" - } - }, - "yazl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", - "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", - "dev": true, - "requires": { - "buffer-crc32": "~0.2.3" - } - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true - }, - "yoctodelay": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/yoctodelay/-/yoctodelay-1.2.0.tgz", - "integrity": "sha512-12y/P9MSig9/5BEhBgylss+fkHiCRZCvYR81eH35NW9uw801cvJt31EAV+WOLcwZRZbLiIQl/hxcdXXXFmGvXg==", - "dev": true - }, - "zip-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.0.tgz", - "integrity": "sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==", - "dev": true, - "requires": { - "archiver-utils": "^2.1.0", - "compress-commons": "^4.1.0", - "readable-stream": "^3.6.0" - } - }, - "zone.js": { - "version": "0.8.29", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.8.29.tgz", - "integrity": "sha512-mla2acNCMkWXBD+c+yeUrBUrzOxYMNFdQ6FGfigGGtEVBPJx07BQeJekjt9DmH1FtZek4E9rE1eRR9qQpxACOQ==" } - } } diff --git a/package.json b/package.json index e299ebc..eea60fd 100644 --- a/package.json +++ b/package.json @@ -1,154 +1,86 @@ { - "name": "into-cps-app", - "productName": "INTO-CPS APP", - "version": "4.0.8-dev", - "description": "User interface for the INTO-CPS Toolchain", - "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/INTO-CPS-Association/into-cps-application.git" - }, - "main": "dist/main.js", - "author": { - "name": "INTO-CPS Project", - "email": "null@void.org", - "url": "http://into-cps.au.dk/" - }, - "electronVersion": "10.1.3", - "scripts": { - "start": "electron --no-sandbox dist/main.js", - "test": "npx playwright test", - "dist": "electron-builder --x64 -p never" - }, - "build": { - "appId": "org.into-cps-association.into-cps-app", - "copyright": "Copyright © 2021 INTO-CPS Association", - "productName": "INTO-CPS-Application", - "electronVersion": "10.1.2", - "files": [ - "**/*", - "dist/**/*" - ], - "directories": { - "output": "release", - "buildResources": "dist" + "name": "into-cps-app", + "productName": "INTO-CPS APP", + "version": "5.0.0", + "description": "User interface for the INTO-CPS Toolchain", + "license": "SEE LICENSE IN ", + "repository": { + "type": "git", + "url": "https://github.com/INTO-CPS-Association/into-cps-application.git" }, - "mac": { - "category": "public.app-category.developer-tools", - "icon": "dist/resources/into-cps/appicon/into-cps-logo.png" + "main": "dist/main.js", + "author": { + "name": "INTO-CPS Project", + "email": "null@void.org", + "url": "http://into-cps.au.dk/" }, - "win": { - "icon": "dist/resources/into-cps/appicon/into-cps-logo.png.ico", - "target": [ - "nsis", - "portable" - ] + "scripts": { + "start": "electron dist/main.js", + "test": "gulp && npx playwright test", + "dist": "electron-builder --x64 -p never", + "dist:win": "electron-builder --win --x64 -p never", + "clean": "rimraf dist monocart-report node_modules release pkg test-results test/coverage-reports" }, - "nsis": { - "oneClick": false, - "allowToChangeInstallationDirectory": true + "build": { + "appId": "org.into-cps-association.into-cps-app", + "copyright": "Copyright © 2021 INTO-CPS Association", + "productName": "INTO-CPS-Application", + "electronVersion": "32.1.2", + "files": [ + "**/*", + "dist/**/*" + ], + "directories": { + "output": "release", + "buildResources": "dist" + }, + "mac": { + "category": "public.app-category.developer-tools", + "icon": "dist/resources/into-cps/appicon/into-cps-logo.ico" + }, + "win": { + "icon": "dist/resources/into-cps/appicon/into-cps-logo.png.ico", + "target": [ + "nsis", + "portable" + ] + }, + "nsis": { + "oneClick": false, + "allowToChangeInstallationDirectory": true + }, + "linux": { + "target": [ + "AppImage" + ], + "icon": "dist/resources/into-cps/appicon/into-cps-logo.png" + } }, - "linux": { - "target": [ - "AppImage" - ], - "icon": "dist/resources/into-cps/appicon/into-cps-logo.png" + "dependencies": { + "@playwright/test": "^1.47.2", + "@popperjs/core": "^2.11.8", + "@types/w2ui": "^1.4.37", + "bootstrap": "^5.3.3", + "del": "^7.1.0", + "gulp": "^5.0.0", + "gulp-sourcemaps": "^3.0.0", + "gulp-typescript": "^6.0.0-alpha.1", + "jquery": "^3.7.1", + "mocha": "^10.7.3" + }, + "devDependencies": { + "@types/node": "^22.7.5", + "electron": "^32.1.2", + "electron-builder": "^25.1.7", + "electron-playwright-helpers": "^1.7.1", + "gulp-clean-css": "^4.3.0", + "gulp-htmlhint": "^4.0.2", + "monocart-coverage-reports": "^2.11.1", + "monocart-reporter": "^2.9.6", + "nyc": "^17.1.0", + "playwright": "^1.47.2", + "source-map-support": "^0.5.21", + "ts-node": "^10.9.2", + "typescript": "^5.6.2" } - }, - "dependencies": { - "@angular/animations": "^7.2.16", - "@angular/cli": "^7.3.9", - "@angular/common": "^7.2.16", - "@angular/compiler": "^7.2.16", - "@angular/compiler-cli": "^7.2.16", - "@angular/core": "^7.2.16", - "@angular/forms": "^7.2.16", - "@angular/http": "^7.2.16", - "@angular/platform-browser": "^7.2.16", - "@angular/platform-browser-dynamic": "^7.2.16", - "@angular/platform-server": "^7.2.16", - "@angular/router": "^7.2.16", - "@types/ace": "0.0.42", - "@types/fs-extra": "9.0.7", - "@types/jquery": "^2.0.54", - "@types/sql.js": "~0.0.28", - "@types/w2ui": "~1.4.30", - "ace-builds": "^1.4.12", - "bluebird": "~3.4.7", - "bootstrap": "^3.3.6", - "electron-default-menu": "^1.0.1", - "es6-shim": "^0.35.5", - "fs-extra": "~0.30.0", - "is-running": "~2.1.0", - "jquery": "^3.4.1", - "jsonschema": "~1.1.1", - "jszip": "^3.2.2", - "md5-promised": "~1.0.1", - "mkdirp": "^1.0.3", - "node-sha1": "^1.0.1", - "plotly.js-dist": "^1.58.4", - "progress-stream": "~2.0.0", - "reflect-metadata": "^0.1.13", - "request": "^2.88.2", - "request-progress": "~2.0.1", - "rimraf": "~2.5.4", - "rxjs": "^6.5.4", - "showdown": "^1.9.1", - "sql.js": "~0.3.2", - "tree-kill": "^1.2.2", - "tslib": "^1.9.0", - "xml2js": "^0.4.23", - "yauzl": "~2.6.0", - "zone.js": "^0.8.29" - }, - "devDependencies": { - "@angular-devkit/build-angular": "^0.901.0", - "@playwright/test": "^1.19.2", - "@types/adm-zip": "^0.4.34", - "@types/bluebird": "~3.0.37", - "@types/bunyan": "0.0.35", - "@types/node": "^12.12.29", - "@types/request": "^2.48.8", - "@types/xml2js": "0.0.32", - "adm-zip": "^0.5.4", - "axios": "^0.26.1", - "chai": "^4.2.0", - "chai-as-promised": "^7.1.1", - "chai-wait-for": "^1.0.4", - "del": "~2.2.0", - "electron": "^10.2.0", - "electron-builder": "^22.9.1", - "electron-packager": "^14.2.1", - "fs": "0.0.1-security", - "gulp": "~4.0.2", - "gulp-bower": "0.0.15", - "gulp-bump": "~2.4.0", - "gulp-clean-css": "~2.3.2", - "gulp-concat": "~2.6.0", - "gulp-debug": "~2.1.2", - "gulp-filter": "~4.0.0", - "gulp-git": "^2.8.1", - "gulp-htmlhint": "^3.0.0", - "gulp-inject": "~4.1.0", - "gulp-sourcemaps": "^2.6.5", - "gulp-typescript": "^4.0.0", - "gulp-uglify": "^3.0.2", - "gulp-util": "~3.0.7", - "gulp-zip": "^5.0.1", - "main-bower-files": "^2.13.3", - "merge-stream": "~1.0.0", - "minimist": "^1.2.5", - "mocha": "^7.1.0", - "playwright": "^1.19.2", - "readable-stream": "^3.6.0", - "run-sequence": "~1.2.2", - "semver": "~5.3.0", - "spectron": "^12.0.0", - "terser-webpack-plugin": "^2.3.5", - "ts-loader": "^8.0.2", - "typescript": "^3.9.7", - "uglify-save-license": "^0.4.1", - "webpack": "^4.42.0", - "webpack-cli": "^3.3.11" - } } diff --git a/playwright.config.ts b/playwright.config.ts index b90f881..a197b8d 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -1,9 +1,54 @@ -import { PlaywrightTestConfig } from '@playwright/test'; - -const config: PlaywrightTestConfig = { - // Limit the number of workers on CI, use default locally - workers: 1, - retries: 0, - timeout: 15000 -}; -export default config; \ No newline at end of file +import { defineConfig, devices } from '@playwright/test'; + +export default defineConfig({ + use: { + baseURL: process.env.BASE_URL || 'http://localhost:4000', + trace: 'retain-on-failure', + }, + testDir: './test', + timeout: 30000, + fullyParallel: true, + + /* Fail the build on CI if you accidentally left test.only in the source code. */ + forbidOnly: Boolean(process.env.CI), + + /* Retry on CI only */ + retries: process.env.CI ? 2 : 0, + + /* Opt out of parallel tests on CI. */ + workers: process.env.CI ? 1 : undefined, + + reporter: [ + ['list'], + ['monocart-reporter', { + name: "Tests Report", + outputFile: './monocart-report/index.html', + coverage: { + entryFilter: { + '**/node_modules/**': false, + '**/dist/**': false, + 'src/**/*.ts': true, + 'src/**/*.js': true + }, + sourceFilter: { + '**/node_modules/**': false, + '**/dist/**': false, + 'src/**/*.ts': true, + 'src/**/*.js': true + }, + outputDir: 'test/coverage-reports' + } + }] +], + globalTeardown: 'test/global-teardown.ts', + globalSetup: 'test/global-setup.ts', + projects: [ + { + name: 'electron', + use: { + browserName: 'chromium', + channel: 'chrome', + } + } + ] +}); \ No newline at end of file diff --git a/src/CoeServerStatusUiController.ts b/src/CoeServerStatusUiController.ts deleted file mode 100644 index 694c61e..0000000 --- a/src/CoeServerStatusUiController.ts +++ /dev/null @@ -1,276 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import { IntoCpsApp } from "./IntoCpsApp"; -import { CoeProcess } from "./coe-server-status/CoeProcess" -// typescript: -/* import {remote} from "electron"; */ -// javascript: -const {remote} = require("electron"); - -export enum UICrtlType {Console, Log}; - -export class CoeServerStatusUiController { - - protected type: UICrtlType = UICrtlType.Console; - private outputDiv: HTMLDivElement = null; //coe-console-output - - activeDiv: HTMLDivElement; - errorPrefix = "."; - coeStatusRunning = false; - bottomElement: any = null; - isSubscribed = false; - buffer: DocumentFragment = new DocumentFragment(); - coeLogStartLine: string; - coeLogStartLineIsSet = false; - public static readonly maxLines: number = 5000; - - constructor(outputDiv: HTMLDivElement) { - this.outputDiv = outputDiv; - } - - public clearOutput() { - let div = this.outputDiv; - while (div != null && div.hasChildNodes()) { - div.removeChild(div.firstChild); - } - } - - protected processOutput(data: string, skip: boolean) { - let endsWithNewline: boolean = data.endsWith("\n"); - let dd = data.split("\n"); - - dd.forEach((line, idx, array) => { - if (line.trim().length != 0) { - // If it is the last line and it does not end with a newline, then save it for next print. - if (idx === array.length - 1 && endsWithNewline === false) { - this.coeLogStartLine = line; - this.coeLogStartLineIsSet = true; - } - else { - let m = document.createElement("span"); - if (!skip) { - if (idx === 0 && this.coeLogStartLineIsSet) { - m.innerHTML = this.coeLogStartLine; - this.coeLogStartLineIsSet = false; - } - m.innerHTML = m.innerHTML.concat(`${line}
`); - if (line.indexOf("ERROR") > -1 || line.indexOf(this.errorPrefix) == 0) - m.style.color = "rgb(255, 0, 0)"; - if (line.indexOf("WARN") > -1) - m.style.color = "rgb(255, 165, 0)"; - if (line.indexOf("DEBUG") > -1) - m.style.color = "rgb(0, 0, 255)"; - if (line.indexOf("TRACE") > -1) - m.style.color = "rgb(128,128,128)"; - } - else { - // This case skips the first line in case skip is true. - skip = false; - m.innerHTML = m.innerHTML.concat(`Skipped part of the log `); - } - this.buffer.appendChild(m); - } - } - }); - - this.outputDiv.appendChild(this.buffer); - this.buffer = new DocumentFragment(); - } - - private setStatusIcons() { - var coe = IntoCpsApp.getInstance().getCoeProcess(); - var ss = document.getElementById("stream-status"); - - if (coe.isLogRedirectActive() && coe.isRunning()) { - ss.className = "glyphicon glyphicon-link"; - } else { - ss.className = "glyphicon glyphicon-remove"; - } - - var os = document.getElementById("online-status"); - //console.log(`CoeServerStatusUiController - isRunnig: ${coe.isRunning()}`) - os.style.color = coe.isRunning() ? "green" : "red"; - - var btnLaunch = document.getElementById("coe-btn-launch"); - btnLaunch.disabled = coe.isRunning(); - var btnStop = document.getElementById("coe-btn-stop"); - btnStop.disabled = !coe.isRunning(); - var btnBottomLaunch = document.getElementById("coe-btn-launch-bottom"); - var btnBottomStop = document.getElementById("coe-btn-launch-bottom"); - } - - public updateButtonState() { - var coe = IntoCpsApp.getInstance().getCoeProcess(); - console.log("is running: ", coe.isRunning()); - let button = document.getElementById("coe-btn-launch-bottom"); - let icon = document.getElementById("coeIconColor"); - - if (coe.isRunning()) { - button.innerHTML = 'Stop COE '; - console.log("button: ", button); - button.setAttribute('onclick', 'coeViewController.stopCoe()'); - icon.style.color = 'green'; - } else { - button.innerHTML = 'Start COE '; - button.setAttribute('onclick', 'coeViewController.launchCoe()'); - icon.style.color = 'red'; - } - } - - - consoleAutoScroll() { - let div = this.outputDiv; - if (!$(div).is(":visible")) - return; - if (this.bottomElement == div.lastChild || div.lastChild == null) - return - this.bottomElement = div.lastChild; - (div.lastChild).scrollIntoView(); - } - - protected truncateVisibleLog() { - if (this.outputDiv.childElementCount > CoeServerStatusUiController.maxLines) { - while (this.outputDiv.childElementCount > CoeServerStatusUiController.maxLines && this.outputDiv.hasChildNodes()) { - this.outputDiv.removeChild(this.outputDiv.firstChild); - } - let m = document.createElement("span"); - m.innerHTML = m.innerHTML.concat(`Truncated part of the log `); - m.style.color = "rgb(128,128,128)"; - this.outputDiv.insertBefore(m, this.outputDiv.firstChild); - } - } - - protected prepareSimulationCallback() { - return () => this.clearOutput(); - } - - public async bind() { - if (this.isSubscribed) - return; - - var coe = IntoCpsApp.getInstance().getCoeProcess(); - this.errorPrefix = coe.getErrorLogLinePrefix(); - coe.subscribe((line: any, skip: boolean) => { this.processOutput(line, skip) }) - let index = coe.subscribePrepareSimulationCallback(this.type, this.prepareSimulationCallback()); - this.isSubscribed = true; - this.setStatusIcons(); - this.updateButtonState(); - - if (!this.coeStatusRunning) { - window.setInterval(() => { this.setStatusIcons(); this.truncateVisibleLog(), this.updateButtonState()}, 3000); - window.setInterval(() => { this.consoleAutoScroll() }, 800); - this.coeStatusRunning = true; - } - window.addEventListener("beforeunload",(ev: BeforeUnloadEvent) => { - remote.getCurrentWindow().removeAllListeners(); - coe.unloadPrintView(this.type); - }); - window.onbeforeunload = ((ev: BeforeUnloadEvent) => { - - }); - } - - public launchCoe() { - - this.activeDiv = this.outputDiv; - while (this.activeDiv.hasChildNodes()) { - this.activeDiv.removeChild(this.activeDiv.firstChild); - } - - var coe = IntoCpsApp.getInstance().getCoeProcess(); - let mLaunch = document.createElement("span"); - mLaunch.innerHTML = "Terminal args: java -jar " + coe.getCoePath() + "
"; - - this.activeDiv.appendChild(mLaunch); - - this.bind(); - - - if (!coe.isRunning()) { - coe.start(); - } - - this.updateButtonState(); - } - - public stopCoe() { - var coe = IntoCpsApp.getInstance().getCoeProcess(); - if (coe.isRunning()) { - coe.stop(); - } - this.updateButtonState(); - } - -} - -export class CoeLogUiController extends CoeServerStatusUiController { - - protected type: UICrtlType = UICrtlType.Log; - - public async bind() { - if (this.isSubscribed) - return; - var coe = IntoCpsApp.getInstance().getCoeProcess(); - coe.subscribeLog4J((line: any, skip: boolean) => { this.processOutput(line, skip) }) - let index = coe.subscribePrepareSimulationCallback(this.type, this.prepareSimulationCallback()); - window.setInterval(() => { this.truncateVisibleLog() }, 3000); - this.isSubscribed = true; - window.setInterval(() => { this.consoleAutoScroll() }, 800); - window.addEventListener("beforeunload",(ev) => { - remote.getCurrentWindow().removeAllListeners(); - coe.unloadPrintView(this.type); - - }); - } -} - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/DialogHandler.ts b/src/DialogHandler.ts deleted file mode 100644 index 8f62a32..0000000 --- a/src/DialogHandler.ts +++ /dev/null @@ -1,105 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import IntoCpsApp from "./IntoCpsApp"; -import {SettingKeys} from "./settings/SettingKeys" -const {remote, BrowserWindow} = require("electron"); -export default class DialogHandler { - - doAction: (arg: any) => void; - htmlPath: string; - ipcDoActionEventName: string; - ipcOpenEventName: string; - windowWidth: number; - windowHeight: number; - - externalUrl: boolean = false; - - win: Electron.BrowserWindow = null; - - constructor(htmlPath: string, windowWidth: number, - windowHeight: number/* , ipcOpenEventName: string, ipcDoActionEventName: string, doAction: (arg: any) => void */) { - this.htmlPath = htmlPath; - this.windowWidth = windowWidth; - this.windowHeight = windowHeight; - /* this.ipcDoActionEventName = ipcDoActionEventName; - this.doAction = doAction; - this.ipcOpenEventName = ipcOpenEventName; - } - - public install() { - - if (this.ipcOpenEventName != null) { - - IntoCpsApp.getInstance().on(this.ipcOpenEventName, (path: any) => { - console.log(path); // prints "ping" - //event.sender.send('asynchronous-reply', 'pong'); - this.openWindow(); - }); - } - - if (this.ipcDoActionEventName != null) { - IntoCpsApp.getInstance().on(this.ipcDoActionEventName, (arg: any) => { - this.doAction(arg); - this.win.close(); - }); - } */ - - } - - public openWindow(data:string = '', showWindow:boolean = true) : Electron.BrowserWindow { - let self = this; - this.win = (BrowserWindow - ? new BrowserWindow({ width: this.windowWidth, height: this.windowHeight, show: showWindow, webPreferences: {nodeIntegration: true, enableRemoteModule : true} }) - : new remote.BrowserWindow({ width: this.windowWidth, height: this.windowHeight, show: showWindow, webPreferences: {nodeIntegration: true, enableRemoteModule : true} })); - if(!IntoCpsApp.getInstance().getSettings().getSetting(SettingKeys.DEVELOPMENT_MODE) && this.win.setMenu) - this.win.setMenu(null); - - // Open the DevTools. - //this.win.webContents.openDevTools(); - /* window.onbeforeunload = (ev: BeforeUnloadEvent) => {if(this.win) this.win.removeAllListeners();} */ - - this.win.on('closed', function () { - self.win.removeAllListeners(); - this.win = null; - }); - - if (this.externalUrl) { - this.win.loadURL(this.htmlPath); - } else { - this.win.loadURL(`file://${__dirname}/${this.htmlPath}?data=${data}`); - } - return this.win; - } - -} -export {DialogHandler} - diff --git a/src/IntoCpsApp.ts b/src/IntoCpsApp.ts deleted file mode 100644 index 1442a38..0000000 --- a/src/IntoCpsApp.ts +++ /dev/null @@ -1,260 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import * as Path from 'path'; -import * as fs from 'fs'; - - -import { ISettingsValues } from "./settings/ISettingsValues"; -import { Settings } from "./settings/settings"; -import { IProject } from "./proj/IProject"; -import { Project } from "./proj/Project"; -import { IntoCpsAppEvents } from "./IntoCpsAppEvents"; -import { SettingKeys } from "./settings//SettingKeys"; -import { Utilities } from "./utilities"; -import { CoeProcess } from "./coe-server-status/CoeProcess"; - -const {remote} = require("electron"); - -// constants -let topBarNameId: string = "activeTabTitle"; - - const globalAny:any = global; - export default class IntoCpsApp { - - app: Electron.App; - platform: String - window: Electron.BrowserWindow; - coeProcess: CoeProcess = null; - - settings: Settings; - - activeProject: IProject = null; - isquitting = false; - - constructor(app: Electron.App, processPlatform: String) { - this.app = app; - this.platform = processPlatform; - - const intoCpsAppFolder = this.createAppFolderRoot(app); - this.createDirectoryStructure(intoCpsAppFolder); - // Set calculated default values - let defaultValues = SettingKeys.DEFAULT_VALUES; - let projRoot = Utilities.getSystemPlatform() == "windows" ? this.app.getPath('documents') : this.app.getPath('home'); - let defaultProjectFolderPath = Path.join(projRoot, "into-cps-projects"); - defaultValues[SettingKeys.INSTALL_TMP_DIR] = Path.join(defaultProjectFolderPath, "install_downloads"); - defaultValues[SettingKeys.INSTALL_DIR] = Path.join(defaultProjectFolderPath, "install"); - defaultValues[SettingKeys.DEFAULT_PROJECTS_FOLDER_PATH] = defaultProjectFolderPath; - - this.settings = new Settings(app, intoCpsAppFolder); - - - this.settings.load(); - // fill-in default values for yet unset values - for (var key in defaultValues) { - if (this.settings.getSetting(key) == null) { - let value: any = SettingKeys.DEFAULT_VALUES[key]; - this.settings.setSetting(key, value); - } - } - this.settings.save(); - - //Check for development mode and adjust settings to reflect this - if (this.settings.getValue(SettingKeys.DEVELOPMENT_MODE)) { - this.settings.setValue(SettingKeys.UPDATE_SITE, this.settings.getValue(SettingKeys.DEV_UPDATE_SITE)); - this.settings.setValue(SettingKeys.EXAMPLE_REPO, this.settings.getValue(SettingKeys.DEV_EXAMPLE_REPO)); - } else { - this.settings.setValue(SettingKeys.UPDATE_SITE, defaultValues[SettingKeys.UPDATE_SITE]); - this.settings.setValue(SettingKeys.EXAMPLE_REPO, defaultValues[SettingKeys.EXAMPLE_REPO]); - } - } - - public loadPreviousActiveProject(){ - let activeProjectPath = this.settings.getSetting(SettingKeys.ACTIVE_PROJECT); - if (activeProjectPath) { - try { - if (fs.accessSync(activeProjectPath, fs.constants.R_OK) !== null) { - - this.activeProject = this.loadProject(activeProjectPath); - } else { - console.error("Could not read the active project path from settings: " + activeProjectPath); - } - } catch (e) { - console.warn(e); - console.warn("Unable to set active project from settings: " + activeProjectPath); - } - } - this.coeProcess = new CoeProcess(this.settings); - - } - - public unloadProject() { - this.fireEvent(IntoCpsAppEvents.PROJECT_CHANGED); - - - this.settings.setSetting(SettingKeys.ACTIVE_PROJECT, null); - this.settings.save(); - } - - public getCoeProcess(): CoeProcess { - return this.coeProcess; - } - - public setWindow(win: Electron.BrowserWindow) { - this.window = win; - - } - - - - - private createAppFolderRoot(app: Electron.App): string { - // Create intoCpsApp folder - const userPath = function () { - if (app.getPath("exe").indexOf("electron-prebuilt") > -1) { - - console.log("Dev-mode: Using " + __dirname + " as user data path."); - return __dirname; - } - else { - let path = app.getPath("userData"); - console.log(`Npm start user data path: ${path}`); - return path; - } - } (); - - return Path.normalize(userPath + "/intoCpsApp"); - } - - private createDirectoryStructure(path: string) { - try { - fs.mkdirSync(path); - } catch (e) { - // the path probably already existed - } - } - - public getSettings(): Settings { - return this.settings; - } - - public getActiveProject(): IProject { - return this.activeProject; - } - - public setActiveProject(project: IProject) { - - if (project == null) - return; - - this.activeProject = project; - - // Fire an event to inform all controlls on main window that the project has changed - this.fireEvent(IntoCpsAppEvents.PROJECT_CHANGED); - - - this.settings.setSetting(SettingKeys.ACTIVE_PROJECT, project.getProjectConfigFilePath()); - this.settings.save(); - } - - - // Fires an ipc event using the window webContent if defined - private fireEvent(event: string) { - if (this.window != undefined) { - // Fire an event to inform all controlls on main window that the project has changed - this.window.webContents.send(IntoCpsAppEvents.PROJECT_CHANGED); - this.window.reload(); - console.info("fire event: " + event); - } - - - } - - - public createProject(name: string, path: string) { - let project = new Project(name, path, Path.normalize(path + "/.project.json")); - project.save(); - this.setActiveProject(project); - } - - // need to fire this to load the projects for the test - loadProject(path: string): IProject { - console.info("Loading project from: " + path); - let config = Path.normalize(path); - let content = fs.readFileSync(config, "utf8"); - // TODO load configuration containers and config files - let project = SerializationHelper.toInstance(new Project("", "", ""), content.toString()); - project.configPath = path; - project.rootPath = Path.dirname(path); - project.save() // create all the project folders, in case they don't exist. - return project; - } - - //get the global instance - public static getInstance(): IntoCpsApp { - let intoApp:IntoCpsApp = null; - if (remote){ - intoApp = remote.getGlobal("intoCpsApp"); - }else{ - intoApp = global.intoCpsApp; - } - return intoApp; - } - - // change topbar title - public static setTopName(s: string) { - var mainName = (document.getElementById(topBarNameId)); - mainName.innerText = s; - }; - - -} - -// http://stackoverflow.com/questions/29758765/json-to-typescript-class-instance -class SerializationHelper { - static toInstance(obj: T, json: string): T { - let jsonObj = JSON.parse(json); - - if (typeof (obj)["fromJSON"] === "function") { - (obj)["fromJSON"](jsonObj); - } - else { - for (let propName in jsonObj) { - (obj)[propName] = jsonObj[propName]; - } - } - - return obj; - } -} - - -export { IntoCpsApp }; diff --git a/src/IntoCpsAppEvents.ts b/src/IntoCpsAppEvents.ts deleted file mode 100644 index fa5a89c..0000000 --- a/src/IntoCpsAppEvents.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -export namespace IntoCpsAppEvents { - export var PROJECT_CHANGED = "project-changed-event"; - export var OPEN_CREATE_PROJECT_WINDOW = "open-create-project-window"; - export var OPEN_OPEN_PROJECT_WINDOW = "open-open-project-window"; -} diff --git a/src/IntoCpsAppMenuHandler.ts b/src/IntoCpsAppMenuHandler.ts deleted file mode 100644 index fa1c1cb..0000000 --- a/src/IntoCpsAppMenuHandler.ts +++ /dev/null @@ -1,75 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - - -import {IViewController} from "./iViewController"; - -export class IntoCpsAppMenuHandler { - openView: (htmlPath: string, callback?: (mainView: HTMLDivElement) => void | IViewController) => void; - openHTMLInMainView: (path: string, title: string) => void; - - openCoeView: (path: string) => void; - openMultiModel: (path: string) => void; - openSysMlDSEExport: (path: string) => void; - openSysMlExport: (path: string) => void; - openFmu: (path: string) => void; - openDseView: (path: string) => void; - openSigverView: (path: string) => void; - - deInitialize: () => boolean; - - createDse: (path: string) => void; - createDsePlain: (path: string) => void; - createSigverPlain: (path: string) => void; - createSysMLDSEConfig: (path: string) => void; - createMultiModel: (path: string, titleMsg? : string) => void; - createCoSimConfiguration: (path: string) => void; - - implodeConfig: (path: string) => void; - - createTDGProject: (path: string) => void; - createMCProject: (path: string) => void; - runRTTesterCommand: (commandSpec: any) => void; - runTest: (path: string) => void; - openLTLQuery: (path: string) => void; - openCTAbstractions: (path: string) => void; - showAddLTLQuery: (folder: string) => void; - openMCResult: (path: string) => void; - - deletePath: (path: string)=>void; - openWithSystemEditor: (path: string)=>void; - createMultiModelPlain: (titleMsg?: string) =>void; - rename: (path:string)=>void; - - showTraceView: () =>void; - openTraceability: () =>void; - exportOvertureFmu: (type: string, path: string)=>void; -} diff --git a/src/SystemUtil.ts b/src/SystemUtil.ts deleted file mode 100644 index 3aedc06..0000000 --- a/src/SystemUtil.ts +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - - -export function openPath(path: string) -{ - var command: string = null; - - //http://stackoverflow.com/questions/8683895/how-do-i-determine-the-current-operating-system-with-node-js - if (process.platform === 'darwin') { - command = "open"; - } else if (process.platform === 'win32') { - command = "explorer.exe" - } else if (process.platform === 'linux') { - command = "nautilus" - } - - if (command != null) { - var spawn = require('child_process').spawn; - - var child = spawn(command, [path], { - detached: true, - shell: false, - // cwd: childCwd - }); - child.unref(); - - child.stdout.on('data', function (data: any) { - console.log('stdout: ' + data); - - }); - child.stderr.on('data', function (data: any) { - console.log('stderr: ' + data); - - }); - child.on('close', function (code: any) { - console.log('closing code: ' + code); - - }); - - } -} diff --git a/src/angular2-app/app.component.ts b/src/angular2-app/app.component.ts deleted file mode 100644 index 13a9316..0000000 --- a/src/angular2-app/app.component.ts +++ /dev/null @@ -1,124 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import { Component, OnInit, NgZone } from '@angular/core'; -import {FileSystemService} from "./shared/file-system.service"; -/* import {Http} from "@angular/http"; */ -import { HttpClient } from '@angular/common/http'; -import {SettingsService} from "./shared/settings.service"; -import {CoeSimulationService} from "./coe/coe-simulation.service"; -import {NavigationService} from "./shared/navigation.service"; -import { MaestroApiService } from './shared/maestro-api.service'; - - - - -interface MyWindow extends Window { - ng2app: AppComponent; -} - -declare let window: MyWindow; - -// Main application component. -// Handles routing between the pages that use Angular 2. - -@Component({ - selector: 'app', - template: ` - - - - ` -}) -export class AppComponent implements OnInit { - private page:string; - private path:string; - - constructor(public navigationService:NavigationService, - private http:HttpClient, - private settings:SettingsService, - private fileSystem:FileSystemService, - private zone:NgZone) { - console.log("appComponent"); - - } - - ngOnInit() { - // Expose the Angular 2 application for the rest of the INTO-CPS application - window.ng2app = this; - } - - // Allows accessing the coe simulation service outside of Angular. - makeCoeSimulationService() { - return new CoeSimulationService(this.settings, this.fileSystem, this.zone, new MaestroApiService(this.http, this.settings)); - } - - openCOE(path: string):void { - this.zone.run(() => { - this.path = path; - this.page = "coe"; - }); - } - - openMultiModel(path: string):void { - this.zone.run(() => { - this.path = path; - this.page = "multiModel"; - }); - } - - openTraceability():void { - this.zone.run(() => { - this.page = "tr"; - }); - } - - openDSE(path: string):void { - this.zone.run(() => { - this.path = path; - this.page = "dse"; - }); - } - - openSV(path: string):void { - this.zone.run(() => { - this.path = path; - this.page = "sv"; - }); - } - - closeAll():void { - /* this.zone.run(() => { */ - this.path = null; - this.page = null; - /* }); */ - } -} diff --git a/src/angular2-app/app.module.ts b/src/angular2-app/app.module.ts deleted file mode 100644 index 6f0c3b3..0000000 --- a/src/angular2-app/app.module.ts +++ /dev/null @@ -1,66 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ -import { NgModule, NgZone } from '@angular/core' -import { BrowserModule } from '@angular/platform-browser' - -import { AppComponent } from './app.component' -import { FormsModule, ReactiveFormsModule } from "@angular/forms"; -/* import { Http } from "@angular/http"; */ -import {FileSystemService} from "./shared/file-system.service"; -import {SettingsService} from "./shared/settings.service"; -import {NavigationService} from "./shared/navigation.service"; -/* import {MmPageComponent} from "./mm/mm-page.component"; */ - - -/*import {CoePageComponent} from "./coe/coe-page.component"; -import {MmConfigurationComponent} from "./mm/mm-configuration.component"; -import {MmOverviewComponent} from "./mm/mm-overview.component"; -import {PanelComponent} from "./shared/panel.component"; */ -import { DseConfigurationComponent } from './dse/dse-configuration.component'; -import {DsePageComponent} from "./dse/dse-page.component"; -import {MmModule} from "./mm/mm.module" -import {COEModule} from "./coe/coe.module" -import { HttpClientModule } from '@angular/common/http'; -import { SharedModule } from './shared/shared.module'; -import { DseCoeLaunchComponent, SafePipe } from './dse/dse-coe-launch.component'; -import {SigverPageComponent} from "./sigver/sigver-page.component"; -import {SigverConfigurationComponent} from "./sigver/sigver-configuration.component"; -import {SigverCoeInteractionComponent} from "./sigver/sigver-coe-interaction.component"; - -@NgModule({ - imports: [ BrowserModule, HttpClientModule, FormsModule, - MmModule, COEModule, ReactiveFormsModule, SharedModule], // module dependencies - declarations: [AppComponent , SafePipe, DsePageComponent, DseConfigurationComponent, DseCoeLaunchComponent, SigverPageComponent, SigverConfigurationComponent, SigverCoeInteractionComponent], // components and directives - bootstrap: [AppComponent], // root component - providers: [FileSystemService, SettingsService, NavigationService], // services - exports: [] -}) -export class AppModule {} diff --git a/src/angular2-app/coe/CoeViewController.ts b/src/angular2-app/coe/CoeViewController.ts deleted file mode 100644 index 9061310..0000000 --- a/src/angular2-app/coe/CoeViewController.ts +++ /dev/null @@ -1,64 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import {ViewController} from "../../iViewController"; -import IntoCpsApp from "../../IntoCpsApp"; -import {AppComponent} from "../app.component"; -import * as Path from 'path'; - -interface MyWindow extends Window { - ng2app: AppComponent; -} - -declare var window: MyWindow; - -export class CoeViewController extends ViewController { - constructor(private view: HTMLDivElement, private path:string) { - super(view); - } - - initialize() { - $(this.view).css('height',0); - let coeFolder = Path.join(this.path,"../"); - IntoCpsApp.setTopName(Path.basename(Path.join(coeFolder,"../"))+" > "+Path.basename(coeFolder)); - window.ng2app.openCOE(this.path); - } - - deInitialize() { - if (window.ng2app.navigationService.canNavigate()) { - window.ng2app.closeAll(); - $(this.view).css('height',"calc(100% - 80px)"); - return true; - } - - return false; - } -} diff --git a/src/angular2-app/coe/coe-configuration.component.html b/src/angular2-app/coe/coe-configuration.component.html deleted file mode 100644 index b1cf9a0..0000000 --- a/src/angular2-app/coe/coe-configuration.component.html +++ /dev/null @@ -1,503 +0,0 @@ -
- - - -
-
-
- -
-
- -
-

- {{ config.startTime }} -

- -
This field is required.
-
Only numbers are allowed.
-
Start time is after end time.
-
-
- -
- -
-

- {{ config.endTime }} -

- -
This field is required.
-
Only numbers are allowed.
-
End time is before start time.
-
-
- -
- -
-

- {{ config.algorithm.name }} -

- -
-
- -
-
- -
-
-
- -
-

- {{ config.algorithm.size }} -

- -
This field is required.
-
Only numbers are allowed.
-
-
-
-
- -
-
-
- -
-

- {{ config.algorithm.initSize }} -

- -
This field is required.
-
Only numbers are allowed.
-
-
- -
- -
-

- {{ config.algorithm.sizeMin }} -

- -
This field is required.
-
Only numbers are allowed.
-
-
- -
- -
-

- {{ config.algorithm.sizeMax }} -

- -
This field is required.
-
Only numbers are allowed.
-
-
- -
- -
-
- - - - -
-
-
-
- -
-
-
- - {{ getConstraintName(constraint) }} -
-
- - - - - - - - -
-
-
-
-
-
-
-
- -
-
-

- Visibility -

-
-
-
- -
-

- {{ config.visible }} -

- -
-
- -
- -
-

- {{ config.loggingOn }} -

- -
-
- -
- -
-

- {{ config.enableAllLogCategoriesPerInstance }} -

- -
-
- -
- -
-

- {{ config.overrideLogLevel }} -

- -
-
-
-
- -
- -
-
- -
-

- {{ config.stabalization }} -

- -
-
- -
- -
-

- {{ config.global_absolute_tolerance }} -

- -
This field is required.
-
Only numbers are allowed.
-
-
- -
- -
-

- {{ config.global_relative_tolerance }} -

- -
This field is required.
-
Only numbers are allowed.
-
-
-
-
- -
- -
-
- -
-

- {{ config.livestreamInterval }} -

- -
This field is required.
-
Only numbers are allowed.
-
-
-
- -
-

- {{ config.liveGraphColumns }} -

- -
This field is required.
-
Only numbers are allowed.
-
-
-
- -
-

- {{ config.liveGraphVisibleRowCount }} -

- -
This field is required.
-
Only numbers are allowed.
-
-
- -
- - -
-
-
-
- - Graph Variables -
-
- -
-
-
-
-
- -
- -
- -
-

- All connected outputs are saved by default. -

-
-
-
- -
- -
-
- -
-
-
- -
-
-
- -
-
-
-
-
-
-
-
-
- -
-
-

- Others -

-
-
-
- -
-

- {{ config.simulationProgramDelay }} -

- -
-
-
- -
- -
-

- {{ config.parallelSimulation }} -

- -
-
-
-
- -
- -
-
- -
-

- {{ config.postProcessingScript }} -

- -
-
-
-
-
-
- -
- -
- Please fix the following issues before saving. -
- {{ warning.message }} -
-
-
- - - -
diff --git a/src/angular2-app/coe/coe-configuration.component.ts b/src/angular2-app/coe/coe-configuration.component.ts deleted file mode 100644 index 3f1372a..0000000 --- a/src/angular2-app/coe/coe-configuration.component.ts +++ /dev/null @@ -1,323 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import { Component, Input, EventEmitter, Output, NgZone } from "@angular/core"; -import { Validators, FormArray, FormControl, FormGroup } from "@angular/forms"; -import IntoCpsApp from "../../IntoCpsApp"; -import { - CoSimulationConfig, - ICoSimAlgorithm, - FixedStepAlgorithm, - VariableStepAlgorithm, - ZeroCrossingConstraint, - BoundedDifferenceConstraint, - SamplingRateConstraint, - VariableStepConstraint, - FmuMaxStepSizeConstraint, - LiveGraph, -} from "../../intocps-configurations/CoSimulationConfig"; -import { ScalarVariable, CausalityType, Instance, InstanceScalarPair, ScalarVariableType } from "./models/Fmu"; -import { lessThanValidator2, numberValidator, uniqueGroupPropertyValidator } from "../shared/validators"; -import { NavigationService } from "../shared/navigation.service"; -import { WarningMessage } from "../../intocps-configurations/Messages"; - -const dialog = require("electron").remote.dialog; - -@Component({ - selector: "coe-configuration", - templateUrl: "./angular2-app/coe/coe-configuration.component.html", -}) -export class CoeConfigurationComponent { - private _path: string; - private _allowChangingAlgorithm: boolean = true; - private _editing: boolean = false; - - public Fmu_x = require("./models/Fmu"); - - @Input() - public set allow_changing_algorithm(allowChangingAlgorithm: boolean) { - this._allowChangingAlgorithm = allowChangingAlgorithm; - this.editAlgorithm = allowChangingAlgorithm; - } - - public editAlgorithm: boolean = false; - - @Input() - set path(path: string) { - this._path = path; - - if (path) this.parseConfig(); - } - get path(): string { - return this._path; - } - - @Output() - change = new EventEmitter(); - - form: FormGroup; - algorithms: ICoSimAlgorithm[] = []; - algorithmFormGroups = new Map(); - outputPorts: Array = []; - newConstraint: new (...args: any[]) => VariableStepConstraint; - - set editing(editing: boolean) { - this._editing = editing; - this.editAlgorithm = this._allowChangingAlgorithm && this.editing; - } - - get editing(): boolean { - return this._editing; - } - - isLoaded: boolean = false; - logVariablesSearchName: string = ""; - parseError: string = null; - warnings: WarningMessage[] = []; - loglevels: string[] = ["Not set", "ERROR", "WARN", "INFO", "DEBUG", "TRACE"]; - - // liveGraphs: LiveGraph[]; - //The variable zeroCrossings is necessary to give different names to the radiobutton groups in the different zeroCrossing constraints. - // Otherwise they will all be connected. - zeroCrossings: number = 0; - - private config: CoSimulationConfig; - - private algorithmConstructors = [FixedStepAlgorithm, VariableStepAlgorithm]; - - private constraintConstructors = [ZeroCrossingConstraint, BoundedDifferenceConstraint, SamplingRateConstraint, FmuMaxStepSizeConstraint]; - - constructor(private zone: NgZone, private navigationService: NavigationService) { - this.navigationService.registerComponent(this); - } - - private parseConfig() { - let project = IntoCpsApp.getInstance().getActiveProject(); - - CoSimulationConfig.parse(this.path, project.getRootFilePath(), project.getFmusPath()) - .then( - (config) => { - this.config = config; - - this.warnings = this.config.validate(); - - this.parseError = null; - - // Create an array of the algorithm from the coe config and a new instance of all other algorithms - this.algorithms = this.algorithmConstructors.map((constructor) => (config.algorithm instanceof constructor ? config.algorithm : new constructor())); - // Create an array of formGroups for the algorithms - this.algorithms.forEach((algorithm) => { - this.algorithmFormGroups.set(algorithm, algorithm.toFormGroup()); - }); - // Create an array of all output ports on all instances - this.outputPorts = this.config.multiModel.fmuInstances - .map((instance) => - instance.fmu.scalarVariables - .filter((sv) => sv.type === ScalarVariableType.Real && (sv.causality === CausalityType.Output || sv.causality === CausalityType.Parameter)) - .map((sv) => this.config.multiModel.getInstanceScalarPair(instance.fmu.name, instance.name, sv.name)) - ) - .reduce((a, b) => a.concat(...b), []); - - // Create a form group for validation - this.form = new FormGroup( - { - startTime: new FormControl(config.startTime, [Validators.required, numberValidator]), - endTime: new FormControl(config.endTime, [Validators.required, numberValidator]), - liveGraphs: new FormArray( - config.liveGraphs.map((g) => g.toFormGroup()), - uniqueGroupPropertyValidator("id") - ), //, uniqueGroupPropertyValidator("id") - livestreamInterval: new FormControl(config.livestreamInterval, [Validators.required, numberValidator]), - liveGraphColumns: new FormControl(config.liveGraphColumns, [Validators.required, numberValidator]), - liveGraphVisibleRowCount: new FormControl(config.liveGraphVisibleRowCount, [Validators.required, numberValidator]), - algorithm: this.algorithmFormGroups.get(this.config.algorithm), - global_absolute_tolerance: new FormControl(config.global_absolute_tolerance, [Validators.required, numberValidator]), - global_relative_tolerance: new FormControl(config.global_relative_tolerance, [Validators.required, numberValidator]), - }, - lessThanValidator2("startTime", "endTime"), - null - ); - console.log("Parsing finished!"); - this.isLoaded = true; - }, - (error) => - this.zone.run(() => { - this.parseError = error; - }) - ) - .catch((error) => console.error(`Error during parsing of config: ${error}`)); - } - - public setPostProcessingScript(config: CoSimulationConfig, path: string) { - config.postProcessingScript = config.getProjectRelativePath(path); - } - - onNavigate(): boolean { - if (!this.editing) return true; - - if (this.form.valid) { - if (confirm("Save your work before leaving?")) this.onSubmit(); - - return true; - } else { - return confirm("The changes to the configuration are invalid and can not be saved. Continue anyway?"); - } - } - - onAlgorithmChange(algorithm: ICoSimAlgorithm) { - this.zone.run(() => { - this.config.algorithm = algorithm; - - this.form.removeControl("algorithm"); - this.form.addControl("algorithm", this.algorithmFormGroups.get(algorithm)); - }); - } - - onSubmit() { - if (!this.editing) return; - - this.warnings = this.config.validate(); - - let override = false; - - if (this.warnings.length > 0) { - let res = dialog.showMessageBoxSync({ title: "The multi-model for this configuration has changed!", message: "Do you want to override it?", buttons: ["No", "Yes"] }); - if (res == 1) { - override = true; - this.warnings = []; - } - } - - if (override) { - this.config - .saveOverride() - .then(() => this.change.emit(this.path)) - .catch((error) => console.error("error when overriding save: " + error)); - } else { - this.config - .save() - .then(() => this.change.emit(this.path)) - .catch((error) => console.error("error when saving: " + error)); - } - - this.editing = false; - } - - getOutputs(scalarVariables: Array) { - return scalarVariables.filter((variable) => variable.causality === CausalityType.Output || variable.causality === CausalityType.Local); - } - - getFilterTypes(scalarVariables: Array, types: ScalarVariableType[]) { - return scalarVariables.filter((v) => types.indexOf(v.scalarVariable.type) > -1); - } - - restrictToCheckedLogVariables(instance: Instance, scalarVariables: Array) { - return scalarVariables.filter((variable) => this.isLogVariableChecked(instance, variable)); - } - - addConstraint() { - if (!this.newConstraint) return; - - let algorithm = this.config.algorithm; - let formArray = this.form.get("algorithm").get("constraints"); - let constraint = new this.newConstraint(); - algorithm.constraints.push(constraint); - formArray.push(constraint.toFormGroup()); - } - - removeConstraint(constraint: VariableStepConstraint) { - let algorithm = this.config.algorithm; - let formArray = this.form.get("algorithm").get("constraints"); - let index = algorithm.constraints.indexOf(constraint); - - algorithm.constraints.splice(index, 1); - formArray.removeAt(index); - } - - addLiveGraph() { - let g = new LiveGraph(); - this.config.liveGraphs.push(g); - let formArray = this.form.get("liveGraphs"); - formArray.push(g.toFormGroup()); - } - - removeGraph(graph: LiveGraph) { - let formArray = this.form.get("liveGraphs"); - let index = this.config.liveGraphs.indexOf(graph); - this.config.liveGraphs.splice(index, 1); - formArray.removeAt(index); - } - - getConstraintName(constraint: any) { - if (constraint === ZeroCrossingConstraint || constraint instanceof ZeroCrossingConstraint) return "Zero Crossing"; - if (constraint === FmuMaxStepSizeConstraint || constraint instanceof FmuMaxStepSizeConstraint) return "FMU Max Step Size"; - - if (constraint === BoundedDifferenceConstraint || constraint instanceof BoundedDifferenceConstraint) return "Bounded Difference"; - - if (constraint === SamplingRateConstraint || constraint instanceof SamplingRateConstraint) return "Sampling Rate"; - } - - isLogVariableChecked(instance: Instance, output: ScalarVariable) { - let variables = this.config.logVariables.get(instance); - - if (!variables) return false; - - return variables.indexOf(output) !== -1; - } - - isLocal(variable: ScalarVariable): boolean { - return variable.causality === CausalityType.Local; - } - - getScalarVariableTypeName(type: ScalarVariableType) { - return ScalarVariableType[type]; - } - - onLogVariableChange(enabled: boolean, instance: Instance, output: ScalarVariable) { - let variables = this.config.logVariables.get(instance); - - if (!variables) { - variables = []; - this.config.logVariables.set(instance, variables); - } - - if (enabled) variables.push(output); - else { - variables.splice(variables.indexOf(output), 1); - - if (variables.length == 0) this.config.logVariables.delete(instance); - } - } - - onLogVariablesKey(event: any) { - this.logVariablesSearchName = event.target.value; - } -} diff --git a/src/angular2-app/coe/coe-page.component.html b/src/angular2-app/coe/coe-page.component.html deleted file mode 100644 index 1de3121..0000000 --- a/src/angular2-app/coe/coe-page.component.html +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/src/angular2-app/coe/coe-page.component.ts b/src/angular2-app/coe/coe-page.component.ts deleted file mode 100644 index 4bcfb45..0000000 --- a/src/angular2-app/coe/coe-page.component.ts +++ /dev/null @@ -1,41 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import {Component, Input} from "@angular/core"; - -@Component({ - selector: "coe-page", - templateUrl: "./angular2-app/coe/coe-page.component.html", -}) -export class CoePageComponent { - @Input() - path:string; -} diff --git a/src/angular2-app/coe/coe-simulation.component.html b/src/angular2-app/coe/coe-simulation.component.html deleted file mode 100644 index 79d72d6..0000000 --- a/src/angular2-app/coe/coe-simulation.component.html +++ /dev/null @@ -1,109 +0,0 @@ -
- The multi model configuration is not valid. -
- {{ warning.message }} -
-
- -
- The co-simulation configuration is not valid. It can be re-generated by - editing and saving. -
- {{ warning.message }} -
-
- -
- The co-simulation responed with a warning or Error: -
- {{ warning.message }} -
-
- -
-
- -
-
- -
-
- -
-
- {{ coeSimulation.progress }}% -
-
- -
- {{ httpErrorMessage }} -
- -
-
-
-
Graph {{ i + 1 }}: {{ g.title }}
- - -
-
-
- -
-
-
Post-script output
-
-
-

{{ postScriptOutput }}

-
-
-

{{ postScriptOutput }}

-
-
-
-
- -
- -
- -
diff --git a/src/angular2-app/coe/coe-simulation.component.ts b/src/angular2-app/coe/coe-simulation.component.ts deleted file mode 100644 index c8e86d0..0000000 --- a/src/angular2-app/coe/coe-simulation.component.ts +++ /dev/null @@ -1,235 +0,0 @@ - - -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ -import { Component, Input, NgZone, OnDestroy } from "@angular/core"; -import { CoSimulationConfig } from "../../intocps-configurations/CoSimulationConfig"; -/* import { LineChartComponent } from "../shared/line-chart.component"; */ -import { CoeSimulationService } from "./coe-simulation.service"; -/* import { Http } from "@angular/http"; */ - -import IntoCpsApp from "../../IntoCpsApp"; -import { Message, WarningMessage } from "../../intocps-configurations/Messages"; -// needs an alternativ!! -/* import { openCOEServerStatusWindow } from "../../menus"; */ -import { shell } from "electron"; -import { Subscription } from 'rxjs'; -import { maestroVersions } from "../shared/maestro-api.service"; - -@Component({ - selector: "coe-simulation", - providers: [CoeSimulationService], -/* directives: [LineChartComponent], */ - templateUrl: "./angular2-app/coe/coe-simulation.component.html" -}) -export class CoeSimulationComponent implements OnDestroy { - private _path: string; - private _masterModel: string = ""; - private _resultsDir: string = ""; - private parsing: boolean = false; - private _coeIsOnlineSub: Subscription; - private correctCoeVersion: boolean = true; - - @Input() - external_disable_simulation: boolean = false; - - @Input() - required_coe_version: maestroVersions = undefined; - - @Input() - set resultsdir(resultsDir: string) { - this._resultsDir = resultsDir; - } - - get resultsdir(): string { - return this._resultsDir; - } - - @Input() - set mastermodel(masterModel: string) { - this._masterModel = masterModel; - } - - get mastermodel(): string { - return this._masterModel; - } - - @Input() - set path(path: string) { - this._path = path; - - if (path) { - this.parseConfig(); - - if (this.coeSimulation) this.coeSimulation.reset(); - } - } - get path(): string { - return this._path; - } - - online: boolean = false; - hasHttpError: boolean = false; - httpErrorMessage: string = ""; - url: string = ""; - version: string = ""; - config: CoSimulationConfig; - mmWarnings: WarningMessage[] = []; - coeWarnings: WarningMessage[] = []; - simWarnings: WarningMessage[] = []; - hasPostScriptOutput = false; - hasPostScriptOutputError = false; - postScriptOutput = ""; - simulating: boolean = false; - hasRunSimulation: boolean = false; - - constructor( - private coeSimulation: CoeSimulationService, - private zone: NgZone - ) { - this._coeIsOnlineSub = coeSimulation.coeIsOnlineObservable.subscribe(isOnline => { - if(this.required_coe_version) { - this.correctCoeVersion = this.required_coe_version == this.coeSimulation.getMaestroVersion(); - } - this.online = isOnline; - } ); - } - - ngOnDestroy() { - this._coeIsOnlineSub.unsubscribe(); - } - - parseConfig() { - let project = IntoCpsApp.getInstance().getActiveProject(); - this.parsing = true; - - CoSimulationConfig.parse( - this.path, - project.getRootFilePath(), - project.getFmusPath() - ).then(config => - this.zone.run(() => { - this.config = config; - - this.mmWarnings = this.config.multiModel.validate(); - this.coeWarnings = this.config.validate(); - - this.parsing = false; - }) - ).catch(error => console.error("error when parsing co-sim-config: " + error)); - } - - canRun() { - return ( - this.online && - this.mmWarnings.length === 0 && - this.coeWarnings.length === 0 && - !this.parsing && - !this.simulating && - !this.external_disable_simulation && - this.correctCoeVersion - ); - } - - runSimulation() { - this.zone.run(() => { - this.hasHttpError = false; - this.hasPostScriptOutput = false; - this.hasPostScriptOutputError = false; - this.postScriptOutput = ""; - this.simulating = true; - }); - - const errorReportCB = (hasError: boolean, message: string, hasWarning: boolean, stopped: boolean) => { - this.zone.run(() => { - this.errorHandler(hasError, message, hasWarning, stopped); - }); - } - const simCompletedCB = () => { - this.zone.run(() => { - this.hasRunSimulation = true; - this.simulating = false; - }); - } - const postScriptOutputReportCB = (hasError: boolean, message: string) => { - this.zone.run(() => { - this.postScriptOutputHandler(hasError, message); - }); - } - - this.coeSimulation.setSimulationCallBacks(errorReportCB, simCompletedCB, postScriptOutputReportCB); - - if(this._masterModel){ - this.coeSimulation.startSigverSimulation(this.config, this.mastermodel, this._resultsDir); - } else { - this.coeSimulation.startSimulation(this.config); - } - } - - onOpenResultsFolder() { - shell.openPath(this.coeSimulation.getResultsDir()); - } - - stopSimulation() { - this.zone.run(() => { - this.simulating = false; - }); - this.coeSimulation.stop(); - } - - errorHandler(hasError: boolean, message: string, hasWarning: boolean = false, stopped?: boolean) { - if(stopped) { - var warning = new Message("Co-simulation stopped. COE status OK"); - this.simWarnings.push(warning); - setTimeout(()=>{ - this.simWarnings.pop(); - }, 5000); - this.simulating = false; - } else if(!stopped && hasWarning) { - var warning = new Message("Unknown error, see the console for more info."); - this.simWarnings.push(warning); - console.warn(message); - setTimeout(()=>{ - this.simWarnings.pop(); - }, 5000); - this.simulating = false; - } - this.hasHttpError = hasError; - this.httpErrorMessage = message; - if (hasError) this.simulating = false; - } - - postScriptOutputHandler(hasError: boolean, message: string) { - this.hasPostScriptOutput = true; - this.hasPostScriptOutputError = hasError; - this.postScriptOutput = message; - } -} diff --git a/src/angular2-app/coe/coe-simulation.service.ts b/src/angular2-app/coe/coe-simulation.service.ts deleted file mode 100644 index 46fea6a..0000000 --- a/src/angular2-app/coe/coe-simulation.service.ts +++ /dev/null @@ -1,393 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import { FileSystemService } from "../shared/file-system.service"; -import { SettingsService, SettingKeys } from "../shared/settings.service"; -import { Fmu } from "./models/Fmu"; -import { CoeConfig } from "./models/CoeConfig"; -import * as Path from "path"; -import { BehaviorSubject, Observable, Subject, Subscription } from "rxjs"; -import { Injectable, NgZone, OnDestroy } from "@angular/core"; -import { CoSimulationConfig, LiveGraph } from "../../intocps-configurations/CoSimulationConfig"; -import { storeResultCrc } from "../../intocps-configurations/ResultConfig"; -import * as fs from 'fs' -import * as child_process from 'child_process' -import DialogHandler from "../../DialogHandler" -import { Graph } from "../shared/graph" -import { Deferred } from "../../deferred" -import { MaestroApiService, simulationEndpoints } from "../shared/maestro-api.service"; - - -@Injectable() -export class CoeSimulationService implements OnDestroy { - progress: number = 0; - errorReport: (hasError: boolean, message: string, hasWarning?: boolean, stopped?: boolean) => void = function () { }; - simulationCompletedHandler: () => void = function () { }; - postProcessingOutputReport: (hasError: boolean, message: string) => void = function () { }; - - private _simulationSessionId: string = ""; - private _resultDir: string; - private _resultPath: string; - private _coeConfigPath: string; - private _mmConfigPath: string; - private masterModel: string; - private config: CoSimulationConfig; - private graphMaxDataPoints: number = 100; - private _coeIsOnlineSub: Subscription; - private _coeIsOnline = new Subject(); - - public graph: Graph = new Graph(); - public externalGraphs: Array = new Array(); - public coeIsOnlineObservable: Observable = this._coeIsOnline.asObservable(); - public coeUrl: string; - - set resultDir(resultsDir: string) { - this._resultDir = resultsDir; - this._resultPath = Path.normalize(`${this.resultDir}/outputs.csv`); - this._coeConfigPath = Path.normalize(`${this.resultDir}/coe.json`); - this._mmConfigPath = Path.normalize(`${this.resultDir}/mm.json`); - } - - get resultDir(): string { - return this._resultDir; - } - - constructor( - settings: SettingsService, - private fileSystem: FileSystemService, - private zone: NgZone, - private maestroApiService: MaestroApiService) { - - this.graphMaxDataPoints = settings.get(SettingKeys.GRAPH_MAX_DATA_POINTS); - this.graph.setProgressCallback((progress: number) => { this.progress = progress }); - this.graph.setGraphMaxDataPoints(this.graphMaxDataPoints); - - this.coeUrl = maestroApiService.coeUrl; - this._coeIsOnlineSub = this.maestroApiService.startMonitoringOnlineStatus(isOnline => this._coeIsOnline.next(isOnline)); - } - - ngOnDestroy(): void { - this.maestroApiService.stopMonitoringOnlineStatus(this._coeIsOnlineSub); - } - - getCoeVersion() { - return this.maestroApiService.coeVersionNumber; - } - - getMaestroVersion() { - return this.maestroApiService.getMaestroVersion(); - } - - reset() { - this.progress = 0; - this.zone.run(() => { - this.graph.reset(); - }); - } - - openCOEServerStatusWindow( - data: string = "", - show: boolean = true - ) { - this.maestroApiService.launchCOE(); - } - - getResultsDir(): string { - return this.resultDir; - } - - stop(): Promise { - return new Promise((resolve, reject) => { - this.maestroApiService.stopSimulation(this._simulationSessionId).then(() => resolve()).catch((res: Response) => reject(res.statusText)); - }); - } - - startSigverSimulation(config: CoSimulationConfig, masterModel: string, resultsDir: string) { - this.config = config; - this.masterModel = masterModel; - this.resultDir = Path.normalize(`${resultsDir}/R_${this.getDateString()}`); - this.initialize().then(() => { - const simulationData: any = { - startTime: this.config.startTime, - endTime: this.config.endTime, - reportProgress: true, - liveLogInterval: this.config.livestreamInterval, - masterModel: this.masterModel - }; - - this.handleSimulationFinished(this.prepareGraphAndrunSimulation(simulationEndpoints.simulate, simulationData)); - }).catch(err => this.errorHandler(err)); - } - - startSimulation(config: CoSimulationConfig) { - this.config = config; - const currentDir = Path.dirname(this.config.sourcePath); - this.resultDir = Path.normalize(`${currentDir}/R_${this.getDateString()}`); - this.initialize().then(() => { - const simulationData: any = { - startTime: this.config.startTime, - endTime: this.config.endTime, - reportProgress: true, - liveLogInterval: this.config.livestreamInterval - }; - - // enable logging for all log categories - const logCategories: any = new Object(); - let self = this; - this.config.multiModel.fmuInstances.forEach(instance => { - let key: any = instance.fmu.name + "." + instance.name; - - if (self.config.enableAllLogCategoriesPerInstance) { - logCategories[key] = instance.fmu.logCategories; - } - }); - Object.assign(simulationData, { logLevels: logCategories }); - - this.handleSimulationFinished(this.prepareGraphAndrunSimulation(simulationEndpoints.simulate, simulationData)); - }).catch(err => this.errorHandler(err)); - } - - errorHandler(err: { error?: string, statusText?: string, status?: number }, stopped?: boolean) { - console.warn(err); - if (stopped) { - this.progress = 0; - this.errorReport(false, "Error: " + err.statusText, true, true) - } else if (!stopped && err.status == 200) { - this.progress = 0; - this.errorReport(false, "Error: " + err.statusText, true) - } else { - this.progress = 0; - console.log("err: ", err); - if('error' in err){ - let errorMessage = typeof err.error === 'string' ? err.error : ''; - this.errorReport(true, "Error: " + err.statusText + (errorMessage ? " - " + errorMessage : "") + ". Check CoE Server and/or CoE Log for more details."); - } else{ - this.errorReport(true, "Error: " + err.statusText); - } - } - } - - setSimulationCallBacks(errorReport: (hasError: boolean, message: string, hasWarning: boolean, stopped: boolean) => void, simCompleted: () => void, postScriptOutputReport: (hasError: boolean, message: string) => void) { - this.errorReport = errorReport; - this.simulationCompletedHandler = simCompleted; - this.postProcessingOutputReport = postScriptOutputReport; - } - - private handleSimulationFinished(simulationPromise: Promise) { - simulationPromise.then(() => { - // If simulation finished successfully get the plain results - this.maestroApiService.getPlainResult(this._simulationSessionId).then(async (resultsString: string) => { - await Promise.all([ - this.fileSystem.writeFile(this._resultPath, resultsString), - this.fileSystem.copyFile(this.config.sourcePath, this._coeConfigPath), - this.fileSystem.copyFile(this.config.multiModel.sourcePath, this._mmConfigPath) - ]).then(async () => { - // Store the results and run the post processing script - storeResultCrc(this._resultPath, this.config); - this.executePostProcessingScript(this._resultPath); - }).catch(err => console.log("Unable to write plain results to file: " + err)); - }).catch((err: Response) => this.errorHandler(err)); - }).finally(() => - // Always get whatever results have been generated - this.maestroApiService.getResults(Path.normalize(`${this.resultDir}/simulation_results.zip`), this._simulationSessionId).finally(() => { - // End the session - this.maestroApiService.destroySession(this._simulationSessionId).catch((err: Response) => console.error("Could not destroy session: " + err.statusText)); - }) - .catch((err: Response) => { - console.error("Could retrieve results: " + err.statusText); - }) - ); - } - - private getDateString(): string { - const now = new Date(); - const nowAsUTC = new Date(Date.UTC(now.getFullYear(), - now.getMonth(), - now.getDate(), - now.getHours(), - now.getMinutes(), - now.getSeconds(), - now.getMilliseconds()) - ); - return nowAsUTC.toISOString().replace(/-/gi, "_") - .replace(/T/gi, "-") - .replace(/Z/gi, "") - .replace(/:/gi, "_") - .replace(/\./gi, "_"); - } - - private async initialize(): Promise { - this.reset(); - this.graph.setCoSimConfig(this.config); - this.graph.initializeDatasets(); - this.maestroApiService.getCoeProcess().prepareSimulation(); - this.errorReport(false, ""); - return this.maestroApiService.createSimulationSession().then(async sessionId => { - this._simulationSessionId = sessionId; - if (this.maestroApiService.isRemoteCoe()) { - await this.prepareAndUploadFmus().catch(err => this.errorHandler(err)); - } - return this.prepareAndInitializeCoe(); - }); - } - - private prepareAndUploadFmus(): Promise { - return new Promise((resolve, reject) => { - const formData = new FormData(); - - this.config.multiModel.fmus.forEach((value: Fmu) => { - this.fileSystem.readFile(value.path).then(content => { - formData.append( - 'file', - new Blob([content], { type: "multipart/form-data" }), - value.path - ); - }); - }); - - this.maestroApiService.uploadFmus(formData, this._simulationSessionId).then(() => resolve()).catch((err: Response) => reject(err)); - }); - } - - private prepareAndInitializeCoe(): Promise { - return new Promise((resolve, reject) => { - const configJson = new CoeConfig(this.config, this.maestroApiService.isRemoteCoe()).toJSON(); - Promise.all([ - this.fileSystem.mkdir(this.resultDir), - this.maestroApiService.initializeCoe(configJson, this._simulationSessionId) - ]).catch(err => reject(err)).finally(() => { - this.fileSystem.writeFile(Path.join(this.resultDir, "config.json"), configJson); - resolve(); - }) - }); - } - - private prepareGraphAndrunSimulation(simulationEndpoint: simulationEndpoints, simulationData: any): Promise { - let deferreds = new Array>(); - - this.graph.graphMap.forEach((value: BehaviorSubject, key: LiveGraph) => { - if (key.externalWindow) { - let deferred: Deferred = new Deferred(); - deferreds.push(deferred.promise); - let graphObj = key.toObject(); - graphObj.webSocket = this.maestroApiService.getWebSocketSessionUrl(this._simulationSessionId); - graphObj.graphMaxDataPoints = this.graphMaxDataPoints; - console.log(graphObj); - let dh = new DialogHandler("angular2-app/coe/graph-window/graph-window.html", 800, 600); - dh.openWindow(JSON.stringify(graphObj), true); - this.externalGraphs.push(dh); - dh.win.webContents.on("did-finish-load", () => { - dh.win.setTitle("Plot: " + key.title); - deferred.resolve(); - }); - } - }); - return new Promise((resolve, reject) => { - Promise.all(deferreds).then(() => { - // Do not start the simulation before the websocket is open. - this.graph.webSocketOnOpenCallback = () => this.fileSystem.writeFile(Path.join(this.resultDir, "config-simulation.json"), JSON.stringify(simulationData)) - .then(() => { - // Call the correct simulate endpoint - const simulationPromise = this.maestroApiService.simulate(simulationData, simulationEndpoint, this._simulationSessionId); - simulationPromise.then(() => { - this.graph.closeSocket(); - let markedForDeletionExternalGraphs: DialogHandler[] = []; - this.externalGraphs.forEach((eg) => { - if (!eg.win.isDestroyed()) { - eg.win.webContents.send("close"); - } else { - // The window have been destroyed, remove it from external graphs - markedForDeletionExternalGraphs.push(eg); - } - }); - markedForDeletionExternalGraphs.forEach((eg) => { - this.externalGraphs.splice(this.externalGraphs.indexOf(eg, 0), 1); - }); - this.graph.setFinished(); - this.maestroApiService.getCoeProcess().simulationFinished(); - this.progress = 100; - this.simulationCompletedHandler(); - resolve(); - }) - .catch((err: Response) => { - this.errorHandler(err); - reject(err.statusText); - }); - }); - - this.graph.launchWebSocket(this.maestroApiService.getWebSocketSessionUrl(this._simulationSessionId)); - }); - }); - } - - private executePostProcessingScript(outputFile: string) { - - let script: string = this.config.postProcessingScript; - let self = this; - - //default will be '.' - if (script == null || script.length <= 1) - return; - - - let scriptNormalized = Path.normalize(Path.join(this.config.projectRoot, script)); - var scriptExists = false; - try { - fs.accessSync(scriptNormalized, fs.constants.R_OK); - scriptExists = true; - - } catch (e) { - - } - - if (scriptExists) { - script = scriptNormalized; - } - - var spawn = child_process.spawn; - - var child = spawn(script, ["\"" + outputFile + "\"", "" + this.config.endTime], { - detached: true, - shell: true, - cwd: Path.dirname(outputFile) - }); - child.unref(); - - child.stdout.on('data', function (data: any) { - self.postProcessingOutputReport(false, data + ""); - }); - - child.stderr.on('data', function (data: any) { - console.log('stderr: ' + data); - self.postProcessingOutputReport(true, data + ""); - }); - } -} diff --git a/src/angular2-app/coe/coe.module.ts b/src/angular2-app/coe/coe.module.ts deleted file mode 100644 index 0399a25..0000000 --- a/src/angular2-app/coe/coe.module.ts +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ -import { NgModule } from "@angular/core"; -import { BrowserModule } from '@angular/platform-browser' -import { FormsModule, ReactiveFormsModule } from "@angular/forms"; -import { CoePageComponent } from "./coe-page.component"; -import { SharedModule } from "../shared/shared.module"; -import { CoeConfigurationComponent } from "./coe-configuration.component"; -import { ZeroCrossingComponent } from "./inputs/zero-crossing.component"; -import { FmuMaxStepSizeComponent } from "./inputs/fmu-max-step-size.component"; -import { BoundedDifferenceComponent } from "./inputs/bounded-difference.component"; -import { SamplingRateComponent } from "./inputs/sampling-rate.component"; -import { LiveGraphComponent } from "./inputs/live-graph-component"; -import { CoeSimulationComponent } from "./coe-simulation.component"; -import { LineChartComponent } from "../shared/line-chart.component"; -@NgModule({ - imports: [BrowserModule, - FormsModule, - ReactiveFormsModule, - SharedModule], // Brings PanelComponent and FileBrowserComponent - declarations: [CoePageComponent, - CoeConfigurationComponent, - ZeroCrossingComponent, - FmuMaxStepSizeComponent, - BoundedDifferenceComponent, - SamplingRateComponent, - LiveGraphComponent, - CoeSimulationComponent, - LineChartComponent], - exports: [CoePageComponent, CoeSimulationComponent, CoeConfigurationComponent] -}) -export class COEModule { - - constructor() { - console.log("COE MODULE") - } -} \ No newline at end of file diff --git a/src/angular2-app/coe/graph-window/app.component.ts b/src/angular2-app/coe/graph-window/app.component.ts deleted file mode 100644 index 3869fb7..0000000 --- a/src/angular2-app/coe/graph-window/app.component.ts +++ /dev/null @@ -1,85 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import { Component, OnInit, NgZone } from '@angular/core'; -import { FileSystemService } from "../../shared/file-system.service"; -/* import { Http } from "@angular/http"; */ -import { HttpClient } from '@angular/common/http'; -import { LiveGraph } from "../../../intocps-configurations/CoSimulationConfig"; -import { Graph } from "../../shared/graph" -import { ipcRenderer } from "electron"; - -// Main application component. -// Handles routing between the pages that use Angular 2. - -@Component({ - selector: 'app', - templateUrl: "./graph.component.html" -}) -export class AppComponent implements OnInit { - graph: Graph = new Graph(); - - constructor(private http: HttpClient, - private fileSystem: FileSystemService, - private zone: NgZone) { - console.log("Graph Window App Component") - } - - initializeGraph() { - /* let dataObj = JSON.parse(data); */ - let dataObj = JSON.parse(this.getParameterByName("data")); - this.zone.run(() => { - this.graph.setGraphMaxDataPoints(dataObj.graphMaxDataPoints); - let lg: LiveGraph = new LiveGraph(); - lg.fromObject(dataObj.livestream,dataObj.title); - this.graph.initializeSingleDataset(lg); - this.graph.launchWebSocket(dataObj.webSocket) - }); - ipcRenderer.on('close', () => { this.graph.closeSocket(); this.graph.setFinished();}); - window.onbeforeunload = ((ev: any) => { - this.graph.closeSocket(); - }); - } -// Retrieves the query string value associated with name -private getParameterByName(name: string, url?: string) { - if (!url) url = window.location.href; - name = name.replace(/[\[\]]/g, "\\$&"); - var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"), - results = regex.exec(url); - if (!results) return null; - if (!results[2]) return ''; - return decodeURIComponent(results[2].replace(/\+/g, " ")); -} - ngOnInit() { - console.log("Graph Window App Component On Init"); - this.initializeGraph(); - } -} diff --git a/src/angular2-app/coe/graph-window/graph-window.html b/src/angular2-app/coe/graph-window/graph-window.html deleted file mode 100644 index 0dd819c..0000000 --- a/src/angular2-app/coe/graph-window/graph-window.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - Loading plot - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/angular2-app/coe/graph-window/graph-window.module.ts b/src/angular2-app/coe/graph-window/graph-window.module.ts deleted file mode 100644 index 5bc7885..0000000 --- a/src/angular2-app/coe/graph-window/graph-window.module.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { BrowserModule } from '@angular/platform-browser'; -import { NgModule } from '@angular/core'; - -import { AppComponent } from './app.component'; -/* import { HttpModule } from '@angular/http'; */ -import { HttpClientModule } from '@angular/common/http'; -import { LineChartComponent } from '../../shared/line-chart.component'; -import { FileSystemService } from '../../shared/file-system.service'; - -@NgModule({ - declarations: [ - AppComponent, - LineChartComponent - ], - imports: [ - BrowserModule, - /* HttpModule */ - HttpClientModule - ], - providers: [FileSystemService], - bootstrap: [AppComponent] -}) -export class GraphWindowModule { - - constructor() - {console.log("GraphWindowModule");} -} \ No newline at end of file diff --git a/src/angular2-app/coe/graph-window/graph-window.ts b/src/angular2-app/coe/graph-window/graph-window.ts deleted file mode 100644 index 6ee1bd1..0000000 --- a/src/angular2-app/coe/graph-window/graph-window.ts +++ /dev/null @@ -1,55 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import { GraphWindowModule } from "./graph-window.module" -import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; -import {enableProdMode} from "@angular/core" - -function getParameterByName(name:string, url?:string) { - if (!url) url = window.location.href; - name = name.replace(/[\[\]]/g, "\\$&"); - var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"), - results = regex.exec(url); - if (!results) return null; - if (!results[2]) return ''; - return decodeURIComponent(results[2].replace(/\+/g, " ")); -} -// Start Angular 2 application -/* let ref = bootstrap(AppComponent, []).then((ref) => { - let data = getParameterByName("data"); - let instance : AppComponent = ref.instance; - instance.initializeGraph(data); -}); */ -window.onload = function () { - console.log("onload"); - enableProdMode(); - platformBrowserDynamic().bootstrapModule(GraphWindowModule).catch(err => console.error(err)); -} diff --git a/src/angular2-app/coe/graph-window/graph.component.html b/src/angular2-app/coe/graph-window/graph.component.html deleted file mode 100644 index fd95589..0000000 --- a/src/angular2-app/coe/graph-window/graph.component.html +++ /dev/null @@ -1,8 +0,0 @@ -
-
-
-
Graph: {{g.title}}
- -
-
-
\ No newline at end of file diff --git a/src/angular2-app/coe/inputs/bounded-difference.component.html b/src/angular2-app/coe/inputs/bounded-difference.component.html deleted file mode 100644 index fd334c5..0000000 --- a/src/angular2-app/coe/inputs/bounded-difference.component.html +++ /dev/null @@ -1,71 +0,0 @@ -
-
- -
-

{{constraint.id}}

- -
This field is required.
-
ID is not unique.
-
-
- -
- -
-
-

{{port.instance.fmu.name}}.{{port.instance.name}}.{{port.scalarVariable.name}}

-
- - - - -
-
-
1 or more ports are required.
-
Ports are not unique.
-
-
- -
- -
-

{{constraint.abstol}}

- -
Only numbers are allowed.
-
-
- -
- -
-

{{constraint.reltol}}

- -
Only numbers are allowed.
-
-
- -
- -
-

{{constraint.safety}}

- -
Only numbers are allowed.
-
-
- -
- -
- -
-
-
\ No newline at end of file diff --git a/src/angular2-app/coe/inputs/bounded-difference.component.ts b/src/angular2-app/coe/inputs/bounded-difference.component.ts deleted file mode 100644 index ff429d3..0000000 --- a/src/angular2-app/coe/inputs/bounded-difference.component.ts +++ /dev/null @@ -1,77 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import {Component, Input} from "@angular/core"; -import {FormGroup, FormControl} from "@angular/forms"; -import {BoundedDifferenceConstraint} from "../../../intocps-configurations/CoSimulationConfig"; -import {InstanceScalarPair} from "../models/Fmu"; - -@Component({ - selector: 'bounded-difference', - templateUrl: "./angular2-app/coe/inputs/bounded-difference.component.html" -}) -export class BoundedDifferenceComponent { - @Input() - constraint:BoundedDifferenceConstraint; - - @Input() - ports:Array = []; - - @Input() - formGroup:FormGroup; - - @Input() - editing:boolean = false; - - customTrackBy(index:number, obj: any):any { - return index; - } - - addPort() { - this.constraint.ports.push(this.ports[0]); - this.updatePortValidation(); - } - - removePort(port:InstanceScalarPair) { - this.constraint.ports.splice(this.constraint.ports.indexOf(port), 1); - this.updatePortValidation(); - } - - onPortChange(output: InstanceScalarPair, index: number) { - this.constraint.ports[index] = output; - this.updatePortValidation(); - } - - updatePortValidation() { - let formControl = this.formGroup.get('ports'); - formControl.updateValueAndValidity(); - } -} diff --git a/src/angular2-app/coe/inputs/fmu-max-step-size.component.html b/src/angular2-app/coe/inputs/fmu-max-step-size.component.html deleted file mode 100644 index 6f7346a..0000000 --- a/src/angular2-app/coe/inputs/fmu-max-step-size.component.html +++ /dev/null @@ -1,10 +0,0 @@ -
-
-
-
-
-
-

Constraint enabled.

-
-
-
diff --git a/src/angular2-app/coe/inputs/fmu-max-step-size.component.ts b/src/angular2-app/coe/inputs/fmu-max-step-size.component.ts deleted file mode 100644 index b8f4671..0000000 --- a/src/angular2-app/coe/inputs/fmu-max-step-size.component.ts +++ /dev/null @@ -1,54 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import {Component, Input} from "@angular/core"; -import {FormArray, FormControl, FormGroup} from "@angular/forms"; -import {FmuMaxStepSizeConstraint} from "../../../intocps-configurations/CoSimulationConfig"; - - -@Component({ - selector: 'fmu-max-step-size', - templateUrl: "./angular2-app/coe/inputs/fmu-max-step-size.component.html" -}) -export class FmuMaxStepSizeComponent { - @Input() - constraint:FmuMaxStepSizeConstraint; - - @Input() - formGroup:FormGroup; - - @Input() - editing:boolean = false; - - customTrackBy(index:number, obj: any):any { - return index; - } -} diff --git a/src/angular2-app/coe/inputs/live-graph-component.html b/src/angular2-app/coe/inputs/live-graph-component.html deleted file mode 100644 index 6cfcc61..0000000 --- a/src/angular2-app/coe/inputs/live-graph-component.html +++ /dev/null @@ -1,53 +0,0 @@ -
-
-
-
- - -
-
-
- - -
-
-
- -

{{graph.title}}

- - - -
-
- -
- -
-
-
- -
-
- -
- -
-
-
-
-
-
-
\ No newline at end of file diff --git a/src/angular2-app/coe/inputs/live-graph-component.ts b/src/angular2-app/coe/inputs/live-graph-component.ts deleted file mode 100644 index 5692b0b..0000000 --- a/src/angular2-app/coe/inputs/live-graph-component.ts +++ /dev/null @@ -1,129 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import { Component, Input } from "@angular/core"; -import { FormArray, FormControl, FormGroup } from "@angular/forms"; -import { LiveGraph, CoSimulationConfig } from "../../../intocps-configurations/CoSimulationConfig"; -import { ScalarVariable, CausalityType, Instance, InstanceScalarPair, ScalarVariableType } from "../models/Fmu"; - -@Component({ - selector: 'live-graph', - templateUrl: "./angular2-app/coe/inputs/live-graph-component.html" -}) -export class LiveGraphComponent { - @Input() - graph: LiveGraph; - - @Input() - config: CoSimulationConfig; - /* set path(config: CoSimulationConfig) { - this.config = config; - - if (config) - this.parseconfig(); - } - get path(): CoSimulationConfig { - return this.config; - }*/ - - - @Input() - formGroup: FormGroup; - - - private _editing: boolean = false; - @Input() - editing: boolean = false; - - - outputPorts: Array = []; - - /* parseconfig() { - // Create an array of all output ports on all instances - this.outputPorts = this.config.multiModel.fmuInstances - .map(instance => instance.fmu.scalarVariables - .filter(sv => sv.type === ScalarVariableType.Real && (sv.causality === CausalityType.Output || sv.causality === CausalityType.Parameter)) - .map(sv => this.config.multiModel.getInstanceScalarPair(instance.fmu.name, instance.name, sv.name))) - .reduce((a, b) => a.concat(...b), []); - } -*/ - liveStreamSearchName: string = ''; - - customTrackBy(index: number, obj: any): any { - return index; - } - - getOutputs(scalarVariables: Array) { - return scalarVariables.filter(variable => (variable.causality === CausalityType.Output || variable.causality === CausalityType.Local)); - } - - isLocal(variable: ScalarVariable): boolean { - return variable.causality === CausalityType.Local - } - - getScalarVariableTypeName(type: ScalarVariableType) { - return ScalarVariableType[type]; - } - - restrictToCheckedLiveStream(instance: Instance, scalarVariables: Array) { - return scalarVariables.filter(variable => this.isLivestreamChecked(instance, variable)); - } - - isLivestreamChecked(instance: Instance, output: ScalarVariable) { - let variables = this.graph.getLivestream().get(instance); - - if (!variables) return false; - - return variables.indexOf(output) !== -1; - } - - onLivestreamChange(enabled: boolean, instance: Instance, output: ScalarVariable) { - let variables = this.graph.getLivestream().get(instance); - - if (!variables) { - variables = []; - this.graph.getLivestream().set(instance, variables); - } - - if (enabled) - variables.push(output); - else { - variables.splice(variables.indexOf(output), 1); - - if (variables.length == 0) - this.graph.getLivestream().delete(instance); - } - } - - onLiveStreamKey(event: any) { - this.liveStreamSearchName = event.target.value; - } -} diff --git a/src/angular2-app/coe/inputs/sampling-rate.component.html b/src/angular2-app/coe/inputs/sampling-rate.component.html deleted file mode 100644 index f798dc8..0000000 --- a/src/angular2-app/coe/inputs/sampling-rate.component.html +++ /dev/null @@ -1,41 +0,0 @@ -
-
- -
-

{{constraint.id}}

- -
This field is required.
-
ID is not unique.
-
-
- -
- -
-

{{constraint.base}}

- -
This field is required.
-
Only integers are allowed.
-
-
- -
- -
-

{{constraint.rate}}

- -
This field is required.
-
Only integers are allowed.
-
-
- -
- -
-

{{constraint.startTime}}

- -
This field is required.
-
Only integers are allowed.
-
-
-
\ No newline at end of file diff --git a/src/angular2-app/coe/inputs/sampling-rate.component.ts b/src/angular2-app/coe/inputs/sampling-rate.component.ts deleted file mode 100644 index 434b8b6..0000000 --- a/src/angular2-app/coe/inputs/sampling-rate.component.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import {Component, Input} from "@angular/core"; -import {FormGroup} from "@angular/forms"; -import {SamplingRateConstraint} from "../../../intocps-configurations/CoSimulationConfig"; - -@Component({ - selector: 'sampling-rate', - templateUrl: "./angular2-app/coe/inputs/sampling-rate.component.html" -}) -export class SamplingRateComponent { - @Input() - constraint:SamplingRateConstraint; - - @Input() - editing:boolean = false; - - @Input() - formGroup:FormGroup; -} diff --git a/src/angular2-app/coe/inputs/zero-crossing.component.html b/src/angular2-app/coe/inputs/zero-crossing.component.html deleted file mode 100644 index 6cb2792..0000000 --- a/src/angular2-app/coe/inputs/zero-crossing.component.html +++ /dev/null @@ -1,70 +0,0 @@ -
-
- -
-

{{constraint.id}}

- -
This field is required.
-
ID is not unique.
-
-
- -
- -
-
-

{{port.instance.fmu.name}}.{{port.instance.name}}.{{port.scalarVariable.name}}

-
- - - - -
-
-
1 or 2 ports are required.
-
Ports are not unique.
-
-
- -
- -
-

{{constraint.order}}

-
- - -
-
-
- -
- -
-

{{constraint.abstol}}

- -
Only numbers are allowed.
-
-
- -
- -
-

{{constraint.safety}}

- -
Only numbers are allowed.
-
-
-
diff --git a/src/angular2-app/coe/inputs/zero-crossing.component.ts b/src/angular2-app/coe/inputs/zero-crossing.component.ts deleted file mode 100644 index 3713738..0000000 --- a/src/angular2-app/coe/inputs/zero-crossing.component.ts +++ /dev/null @@ -1,78 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import {Component, Input} from "@angular/core"; -import {FormArray, FormControl, FormGroup} from "@angular/forms"; -import {ZeroCrossingConstraint} from "../../../intocps-configurations/CoSimulationConfig"; -import {InstanceScalarPair} from "../models/Fmu"; - -@Component({ - selector: 'zero-crossing', - templateUrl: "./angular2-app/coe/inputs/zero-crossing.component.html" -}) -export class ZeroCrossingComponent { - @Input() - constraint:ZeroCrossingConstraint; - - @Input() - ports:Array = []; - - _formGroup: FormGroup - @Input() - formGroup:FormGroup; - - @Input() - editing:boolean = false; - - customTrackBy(index:number, obj: any):any { - return index; - } - - addPort() { - this.constraint.ports.push(this.ports[0]); - this.updatePortValidation(); - } - - removePort(port:InstanceScalarPair) { - this.constraint.ports.splice(this.constraint.ports.indexOf(port), 1); - this.updatePortValidation(); - } - - onPortChange(output: InstanceScalarPair, index: number) { - this.constraint.ports[index] = output; - this.updatePortValidation(); - } - - updatePortValidation() { - let formControl = this.formGroup.get('ports'); - formControl.updateValueAndValidity(); - } -} diff --git a/src/angular2-app/coe/models/CoeConfig.ts b/src/angular2-app/coe/models/CoeConfig.ts deleted file mode 100644 index 78d7673..0000000 --- a/src/angular2-app/coe/models/CoeConfig.ts +++ /dev/null @@ -1,142 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import * as Path from 'path'; -import { CoSimulationConfig } from "../../../intocps-configurations/CoSimulationConfig"; -import { Instance, ScalarVariable } from "../models/Fmu" -import { Serializer } from "../../../intocps-configurations/Parser" - -export class CoeConfig { - constructor(private coSimConfig: CoSimulationConfig, private remoteCoe: boolean = false) { - - } - - toJSON(implodeMM?: any): string { - let fmus: any = {}; - this.coSimConfig.multiModel.fmus.forEach(fmu => { - let fmuPath; - if(this.remoteCoe) fmuPath = Path.join("session:", Path.basename(fmu.path)); - else if (fmu.isNested()) - { - fmuPath = "coe:/" + fmu.path; - } - else - { - fmuPath = "file:///" + fmu.path - } - fmus[fmu.name] = fmuPath.replace(/\\/g, "/").replace(/ /g, "%20"); - }); - // Add the implode fmu - if (implodeMM) { - for (let key in implodeMM.fmus) { - fmus[key] = implodeMM.fmus[key]; - } - } - - let data: any = {}; - - let livestream: Map = new Map(); - - if (this.coSimConfig.liveGraphs) { - this.coSimConfig.liveGraphs.forEach(g => { - - if (g.getLivestream()) { - g.getLivestream().forEach((svs, ins: Instance) => { - - let iname = Serializer.getId(ins); - if (livestream.has(iname)) { - let list: any = livestream.get(iname); - g.getLivestream().get(ins).forEach(sv => { - if (list.indexOf(sv) < 0) { - list.push(sv); - } - }); - - livestream.set(iname, list); - } - else { - livestream.set(iname, g.getLivestream().get(ins).map(x => x)); - } - }); - } - - }); - } - - //FMUS - Object.assign(data, this.coSimConfig.multiModel.toObject(), this.coSimConfig.toObject()); - - if (implodeMM) { - for (let key in implodeMM.connections) { - data.connections[key] = implodeMM.connections[key]; - } - if(implodeMM.logVariables) - data["logVariables"] = implodeMM.logVariables; - - data["hasExternalSignals"] = true; - } - - delete data["endTime"]; - delete data["startTime"]; - delete data["multimodel_path"]; - delete data["multimodel_crc"]; - delete data["enableAllLogCategoriesPerInstance"]; - delete data["postProcessingScript"]; - - let livestreamData: any = {}; - livestream.forEach((svs, iname) => livestreamData[iname] = svs.map(sv => sv.name)); - data["livestream"] = livestreamData; - - if (data["graphs"]) - delete data["graphs"]; - - - - if (!data["livestreamInterval"]) - delete data["livestreamInterval"]; - if (!data["visible"]) - delete data["visible"]; - if (!data["loggingOn"]) - delete data["loggingOn"]; - - if (data["overrideLogLevel"] === null || data["overrideLogLevel"] === "Not set") - delete data["overrideLogLevel"]; - - data["fmus"] = fmus; - - return JSON.stringify(data); - } -} - - - - - diff --git a/src/angular2-app/coe/models/Fmu.ts b/src/angular2-app/coe/models/Fmu.ts deleted file mode 100644 index 73cc6e4..0000000 --- a/src/angular2-app/coe/models/Fmu.ts +++ /dev/null @@ -1,509 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import * as fs from 'fs'; -import Path = require("path"); -let JSZip = require("jszip"); -import { Utilities } from "../../../utilities" -import { NgZone } from '@angular/core'; -import { reject } from 'bluebird'; - -// Holds information about a .fmu container -export class Fmu { - platforms: string[] = []; - scalarVariables: ScalarVariable[] = []; - pathNotFound = true; - logCategories: string[] = []; - system_platform: string = Utilities.getSystemPlatform() + Utilities.getSystemArchitecture(); - nested = false; - - - constructor(public name: string = "{FMU}", public path: string = "") { - - } - - public isNested() {return this.nested;} - - isSupported() { - return !!this.platforms.find(x => x === this.system_platform); - } - - public updatePath(path: string): Promise { - this.path = path; - this.scalarVariables.forEach(sv => sv.isConfirmed = false); - this.platforms = []; - try { - return this.populate(); - } catch(err){ - console.log("Error in updating path: " + err); - this.pathNotFound = true; - return Promise.reject(err);} - /* return this.populate().catch(() => this.pathNotFound = true); */ - } - - public populate(): Promise { - if (fs.lstatSync(this.path).isDirectory()) { - return this.populateFromDir(); - } else { - return this.populateFromZip(); - } - } - - public populateFromDir(): Promise { - let self = this; - - // Get supported platforms - fs.readdir(Path.join(self.path, "binaries"), function (err, items) { - //See https://typescript.codeplex.com/workitem/2242 for reason of any usage. - if( items != undefined) - { - self.platforms = items.map(x => self.convertToPlatform(x)); - }else - { - self.platforms = ["N/A"]; - } - }); - - let mdPath = Path.join(self.path, "modelDescription.xml") - let checkFileExists = new Promise(function (resolve, reject) { - try { - if (fs.accessSync(mdPath, fs.constants.R_OK) === null) { - reject(); - } - self.pathNotFound = false; - resolve(); - } catch (e) { - reject(e); - } - }); - - //wrap readFile in a promise - let fileReadPromise = new Promise(function (resolve, reject) { - fs.readFile(mdPath, function (err, data) { - if (err !== null) { - return reject(err); - } - resolve(data); - }); - }); - - return checkFileExists.then(() => { - return fileReadPromise.then(data => { - self.populateFromModelDescription(data.toString('UTF-8', 0, data.length)); - }); - }).catch(error => console.error("Error when popilating from model description: " + error)); - } - private convertToPlatform(platform: string): string { - let pl = platform.toLowerCase(); - switch (pl) { - case "win32": return "windows32"; - case "win64": return "windows64"; - default: return pl; - } - } - - public populateFromZip(): Promise { - return new Promise((resolve, reject) => { - try { - if (fs.accessSync(this.path, fs.constants.R_OK) === null) - return reject(); - - fs.readFile(this.path, (err, data) => { - if (err) - return reject(err); - - var zip = new JSZip(); - - zip - .loadAsync(data) - .then(() => { - this.pathNotFound = false; - - // Get platform names - this.platforms = zip - .file(/^binaries\/[a-zA-Z0-9]+\/.+/) - .map((folder: any) => this.convertToPlatform(folder.name.split('/')[1])); - - zip.file("modelDescription.xml").async("string") - .then((content: string) => { - this.populateFromModelDescription(content); - resolve(); - }); - }); - }); - } catch (e) { - reject(e); - } - }); - } - - private populateFromModelDescription(content: string) { - var oParser = new DOMParser(); - var oDOM = oParser.parseFromString(content, "text/xml"); - - // Check for nested coe - let test = document.evaluate('//Nested', oDOM, null, XPathResult.BOOLEAN_TYPE, null); - if(test.booleanValue === true) - this.nested = true; - - //output - var iterator = document.evaluate('//ScalarVariable', oDOM, null, XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null); - - var thisNode: Element = iterator.iterateNext() as Element; - - while (thisNode) { - - let causalityNode = thisNode.attributes.getNamedItem("causality"); - let variabilityNode = thisNode.attributes.getNamedItem("variability"); - let nameNode = thisNode.attributes.getNamedItem("name"); - let initialNode = thisNode.attributes.getNamedItem("initial"); - var type: ScalarVariableType; - - var tNode: Element = document.evaluate('Real', thisNode, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue as Element; - - if (tNode != null) { - type = ScalarVariableType.Real; - } else { - tNode = document.evaluate('Boolean', thisNode, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue as Element; - if (tNode != null) { - type = ScalarVariableType.Bool; - } else { - tNode = document.evaluate('Integer', thisNode, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue as Element; - if (tNode != null) { - type = ScalarVariableType.Int; - } else { - tNode = document.evaluate('String', thisNode, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue as Element; - if (tNode != null) { - type = ScalarVariableType.String; - } else { - tNode = document.evaluate('Enumeration', thisNode, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue as Element; - if(tNode != null) { - type = ScalarVariableType.Enumeration; - } - } - } - } - } - let start: string; - if(tNode.hasAttributes()) - { - let startAttribute = tNode.attributes.getNamedItem("start"); - if(startAttribute) - start = startAttribute.textContent; - } - - let causality: CausalityType; - - if (causalityNode != undefined) { - let causalityText = causalityNode.textContent; - - if ("output" == causalityText) { - causality = CausalityType.Output; - } - else if ("input" == causalityText) { - causality = CausalityType.Input; - } - else if ("parameter" == causalityText) { - causality = CausalityType.Parameter; - } - else if ("calculatedParameter" == causalityText) { - causality = CausalityType.CalculatedParameter; - } - else if ("local" == causalityText) { - causality = CausalityType.Local; - } - else if ("independent" == causalityText) { - causality = CausalityType.Independent; - } - } - - let variability: VariabilityType; - if (variabilityNode != undefined) { - let variabilityText = variabilityNode.textContent; - if ("constant" == variabilityText) { - variability = VariabilityType.Constant; - } else if ("continuous" == variabilityText) { - variability = VariabilityType.Continuous - } else if ("discrete" == variabilityText) { - variability = VariabilityType.Discrete - } else if ("fixed" == variabilityText) { - variability = VariabilityType.Fixed - } else if ("tunable" == variabilityText) - { - variability = VariabilityType.Tunable; - } - } - - let initial: InitialType; - if(initialNode != undefined) - { - let initialText = initialNode.textContent; - if("exact" == initialText) - { - initial = InitialType.Exact; - } else if ("approx" == initialText) - { - initial = InitialType.Approx - } else if ("calculated" == initialText) - { - initial = InitialType.Calculated - } - } - - let sv = this.getScalarVariable(nameNode.textContent); - sv.type = type; - sv.causality = causality; - sv.isConfirmed = true; - sv.variability = variability; - sv.start = start; - sv.initial = initial; - - thisNode = iterator.iterateNext() as Element; - } - - this.scalarVariables.sort((a, b) => a.name.localeCompare(b.name)); - - - iterator = document.evaluate('fmiModelDescription/LogCategories/*[@name]/@name', oDOM, null, XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null); - - thisNode = iterator.iterateNext() as Element; - - while (thisNode) { - this.logCategories.push(thisNode.nodeValue); - thisNode = iterator.iterateNext() as Element; - } - - this.logCategories.sort((a, b) => a.localeCompare(b)); - } - - public getScalarVariable(name: string): ScalarVariable { - let scalar = this.scalarVariables.find(s => s.name == name); - - if (!scalar) { - scalar = new ScalarVariable(name); - this.scalarVariables.push(scalar); - } - - return scalar; - } -} - -// Represents a FMI ScalarVariable -export class ScalarVariable { - constructor( - public name: string = "", - public type: ScalarVariableType = ScalarVariableType.Unknown, - public causality: CausalityType = CausalityType.Unknown, - public variability: VariabilityType = VariabilityType.Unknown, - public initial: InitialType = InitialType.Unknown, - public start: string = undefined, - public isConfirmed: boolean = false // none FMI specific - ) { - - } -} - -export enum ScalarVariableType { Real, Bool, Int, String, Enumeration, Unknown } -export function typeToString(type: ScalarVariableType) { - switch (type) { - case ScalarVariableType.Real: - return "Real"; - case ScalarVariableType.Bool: - return "Boolean"; - case ScalarVariableType.Int: - return "Integer"; - case ScalarVariableType.String: - return "String"; - case ScalarVariableType.Enumeration: - return "Enumeration"; - case ScalarVariableType.Unknown: - return "unknown"; - } -} - -export enum CausalityType { Output, Input, Parameter, CalculatedParameter, Local, Independent, Unknown } - -export function causalityToString(causality: CausalityType) { - switch (causality) { - case CausalityType.Output: - return "output"; - case CausalityType.Input: - return "input"; - case CausalityType.Parameter: - return "parameter"; - case CausalityType.CalculatedParameter: - return "calculatedParameter"; - case CausalityType.Local: - return "local"; - case CausalityType.Independent: - return "independent"; - case CausalityType.Unknown: - return "unknown"; - } -} - -export enum InitialType {Exact, Approx, Calculated, Unknown} -export function initialToString(initial: InitialType) { - switch(initial){ - case InitialType.Exact: return "exact"; - case InitialType.Approx: return "approx"; - case InitialType.Calculated: return "calculated"; - case InitialType.Unknown: return "unknown"; - } - -} - -export enum VariabilityType { Constant, Fixed, Tunable, Continuous, Discrete, Unknown } -export function variabilityToString(variability: VariabilityType) { - switch (variability) { - case VariabilityType.Constant: return "constant"; - case VariabilityType.Fixed: return "fixed"; - case VariabilityType.Tunable: return "tunable"; - case VariabilityType.Continuous: return "continuous"; - case VariabilityType.Discrete: return "discrete"; - case VariabilityType.Unknown: return "unknown"; - } -} - -export function isTypeCompatiple(t1: ScalarVariableType, t2: ScalarVariableType): boolean { - if (t1 == ScalarVariableType.Unknown || t2 == ScalarVariableType.Unknown) { - return true; - } else if (t1 == ScalarVariableType.Bool && (t2 == ScalarVariableType.Int || t2 == ScalarVariableType.Real)) { - // bool -> number - return true; - } else if (t2 == ScalarVariableType.Bool && (t1 == ScalarVariableType.Int || t1 == ScalarVariableType.Real)) { - //number -> bool - return true; - } else { - return t1 == t2; - } -} - -export function isCausalityCompatible(t1: CausalityType, t2: CausalityType): boolean { - if (t1 == CausalityType.Unknown || t2 == CausalityType.Unknown) { - return true; - } - else { - return t1 == t2; - } -} - -export function isInteger(x: any) { return !isNaN(x) && isFinite(x) && Math.floor(x) === x; } -export function isFloat(x: any) { return !!(x % 1); } -export function isString(value: any) { return typeof value === 'string'; } - - -export function convertToType(type: ScalarVariableType, value: any): any { - if (type == ScalarVariableType.Bool) { - return Boolean(value); - } - else if (type == ScalarVariableType.Int) { - let mValue = Number(value); - if (isInteger(mValue)) { - return mValue; - } - } - else if (type == ScalarVariableType.Real) { - let mValue = Number(value); - if (isFloat(mValue) || isInteger(mValue)) { - return mValue; - } - } - else if (type == ScalarVariableType.String) { - let mValue = value.toString(); - if (isString(mValue)) { - return mValue; - } - } - - return null; -} - -export function isTypeCompatipleWithValue(t1: ScalarVariableType, value: any): boolean { - switch (t1) { - case ScalarVariableType.Unknown: - return true; - case ScalarVariableType.Real: - return isFloat(value) || isInteger(value); - case ScalarVariableType.Bool: - return typeof (value) === "boolean" || isInteger(value); - case ScalarVariableType.Int: - return isInteger(value); - case ScalarVariableType.String: - return isString(value); - } - return false; -} - -// Repersents an instance of an FMU, including initial parameters and a mapping from outputs to InstanceScalarPair -export class Instance { - //mapping from output to FmuConnection where connection holds an instane and input scalarVariable - outputsTo: Map = new Map(); - - // initial parameter values - initialValues: Map = new Map(); - - constructor(public fmu: Fmu, public name: string) { - - } - - public addOutputToInputLink(source: ScalarVariable, target: InstanceScalarPair) { - if (this.outputsTo.has(source)) { - let list = this.outputsTo.get(source); - let match = list.find(pair => pair.instance == target.instance && pair.scalarVariable == target.scalarVariable); - - if (!match) list.push(target); - } else { - this.outputsTo.set(source, [target]); - } - } -} - -// Represents a link pair (FmuInstances, scalarVariable) -export class InstanceScalarPair { - constructor(public instance: Instance, public scalarVariable: ScalarVariable) { - - } -} - -// Represents a parameter-value pair (ScalarVariable, any) -export class ScalarValuePair { - constructor(public scalarVariable: ScalarVariable, public value: any) { - - } -} - -// Represents an output-connections pair (ScalarVariable, any) -export class OutputConnectionsPair { - constructor(public name: string, public connections: InstanceScalarPair[]) { - - } -} diff --git a/src/angular2-app/dependencies/Dependencychecker.ts b/src/angular2-app/dependencies/Dependencychecker.ts deleted file mode 100644 index 665283a..0000000 --- a/src/angular2-app/dependencies/Dependencychecker.ts +++ /dev/null @@ -1,132 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ -import * as child_process from "child_process"; -import { shell } from 'electron'; -// dialog from main thread -const { dialog } = require('electron'); - - // check if java is running and which version no working - export function dependencyCheckJava() { - var spawn = child_process.spawn("java", ["-version"],{shell : true}); - spawn.on("error", err => { - console.error(err); - return false; - }); - spawn.on("close", (code, signal) => { - if (code != 0) { - dialog.showMessageBox( - {title: "error", buttons: ["OK"], message: "Java wasn´t detected on your system \n" + - "JRE is needed to run the COE"} - ); - } - console.log("the java dependency check subprocess has been closed"); - }); - } -/* } - */ - -// check if python is running and which version no working - -export function dependencyCheckPythonVersion() { - var spawn = child_process.spawn("python", ["--version"]); - spawn.on("error", err => { - console.error(err); - return false; - }); - spawn.stderr.on("data", function(data) { - data = data.toString("utf8").split("\n")[0]; - // the pythonVersion is false if the output from the spawn do not follow the stardard of: "Python *.*.*" - var pythonVersion = data.split(" ")[1] ? data.split(" ")[1] : false; - if (pythonVersion != false) { - // this converts a string of "*.*.*"" into a number *.* - var pythonversion = parseFloat(pythonVersion); - - } else if (pythonVersion === false) { - console.log(data); - // should find a better way than this to display dialogs - dialog.showMessageBox( - { - type: "error", - buttons: ["OK"], - message: - "INTO-CPS found Python on your system. \n" + - "But was unable to assess your version of Python. \n" + - "Your python version needs to be 2.7 or newer." - } - ); - - } - - }); - spawn.stdout.on('data', function(data) { - data = data.toString("utf8").split("\n")[0]; - var pythonVersion = data.split(" ")[1] ? data.split(" ")[1] : false; - var pythonversion = parseFloat(pythonVersion); - if (pythonversion < 2.6 /* || pythonversion >= 3.0 */) { - - console.log(pythonversion); - dialog.showMessageBox( - { - type: "error", - buttons: ["OK"], - message: - "INTO-CPS has assest your python version to be older than 2.7. \n" + - "Your python version needs to be 2.7 or newer" - } - ); - } else if (pythonversion > 3.0) { - console.log(pythonversion); - dialog.showMessageBox( - { - type: "error", - buttons: ["OK"], - message: - "INTO-CPS has assest your python version to be newer than 2.9. \n" + - "Your python version needs to be 2.7 or newer, but can´t be 3.0 or newer" - } - ); - } - }) - spawn.on("close", (code, signal) => { - // the shell returns != 0 if it fails to run python. - if (code != 0) { - dialog.showMessageBox( - { - type: "error", - buttons: ["OK"], - message: "Python wasn't found on your system" - } - ); - } - - console.log("the python dependency check subprocess has been closed"); - }); -} diff --git a/src/angular2-app/dse/DseViewController.ts b/src/angular2-app/dse/DseViewController.ts deleted file mode 100644 index a653988..0000000 --- a/src/angular2-app/dse/DseViewController.ts +++ /dev/null @@ -1,62 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import {ViewController} from "../../iViewController"; -import IntoCpsApp from "../../IntoCpsApp"; -import {AppComponent} from "../app.component"; -import * as Path from 'path'; - -interface MyWindow extends Window { - ng2app: AppComponent; -} - -declare var window: MyWindow; - -export class DseViewController extends ViewController { - constructor(private view: HTMLDivElement, private path:string) { - super(view); - } - - initialize() { - $(this.view).css('height',0); - IntoCpsApp.setTopName(Path.basename(Path.join(this.path,"../"))); - window.ng2app.openDSE(this.path); - } - - deInitialize() { - if (window.ng2app.navigationService.canNavigate()) { - window.ng2app.closeAll(); - $(this.view).css('height',"calc(100% - 80px)"); - return true; - } - return false; - } -} diff --git a/src/angular2-app/dse/dse-coe-launch.component.html b/src/angular2-app/dse/dse-coe-launch.component.html deleted file mode 100644 index 3871193..0000000 --- a/src/angular2-app/dse/dse-coe-launch.component.html +++ /dev/null @@ -1,50 +0,0 @@ -

DSE Co-simulation

- -
-
- -

Error: Could not run config.

-

Message: {{parseError}}

-

Path: {{path}}

-
-
- - - -
-
-
- - -

{{threadCount}}

-
-
- -
- -
- -
- -
-
- -
-
- -
- - Simulation successful - Simulation failed -
- -
- -
- diff --git a/src/angular2-app/dse/dse-coe-launch.component.ts b/src/angular2-app/dse/dse-coe-launch.component.ts deleted file mode 100644 index a29fb30..0000000 --- a/src/angular2-app/dse/dse-coe-launch.component.ts +++ /dev/null @@ -1,252 +0,0 @@ -import { Component, ViewEncapsulation, ViewChild, ElementRef, PipeTransform, Pipe, OnInit, OnDestroy, Input, NgZone } from '@angular/core'; -import { CoeSimulationService } from '../coe/coe-simulation.service'; -import { SettingsService, SettingKeys } from '../shared/settings.service'; -import IntoCpsApp from "../../IntoCpsApp"; -import { HttpClient } from '@angular/common/http'; -import { timeout, map } from 'rxjs/operators'; -import {Project} from "../../proj/Project"; -import * as fs from 'fs'; -import * as Path from 'path'; - -import {DomSanitizer} from '@angular/platform-browser'; -import { dependencyCheckPythonVersion } from "../dependencies/Dependencychecker"; -import { MaestroApiService } from '../shared/maestro-api.service'; -import { Subscription } from 'rxjs'; -// https://www.electronjs.org/docs/api/dialog dialog from main thread. If you want to use the dialog object from a renderer process, remember to access it using the remote: -const { dialog } = require('electron').remote; - -@Pipe({ name: 'safe' }) -export class SafePipe implements PipeTransform { - constructor(private sanitizer: DomSanitizer) { } - transform(url: string) { - return this.sanitizer.bypassSecurityTrustResourceUrl(url); - } -} - -@Component({ - selector: "dse-coe-launch", - templateUrl: "./angular2-app/dse/dse-coe-launch.component.html" -}) -export class DseCoeLaunchComponent implements OnInit, OnDestroy { - private _path:string; - private resultdir: string; - private _coeIsOnlineSub: Subscription; - @Input() - set path(path:string) { - this._path = path; - - if (path){ - let app: IntoCpsApp = IntoCpsApp.getInstance(); - let p: string = app.getActiveProject().getRootFilePath(); - this.cosimConfig = this.loadCosimConfigs(Path.join(p, Project.PATH_MULTI_MODELS)); - } - } - get path():string { - return this._path; - } - - generateHTMLOutput: boolean = true; - generateCSVOutput: boolean = true; - threadCount : number = 1; - - editing: boolean = false; - editingMM: boolean = false; - simsuccess: boolean = false; - simfailed: boolean = false; - parseError: string = null; - simulation: boolean = false;/* - resultshtml: any = null; */ - resultpath: any = null; - - mmSelected:boolean = true; - mmPath:string = ''; - - cosimConfig:string[] = []; - mmOutputs:string[] = []; - objNames:string[] = []; - - @Input() - coeconfig:string = ''; - - online:boolean = false; - - constructor(private maestroApiService: MaestroApiService, private zone:NgZone) { - this._coeIsOnlineSub = this.maestroApiService.startMonitoringOnlineStatus(isOnline => this.online = isOnline); - } - - ngOnInit() { - console.log(this.path); - } - - ngOnDestroy() { - this.maestroApiService.stopMonitoringOnlineStatus(this._coeIsOnlineSub); - } - - getFiles(path: string): string [] { - var fileList: string[] = []; - var files = fs.readdirSync(path); - for(var i in files){ - var name = Path.join(path, files[i]); - if (fs.statSync(name).isDirectory()){ - fileList = fileList.concat(this.getFiles(name)); - } else { - fileList.push(name); - } - } - - return fileList; - } - - resetParseError() { - this.zone.run(() => { - this.parseError = null; - }); - } - - - loadCosimConfigs(path: string): string[] { - var files: string[] = this.getFiles(path); - return files.filter(f => f.endsWith("coe.json")); - } - /* - * Method to check if can run a DSE. Will check if the COE is online, if there are any warnings - * and also some DSE-specific elements - */ - canRun() { - return this.online - && this.coeconfig != "" - && !this.simulation - /* && this.dseWarnings.length === 0 - && this.coeWarnings.length === 0 */ - //&& this.config.dseSearchParameters.length > 1 - /* && this.config - && this.config.extScrObjectives - && (this.config.extScrObjectives.length + this.config.intFunctObjectives.length) >= 2; */ - } - - /* - * Method to run a DSE with the current DSE configuration. Assumes that the DSE can be run. - * The method does not need to send the DSEConfiguration object, simply the correct paths. It relies upon the - * config being saved to json format correctly. - */ - runDse() { - var dir = Path.dirname(this._path); - fs.watch(dir, (eventType, filename) => { - if (filename) { - if(eventType == 'rename') { - this.resultdir = Path.join(dir,filename); - } - } else { - console.log('filename not provided'); - } - }); - this.simulation = true; - this.simfailed = false; - this.simsuccess = false; - var stdoutChunks: any[] = []; - var stderrChunks: any[] = []; - var spawn = require('child_process').spawn; - let installDir = IntoCpsApp.getInstance().getSettings().getValue(SettingKeys.INSTALL_DIR); - - let absoluteProjectPath = IntoCpsApp.getInstance().getActiveProject().getRootFilePath(); - let experimentConfigName = this._path.slice(absoluteProjectPath.length + 1, this._path.length); - let multiModelConfigName = this.coeconfig.slice(absoluteProjectPath.length + 1, this.coeconfig.length); - - - //Using algorithm selector script allows any algortithm to be used in a DSE config. - let scriptFile = Path.join(installDir, "dse", "Algorithm_selector.py"); - var dseScriptOptions = [scriptFile, absoluteProjectPath, experimentConfigName, multiModelConfigName, `-t ${this.threadCount}`]; - - if(!this.generateHTMLOutput) - dseScriptOptions.push("-noHTML"); - if(!this.generateCSVOutput) - dseScriptOptions.push("-noCSV"); - - var child = spawn("python", dseScriptOptions, { - /* detached: true, */ - shell: false, - // cwd: childCwd - }); - child.unref(); - - child.on('error', (err: any) => { - // When the python was not found in your system - console.error('Failed to start subprocess.'+ err.message); - dialog.showMessageBox( - { - type: "error", - buttons: ["OK"], - message: - "Python spawn failed \n" + - "Check if Python is install and available in the path \n" + - err.message - } - ); - this.simfailed = true; - this.simulation = false; - }); - - child.on('close', (code: any) => { - console.log(`child process close all stdio with code ${code}`); - }); - - child.on('end', (code: any) => { - console.log(`child process exited with code ${code}`); - }); - - child.stdout.on('data', function (data: any) { - stdoutChunks = stdoutChunks.concat(data); - }); - child.stdout.on('end', () => { - var stdoutContent = Buffer.concat(stdoutChunks).toString(); - console.log('stdout chars:', stdoutContent.length); - // see the output uncomment this line - // console.log(stdoutContent); - }); - child.stderr.on('data', function (data: any) { - stderrChunks = stderrChunks.concat(data); - }); - child.stderr.on('end', () => { - var stderrContent = Buffer.concat(stderrChunks).toString(); - console.log('stderr chars:', stderrContent.length); - - console.log(stderrContent); - if(stderrContent.length > 0) { - this.parseError = stderrContent; - console.warn(this.parseError); - this.simfailed = true; - this.simulation = false; - dialog.showMessageBox( - { - type: "error", - buttons: ["OK"], - message: - "Running DSE failed. \n" + - this.parseError.toString().substr(0,25) + - "See full error description in devtools. \n" - } - ); - } else { - this.simsuccess = true; - this.simulation = false; - console.log("end DSE sim"); - this.resultpath = Path.normalize(`${this.resultdir}/results.html`); - } - }); - } - - updateThreadCount(value: number) { - if(value <= 0) - throw new Error(`Thread count should be greater than or equal to 1 given: ${value}`); - - this.threadCount = value; - } - - setGenerateHTMLOutput() { - this.generateHTMLOutput = !this.generateHTMLOutput; - } - - setGenerateCSVOutput() { - this.generateCSVOutput = !this.generateCSVOutput; - } -} diff --git a/src/angular2-app/dse/dse-configuration.component.html b/src/angular2-app/dse/dse-configuration.component.html deleted file mode 100644 index a3ee0d9..0000000 --- a/src/angular2-app/dse/dse-configuration.component.html +++ /dev/null @@ -1,381 +0,0 @@ -
-
-

Error: Could not parse config.

-

Message: {{parseError}}

-

Path: {{path}}

-
-
- - - -
- - - -

Experiment Multi-model

-
- -
-

{{getMultiModelName()}}

- - - - - -
-
- - - -

DSE Configuration Setup

-

DSE Search Algorithms

-
- -
-

{{config.searchAlgorithm.getName()}}

- -
-
- -
-
-
- -
-

{{config.searchAlgorithm.initialPopulation}}

- -
-
- -
- -
-

{{config.searchAlgorithm.initialPopulationDistribution}}

- -
-
- -
- -
-

{{config.searchAlgorithm.mutationProbability}}

- -
-
- -
- -
-

{{config.searchAlgorithm.parentSelectionStrategy}}

- -
-
- -
- -
-

{{config.searchAlgorithm.maxGenerationsWithoutImprovement}}

- -
-
-
-
- -
- - -

Experiment parameters

-
- -
-
-
-
-
-
-
- - - - -
-
-
- -
-
-
-

- {{getScalarTypeName(initialValue.scalarVariable.type)}} {{initialValue.scalarVariable.name}} - -

-
-
- - -
-

{{getDseParamValue(selectedParameterInstance, initialValue.scalarVariable.name)}}

-
- - - - -
-
-
-

{{initialValue.value}}

-
- -
-
-
-
-
-
-
- - -
- - -

Parameter Constraints

-
-
-

{{getParameterConstraint(p)}}

- -
-
- -
-
- - -
- - -

External Script Objectives

-
-
-
-
-
- -
-
-

{{getExternalScriptName(e)}}

- - -
-
-

{{getExternalScriptFilename(e)}}

- -
-
-
-
-

{{p.id}}

- -
-
-

{{p.type}}

- -
-
-

{{p.value}}

-
- -
-
- -
-
- -
- -
-
-
- -
- -
-
- -
- -

Internal Function Objectives

-
-
-
-
-
- -
-
-

{{getExternalScriptName(i)}}

- - -
-
-

{{getInternalFunctionColumnName(i)}}

- -
-
-

{{getInternalFunctionObjectiveType(i)}}

- -
-
- - -
- -

Objective Constraints

-
-
-

{{getObjectiveConstraint(o)}}

- -
-
- -
-
- - -
- - -

Ranking

-
-
-
-
- -
-
- {{getRankingMethod()}} - -
-
-
-
-
-

{{getDimensionName(d)}}

- -
-
-

{{getDimensionDirection(d)}}

- - -
-
-
-
-
- -
- -

Scenario

-
-
-

{{getScenario(s)}}

- - -
-
- -
- - - - - - - - - - -
- diff --git a/src/angular2-app/dse/dse-configuration.component.ts b/src/angular2-app/dse/dse-configuration.component.ts deleted file mode 100644 index eb7ea4b..0000000 --- a/src/angular2-app/dse/dse-configuration.component.ts +++ /dev/null @@ -1,846 +0,0 @@ - - -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ -import { Component, Input, NgZone, Output, EventEmitter, OnDestroy } from "@angular/core"; -import {Serializer} from "../../intocps-configurations/Parser"; -import { - Instance, ScalarVariable, CausalityType, InstanceScalarPair, isCausalityCompatible, isTypeCompatiple, - Fmu, ScalarValuePair, ScalarVariableType -} from "../coe/models/Fmu"; -import {CoeSimulationService} from "../coe/coe-simulation.service"; -import IntoCpsApp from "../../IntoCpsApp"; -/* import {Http} from "@angular/http"; */ -import { HttpClient } from '@angular/common/http'; -import {SettingsService, SettingKeys} from "../shared/settings.service"; -import {ParetoDimension, InternalFunction, DseConfiguration, ParetoRanking, ExternalScript, DseParameter, DseScenario, DseParameterConstraint, DseObjectiveConstraint,IDseAlgorithm, GeneticSearch, ExhaustiveSearch} from "../../intocps-configurations/dse-configuration"; -import { WarningMessage } from "../../intocps-configurations/Messages"; -import { NavigationService } from "../shared/navigation.service"; -import { FormGroup, FormArray, FormControl } from "@angular/forms"; -import {Project} from "../../proj/Project"; -import * as Path from 'path'; -import * as fs from 'fs'; -import { MaestroApiService } from "../shared/maestro-api.service"; -import { Subscription } from "rxjs"; - - - -@Component({ - selector: "dse-configuration", - templateUrl: "./angular2-app/dse/dse-configuration.component.html" -}) -export class DseConfigurationComponent implements OnDestroy { - private _path:string; - private _coeIsOnlineSub: Subscription; - @Input() - set path(path:string) { - this._path = path; - - if (path){ - let app: IntoCpsApp = IntoCpsApp.getInstance(); - let p: string = app.getActiveProject().getRootFilePath(); - this.cosimConfig = this.loadCosimConfigs(Path.join(p, Project.PATH_MULTI_MODELS)); - - } - } - get path():string { - return this._path; - } - - @Output() - change = new EventEmitter(); - - @Output() - coechange = new EventEmitter(); - - form: FormGroup; - algorithms: IDseAlgorithm[] = []; - algorithmFormGroups = new Map(); - editing: boolean = false; - editingMM: boolean = false; - isInValidDSEConfig: boolean = false; - warnings: WarningMessage[] = []; - parseError: string = null; - - mmSelected:boolean = true; - mmPath:string = ''; - - config = new DseConfiguration(); - cosimConfig:string[] = []; - mmOutputs:string[] = []; - objNames:string[] = []; - coeconfig:string = ''; - - online:boolean = false; - dseWarnings:WarningMessage[] = []; - coeWarnings:WarningMessage[] = []; - - private onlineInterval:number; - - private selectedParameterInstance: Instance; - - private newParameter: ScalarVariable; - - private algorithmConstructors = [ - ExhaustiveSearch, - GeneticSearch - ]; - - //Collection of arrays to use for drop-boxes. Some may be expanded as the backend is developed - private geneticPopulationDistribution = ["random"];//To add in when backend works["random", "uniform"]; - private geneticParentSelectionStrategy = ["random"];//["random", "algorithmObjectiveSpace","algorithmDesignSpace"]; - private internalFunctionTypes = ["max", "min","mean"]; - private externalScriptParamTp = ["model output", "constant", "simulation value"]; - private simulationValue = ["step-size", "time"]; - private paretoDirections = ["-", "+"]; - - - constructor(private maestroApiService: MaestroApiService, private zone:NgZone, private navigationService: NavigationService) { - this.navigationService.registerComponent(this); - this._coeIsOnlineSub = this.maestroApiService.startMonitoringOnlineStatus(isOnline => this.online = isOnline); - } - - ngOnDestroy() { - clearInterval(this.onlineInterval); - this.maestroApiService.stopMonitoringOnlineStatus(this._coeIsOnlineSub); - } - - parseConfig(mmPath : string) { - let project = IntoCpsApp.getInstance().getActiveProject(); - DseConfiguration - .parse(this.path, project.getRootFilePath(), project.getFmusPath(), mmPath) - .then(config => { - this.zone.run(() => { - this.config = config; - //retrieve information to use for validation purposes - this.objNames = this.getObjectiveNames(); - this.mmOutputs = this.loadMMOutputs(); - - // Create an array of the algorithm from the coe config and a new instance of all other algorithms - this.algorithms = this.algorithmConstructors - .map(constructor => - config.searchAlgorithm instanceof constructor - ? config.searchAlgorithm - : new constructor() - ); - // Create an array of formGroups for the algorithms - this.algorithms.forEach(algorithm => { - this.algorithmFormGroups.set(algorithm, algorithm.toFormGroup()); - }); - - // Create a form group for validation - this.form = new FormGroup({ - searchAlgorithm : this.algorithmFormGroups.get(this.config.searchAlgorithm), - paramConstraints : new FormArray(this.config.paramConst.map(c => new FormControl(c))), - - objConstraints : new FormArray(this.config.objConst.map(c => new FormControl(c))), - extscr : new FormArray(this.config.extScrObjectives.map(s => new FormControl(s))), - scenarios : new FormArray(this.config.scenarios.map(s => new FormControl(s))) - }); - }); - }, error => this.zone.run(() => {this.parseError = error})).catch(error => console.error(`Error during parsing of config: ${error}`)); - - } - - onNavigate(): boolean { - if (!this.editing) - return true; - - if (this.form.valid) { - if (confirm("Save your work before leaving?")) - this.onSubmit(); - - return true; - } else { - return confirm("The changes to the configuration are invalid and can not be saved. Continue anyway?"); - } - } - - onSubmit() { - if (!this.editing) return; - - this.warnings = this.config.validate(); - - let override = false; - - if (this.warnings.length > 0) { - - const electron = require("electron"); - let dialog = electron.dialog; - /* let res = dialog.showMessageBox({ title: 'Validation failed', message: 'Do you want to save anyway?', buttons: ["No", "Yes"] }); - - if (res == 0) { - return; - } else { - override = true; - this.warnings = []; - } */ - // for electron v10 - let res = dialog.showMessageBox({ title: 'Validation failed', message: 'Do you want to save anyway?', buttons: ["No", "Yes"] }); - res.catch(() => { - return - }); - res.then(function(res) { - if (res.response == 0) { - return; - } else { - override = true; - this.warnings = []; - } - }) - } - - this.config.save() - .then(() => this.change.emit(this.path)) - .then(() => this.coechange.emit(this.coeconfig)) - .catch(error => console.error("error when saving dse config: " + error)); - - this.editing = false; - - } - - /* - * Method to state that the multi-model has been chosen for the DSE config - */ - /* onMMSubmit() { - if (!this.editingMM) return; - this.editingMM = false; - if (this.mmPath !='') - { - this.mmSelected = true; - } - } */ - - - - getFiles(path: string): string [] { - var fileList: string[] = []; - var files = fs.readdirSync(path); - for(var i in files){ - var name = Path.join(path, files[i]); - if (fs.statSync(name).isDirectory()){ - fileList = fileList.concat(this.getFiles(name)); - } else { - fileList.push(name); - } - } - - return fileList; - } - - loadCosimConfigs(path: string): string[] { - var files: string[] = this.getFiles(path); - return files.filter(f => f.endsWith("coe.json")); - } - - experimentName(path: string): string { - let elems = path.split(Path.sep); - let mm: string = elems[elems.length-2]; - let ex: string = elems[elems.length-3]; - return mm + " | " + ex; - } - - getMultiModelName():string{ - return this.experimentName(this.mmPath); - } - - onConfigChange(config:string) { - this.parseError = null; - this.coeconfig = config; - let mmPath = Path.join(this.coeconfig, "..", "..", "mm.json"); - /* let coePath = Path.join(this.coeconfig, "..", "..", "coe.json"); */ - try { - if(Path.isAbsolute(mmPath)) { - // console.warn("Could not find mm at: " + mmPath + " initiating search or possible alternatives...") - //no we have the old style - fs.readdirSync(Path.join(this.coeconfig, "..", "..")).forEach(file => { - if (file.endsWith("mm.json")) { - mmPath = Path.join(this.coeconfig, "..", "..", file); - console.log("Found mm at: " + mmPath); - // console.debug("Found old style mm at: " + mmPath); - return; - } - }); - } - this.mmPath=mmPath; - this.parseConfig(mmPath); - } catch (error) { - console.error("Path was not a correct path.. " + mmPath + " error: " + error); - } - - - } - - /* - * Method for updating the DSE algorithm - */ - onAlgorithmChange(algorithm: IDseAlgorithm) { - this.parseError = null; - this.config.searchAlgorithm = algorithm; - - this.form.removeControl('algorithm'); - this.form.addControl('algorithm', this.algorithmFormGroups.get(algorithm)); - } - - getSearchAlgorithm(){ - return this.config.searchAlgorithm.getName() - } - - setGeneticpopDist(dist: string) { - //assume is a genetic search - (this.config.searchAlgorithm).initialPopulationDistribution = dist; - } - - setParentSelectionStrategy(strat: string) { - //assume is a genetic search - (this.config.searchAlgorithm).parentSelectionStrategy = strat; - } - - /* REUSED FROM MM-CONFIG */ - selectParameterInstance(instance: Instance) { - this.selectedParameterInstance = instance; - this.newParameter = this.getParameters()[0]; - } - - /* - * Get the parameters for a selected FMU instance (selected instance set as a state variable) - */ - getParameters() { - if (!this.selectedParameterInstance) - return [null]; - - return this.selectedParameterInstance.fmu.scalarVariables - .filter(variable => isCausalityCompatible(variable.causality, CausalityType.Parameter) && !this.selectedParameterInstance.initialValues.has(variable)); - } - - /* - * Get the initial values for a selected FMU instance (selected instance set as a state variable) - */ - getInitialValues(): Array { - let initialValues: Array = []; - - this.selectedParameterInstance.initialValues.forEach((value, variable) => { - initialValues.push(new ScalarValuePair(variable, value)); - }); - - return initialValues; - } - - getScalarTypeName(type: number) { - return ['Real', 'Bool', 'Int', 'String', 'Unknown'][type]; - } - - /* - * Add a new DSE parameter - */ - addParameter() { - if (!this.newParameter) return; - - this.selectedParameterInstance.initialValues.set(this.newParameter, []); - this.newParameter = this.getParameters()[0]; - } - - /* - * Remove the given DSE search parameter - */ - removeParameter(instance: Instance, parameter: ScalarVariable) { - instance.initialValues.delete(parameter); - this.newParameter = this.getParameters()[0]; - } - - setParameterName(p: DseParameter, name: string) { - p.param = `${name}`; - } - - getParameterName(p:DseParameter){ - return p.param; - } - - /* - * Set the initial values for a DSE parameter. Will check types of values and also ensure - * parameter of choice is recorded in the DSE config. - */ - setDSEParameter(instance: Instance, variableName:string, newValue: any) { - - // this will not work with the python scripts as it will try to run on an array, this will be commented out for now and removed in an up-coming commit - /* if (!newValue.includes(",")){ - if (instance.fmu.getScalarVariable(variableName).type === ScalarVariableType.Real) - newValue = parseFloat(newValue); - else if (instance.fmu.getScalarVariable(variableName).type === ScalarVariableType.Int) - newValue = parseInt(newValue); - else if (instance.fmu.getScalarVariable(variableName).type === ScalarVariableType.Bool) - newValue = !!newValue; - } - else{ - newValue = this.parseArray(instance.fmu.getScalarVariable(variableName).type, newValue); - } */ - - newValue = this.parseArray(instance.fmu.getScalarVariable(variableName).type, newValue); - - let varExistsInDSE = false - let instanceExistsInDSE = false - - //Need to determine if the DSE configuration knows firstly about the FMU instance, and then - //if it does AND has existing values for the given parameter, add the new value to the initial values. - for (let dseParam of this.config.dseSearchParameters) { - if (dseParam.name === instance.name) { - instanceExistsInDSE = true - dseParam.initialValues.forEach((value, variable) => { - if (variable.name === variableName){ - dseParam.initialValues.set(variable, newValue) - varExistsInDSE = true - } - }) - } - } - //If the config does not know about this instance, it is added with the given initial values - if(!instanceExistsInDSE){ - let newInstance = this.addDSEParameter(instance); - newInstance.initialValues.set(instance.fmu.getScalarVariable(variableName), newValue); - } - //If the config knows about the instance but NOT the parameter values, they are added to the - //instance in the DSE config. - if(!varExistsInDSE){ - for (let dseParam of this.config.dseSearchParameters) { - if (dseParam.name === instance.name) { - dseParam.initialValues.set(instance.fmu.getScalarVariable(variableName), newValue); - } - } - } - } - - /* - * Record a new instance in the list of DSE parameters - */ - addDSEParameter(instance: Instance):Instance{ - let newInstance = instance - this.config.dseSearchParameters.push(newInstance); - return newInstance; - } - - removeDSEParameter(instance: Instance, variableName:string) { - for (let dseParam of this.config.dseSearchParameters) { - if (dseParam.name === instance.name) { - dseParam.initialValues.delete(instance.fmu.getScalarVariable(variableName)); - } - } - } - - parseArray(tp : ScalarVariableType, value: any):any []{ - let newArray = value.split(",") - for(let v of newArray){ - if (tp === ScalarVariableType.Real) - newArray.splice(newArray.indexOf(v),1, parseFloat(v)); - else if (tp === ScalarVariableType.Int) - newArray.splice(newArray.indexOf(v),1, parseInt(v)); - else if (tp === ScalarVariableType.Bool) - newArray.splice(newArray.indexOf(v),1, !!v); - } - return newArray - } - - //Utility method to obtain an instance from the multimodel by its string id encoding - private getParameter(dse: DseConfiguration, id: string): Instance { - let ids = this.parseId(id); - - let fmuName = ids[0]; - let instanceName = ids[1]; - let scalarVariableName = ids[2]; - return dse.getInstanceOrCreate(fmuName, instanceName); - } - - /* - * Parse an FMU id - */ - parseId(id: string): string[] { - //is must have the form: '{' + fmuName '}' + '.' instance-name + '.' + scalar-variable - // restriction is that instance-name cannot have '.' - - let indexEndCurlyBracket = id.indexOf('}'); - if (indexEndCurlyBracket <= 0) { - throw "Invalid id"; - } - - let fmuName = id.substring(0, indexEndCurlyBracket + 1); - var rest = id.substring(indexEndCurlyBracket + 1); - var dotIndex = rest.indexOf('.'); - if (dotIndex < 0) { - throw "Missing dot after fmu name"; - } - rest = rest.substring(dotIndex + 1); - //this is instance-name start index 0 - - dotIndex = rest.indexOf('.'); - if (dotIndex < 0) { - throw "Missing dot after instance name"; - } - let instanceName = rest.substring(0, dotIndex); - let scalarVariableName = rest.substring(dotIndex + 1); - - return [fmuName, instanceName, scalarVariableName]; - } - - /* - * Method to produce an array of outputs in the chosen multi-model - */ - loadMMOutputs():string[]{ - let outputs :string []= []; - - this.config.multiModel.fmuInstances.forEach(instance => { - instance.outputsTo.forEach((connections, scalarVariable) => { - outputs.push(Serializer.getIdSv(instance, scalarVariable)); - }); - }); - - return outputs; - } - - customTrackBy(index: number, obj: any): any { - return index; - } - - dseParamExists(instance: Instance, variableName:string) :boolean{ - let paramFound = false; - - for (let dseParam of this.config.dseSearchParameters) { - if (dseParam.name === instance.name) { - dseParam.initialValues.forEach((value, variable) => { - if (variable.name === variableName){ - paramFound = true; - } - }) - } - } - return paramFound; - } - - - getDseParamValue(instance: Instance, variableName:string) :any{ - let result = "ERROR"; - for (let dseParam of this.config.dseSearchParameters) { - if (dseParam.name === instance.name) { - dseParam.initialValues.forEach((value, variable) => { - if (variable.name === variableName){ - result = value; - } - }) - } - } - return result; - } - - - addParameterInitialValue(p: DseParameter, value: any) { - p.addInitialValue(value); - } - - getParameterIntialValues(p:DseParameter){ - return p.initialValues; - } - - setParameterIntialValues(p:DseParameter, oldVal: any, newVal:any){ - return p.setInitialValue(oldVal, newVal); - } - - removeParameterInitialValue(p: DseParameter, value: string) { - p.removeInitialValue(value); - } - - - - addParameterConstraint(){ - let pc = this.config.addParameterConstraint(); - let pcArray = this.form.get('paramConstraints'); - - pcArray.push(new FormControl(this.getParameterConstraint(pc))); - } - - setParameterConstraint(pc: DseParameterConstraint, name: string) { - pc.constraint = `${name}`; - } - - getParameterConstraint(pc:DseParameterConstraint){ - return pc.constraint; - } - - removeParameterConstraint(pc:DseParameterConstraint){ - this.config.removeParameterConstraint(pc); - let pcArray = this.form.get('paramConstraints'); - let index = this.config.paramConst.indexOf(pc); - - pcArray.removeAt(index); - } - - - - addExternalScript(){ - let es = this.config.addExternalScript(); - this.objNames = this.getObjectiveNames(); - } - - getExternalScriptName(e: ExternalScript){ - return e.name; - } - - setExternalScriptName(p: ExternalScript, name: string) { - p.name = `${name}`; - this.objNames = this.getObjectiveNames(); - } - - getExternalScriptFilename(e: ExternalScript){ - return e.fileName; - } - - setExternalScriptFileName(p: ExternalScript, name: string) { - p.fileName = `${name}`; - } - - getExternalScriptParameters(e: ExternalScript){ - return e.parameterList; - } - - addExternalScriptParameter(e: ExternalScript, value: any, tp: string) { - e.addParameter(value, tp); - } - - setExternalScriptParameterId(e:ExternalScript, param: any, newId:any){ - return e.setParameterId(param, newId); - } - - setExternalScriptParameterValue(e:ExternalScript, param: any, newVal:any){ - return e.setParameterValue(param, newVal); - } - - setExternalScriptParameterType(e:ExternalScript, param: any, newTp:string){ - return e.setParameterType(param, newTp); - } - - removeExternalScriptParameter(e: ExternalScript, value: string) { - e.removeParameter(value); - } - - removeExternalScript(e:ExternalScript){ - this.config.removeExternalScript(e); - this.objNames = this.getObjectiveNames(); - } - - - - addInternalFunction(){ - let intf = this.config.addInternalFunction(); - this.objNames = this.getObjectiveNames(); - } - - removeInternalFunction(i:InternalFunction){ - this.config.removeInternalFunction(i); - this.objNames = this.getObjectiveNames(); - } - - getInternalFunctionName(i: InternalFunction){ - return i.name; - } - - setInternalFunctionName(i: InternalFunction, name: string) { - i.name = `${name}`; - this.objNames = this.getObjectiveNames(); - } - - getInternalFunctionColumnName(i: InternalFunction){ - return i.columnId; - } - - setInternalFunctionColumnName(i: InternalFunction, name: string) { - i.columnId = `${name}`; - } - - getInternalFunctionObjectiveType(i: InternalFunction){ - return i.funcType; - } - - setInternalFunctionObjectiveType(i: InternalFunction, name: string) { - i.funcType = `${name}`; - } - - - - addObjectiveConstraint(){ - let oc = this.config.addObjectiveConstraint(); - let ocArray = this.form.get('objConstraints'); - - ocArray.push(new FormControl(this.getObjectiveConstraint(oc))); - } - - setObjectiveConstraint(oc: DseObjectiveConstraint, name: string) { - oc.constraint = `${name}`; - } - - getObjectiveConstraint(oc:DseObjectiveConstraint){ - return oc.constraint; - } - - removeObjectiveConstraint(oc:DseObjectiveConstraint){ - this.config.removeObjectiveConstraint(oc); - let ocArray = this.form.get('objConstraints'); - let index = this.config.objConst.indexOf(oc); - - ocArray.removeAt(index); - } - - - - getRankingMethod(){ - return this.config.ranking.getType(); - } - - /* - * Method to provide an array of all objective names - */ - getObjectiveNames():string []{ - let objNames = [""]; - this.config.extScrObjectives.forEach((o:ExternalScript) =>{ - objNames.push(o.name) - }); - this.config.intFunctObjectives.forEach((o:InternalFunction) =>{ - objNames.push(o.name) - }); - - return objNames; - } - - getRankingDimensions(){ - return ( this.config.ranking).getDimensions(); - } - - getDimensionName(d:ParetoDimension){ - return d.getObjectiveName() - } - - setDimensionName(d:ParetoDimension, name: string){ - d.objectiveName = name; - } - - onDimensionChange(pd: ParetoDimension, d:string){ - pd.objectiveName = d; - } - - getDimensionDirection(d:ParetoDimension){ - return d.getDirection() - } - - setDimensionDirection(d :ParetoDimension, direct :string){ - d.direction = direct; - } - - removeParetoDimension(d:ParetoDimension){ - ( this.config.ranking).removeDimension(d); - } - - addParetoDimension(objective:string, direction:string){ - if (this.config.ranking instanceof ParetoRanking){ - ( this.config.ranking).addDimension(objective, direction); - } - } - - - addScenario(){ - let s = this.config.addScenario(); - let sArray = this.form.get('scenarios'); - - sArray.push(new FormControl(this.getScenario(s))); - } - - setScenario(s: DseScenario, name: string) { - s.name = `${name}`; - } - - getScenario(s:DseScenario){ - return s.name; - } - - removeScenario(s:DseScenario){ - this.config.removeScenario(s); - let sArray = this.form.get('scenarios'); - let index = this.config.scenarios.indexOf(s); - - sArray.removeAt(index); - } - - - /* - * Method to check if can run a DSE. Will check if the COE is online, if there are any warnings - * and also some DSE-specific elements - */ - canRun() { - return this.online - && this.coeconfig != "" - && this.dseWarnings.length === 0 - && this.coeWarnings.length === 0 - //&& this.config.dseSearchParameters.length > 1 - && this.config - && this.config.extScrObjectives - && (this.config.extScrObjectives.length + this.config.intFunctObjectives.length) >= 2; - //&& ( this.config.ranking).dimensions.length == 2; - } - - /* - * Method to run a DSE with the current DSE configuration. Assumes that the DSE can be run. - * The method does not need to send the DSEConfiguration object, simply the correct paths. It relies upon the - * config being saved to json format correctly. - */ - runDse() { - console.log('running from config'); - var spawn = require('child_process').spawn; - let installDir = IntoCpsApp.getInstance().getSettings().getValue(SettingKeys.INSTALL_DIR); - - let absoluteProjectPath = IntoCpsApp.getInstance().getActiveProject().getRootFilePath(); - let experimentConfigName = this._path.slice(absoluteProjectPath.length + 1, this._path.length); - let multiModelConfigName = this.coeconfig.slice(absoluteProjectPath.length + 1, this.coeconfig.length); - // check if python is installed. - /* dependencyCheckPythonVersion(); */ - - - //Using algorithm selector script allows any algortithm to be used in a DSE config. - let scriptFile = Path.join(installDir, "dse", "Algorithm_selector.py"); - var child = spawn("python", [scriptFile, absoluteProjectPath, experimentConfigName, multiModelConfigName], { - detached: true, - shell: false, - // cwd: childCwd - }); - child.unref(); - - child.stdout.on('data', function (data: any) { - console.log('dse/stdout: ' + data); - }); - child.stderr.on('data', function (data: any) { - console.log('dse/stderr: ' + data); - }); - } -} diff --git a/src/angular2-app/dse/dse-page.component.html b/src/angular2-app/dse/dse-page.component.html deleted file mode 100644 index 40a29bd..0000000 --- a/src/angular2-app/dse/dse-page.component.html +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/angular2-app/dse/dse-page.component.ts b/src/angular2-app/dse/dse-page.component.ts deleted file mode 100644 index 9ad69b1..0000000 --- a/src/angular2-app/dse/dse-page.component.ts +++ /dev/null @@ -1,55 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import {Component, Input} from "@angular/core"; -import { CoeSimulationService } from "../coe/coe-simulation.service"; - - -@Component({ - selector: "dse-page", - providers: [ - CoeSimulationService - ], - templateUrl: "./angular2-app/dse/dse-page.component.html" -}) -export class DsePageComponent { - @Input() - path:string; - coeconfig:string = ''; - - constructor() { - console.log("DSEPAGECOMPONENT"); - } - - coeChangeEvent(config: string) { - this.coeconfig = config; - } -} diff --git a/src/angular2-app/mm/MmViewController.ts b/src/angular2-app/mm/MmViewController.ts deleted file mode 100644 index e2895d7..0000000 --- a/src/angular2-app/mm/MmViewController.ts +++ /dev/null @@ -1,62 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import {ViewController} from "../../iViewController"; -import IntoCpsApp from "../../IntoCpsApp"; -import {AppComponent} from "../app.component"; -import * as Path from 'path'; - -interface MyWindow extends Window { - ng2app: AppComponent; -} - -declare var window: MyWindow; - -export class MmViewController extends ViewController { - constructor(private view: HTMLDivElement, private path:string) { - super(view); - } - - initialize() { - $(this.view).css('height',0); - IntoCpsApp.setTopName(Path.basename(Path.join(this.path,"../"))); - window.ng2app.openMultiModel(this.path); - } - - deInitialize() { - if (window.ng2app.navigationService.canNavigate()) { - window.ng2app.closeAll(); - $(this.view).css('height',"calc(100% - 80px)"); - return true; - } - return false; - } -} diff --git a/src/angular2-app/mm/inputs/file-browser.component.html b/src/angular2-app/mm/inputs/file-browser.component.html deleted file mode 100644 index 414cf04..0000000 --- a/src/angular2-app/mm/inputs/file-browser.component.html +++ /dev/null @@ -1,20 +0,0 @@ -
- - - - - - - - - - -
\ No newline at end of file diff --git a/src/angular2-app/mm/inputs/file-browser.component.ts b/src/angular2-app/mm/inputs/file-browser.component.ts deleted file mode 100644 index d5dbc76..0000000 --- a/src/angular2-app/mm/inputs/file-browser.component.ts +++ /dev/null @@ -1,94 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import {Component, Input, Output, EventEmitter, OnInit} from "@angular/core"; -// ES6 -/* import {remote} from "electron"; */ -// CommonJS -const remote = require("electron").remote; -import * as Path from "path"; -import * as fs from "fs"; - -@Component({ - selector: "file-browser", - templateUrl: "./angular2-app/mm/inputs/file-browser.component.html" -}) -export class FileBrowserComponent implements OnInit { - @Input() - basePath = ""; - - @Input() - set path(path:string) { - this._path = path.replace(Path.normalize(`${this.basePath}/`), ""); - } - get path():string { - return this._path; - } - - @Output() - pathChange = new EventEmitter(); - - private _path:string = ""; - private dialog:Electron.Dialog; - private platform:string; - - ngOnInit():any { - this.dialog = remote.dialog; - this.platform = remote.getGlobal("intoCpsApp").platform; - } - - browseFile() { - this.browse(["openFile"]); - } - - browseDirectory() { - this.browse(["openDirectory"]); - } - - browse(properties: ('openFile' | 'openDirectory' | 'multiSelections' | 'createDirectory')[] = ["openFile", "openDirectory"]) { - - this.dialog.showOpenDialog({defaultPath: this.basePath, properties: properties }).then((res) => { - if(res) this.onChange(res.filePaths[0]); - }).catch((error: Error) => { - console.error(error); - return; - }); - - } - - onChange(path:string) { - this.path = path; - - fs.access(Path.normalize(`${this.basePath}/${this.path}`), fs.constants.R_OK, error => { - this.pathChange.emit(Path.normalize(error ? this.path : `${this.basePath}/${this.path}`)); - }); - } -} diff --git a/src/angular2-app/mm/mm-configuration.component.html b/src/angular2-app/mm/mm-configuration.component.html deleted file mode 100644 index 97d6b8f..0000000 --- a/src/angular2-app/mm/mm-configuration.component.html +++ /dev/null @@ -1,235 +0,0 @@ -
-
-

Error: Could not parse config.

-

Message: {{parseError}}

-

Path: {{path}}

-
-
- -
- - - - -

FMUs - -

- -
-
- -
-
- -
-
- -
-
-

{{getFmuName(fmu)}}

- -
This field is required.
-
{{'{' }} and {{'}' }} are not allowed.
-
Key is not unique.
-
-
-

{{createDisplayFmuPath(config.fmusRootPath,fmu.path)}}

- -
Path not found.
- Not supported - Supported -
-
- -
-
- -
- -

FMU instances

- -
-
- - - -
-
- - -
-
-

{{instance.name}}

-
- - - - -
-
This field is required.
-
"." is not allowed.
-
Key is not unique.
-
-
-
-
- -
- -

Connections

- -
-
-
- -
- - -
- -
-
- -
- - -
- -
-
- -
- - -
- -
-
- -
- -
    - -
-
-
- -
- -

Initial values of parameters

- -
-
-
- -
- - -
-
-
-
-
- -
-
-
-
- - - - -
-
-
- -
-
-
-

- {{getScalarTypeName(initialValue.scalarVariable.type)}} {{initialValue.scalarVariable.name}} - -

-
-
-

{{initialValue.value}}

-
- - - - - - - - -
-
-
-
-
-
- -
- -
- Please fix the following issues before saving: -
-
{{error.message}}
-
-
-
{{warning.message}}
-
-
-
- - - -
diff --git a/src/angular2-app/mm/mm-configuration.component.ts b/src/angular2-app/mm/mm-configuration.component.ts deleted file mode 100644 index 2f2033e..0000000 --- a/src/angular2-app/mm/mm-configuration.component.ts +++ /dev/null @@ -1,360 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import { Component, Input, NgZone, Output, EventEmitter } from "@angular/core"; -import { MultiModelConfig } from "../../intocps-configurations/MultiModelConfig"; -import IntoCpsApp from "../../IntoCpsApp"; -import { - Instance, - ScalarVariable, - CausalityType, InstanceScalarPair, isCausalityCompatible, isTypeCompatiple, - Fmu, ScalarValuePair, ScalarVariableType -} from "../coe/models/Fmu"; -import { IProject } from "../../proj/IProject"; -import { FormGroup, FormArray, FormControl, Validators} from "@angular/forms"; -import { uniqueControlValidator } from "../shared/validators"; -import { NavigationService } from "../shared/navigation.service"; -import { WarningMessage, ErrorMessage } from "../../intocps-configurations/Messages"; - -import * as Path from 'path'; - -@Component({ - selector: "mm-configuration", - templateUrl: "./angular2-app/mm/mm-configuration.component.html" -}) -export class MmConfigurationComponent { - private _path: string; - - @Input() - set path(path: string) { - this._path = path; - - if (path) - this.parseConfig(); - } - get path(): string { - return this._path; - } - - @Output() - change = new EventEmitter(); - - form: FormGroup; - editing: boolean = false; - parseError: string = null; - warnings: WarningMessage[] = []; - - private config: MultiModelConfig; - - private selectedParameterInstance: Instance; - private selectedOutputInstance: Instance; - private selectedOutput: ScalarVariable; - private selectedInputInstance: Instance; - private selectedInstanceFmu: Fmu; - - private newParameter: ScalarVariable; - - constructor(private zone: NgZone, private navigationService: NavigationService) { - this.navigationService.registerComponent(this); - } - - parseConfig() { - let project: IProject = IntoCpsApp.getInstance().getActiveProject(); - - MultiModelConfig - .parse(this.path, project.getFmusPath()) - .then(config => { - /* this.zone.run(() => { */ - this.parseError = null; - - this.config = config; - - // Create a form group for validation - this.form = new FormGroup({ - fmus: new FormArray(this.config.fmus.map(fmu => - new FormControl(this.getFmuName(fmu), - [Validators.required, Validators.pattern("[^{^}]*")])), - uniqueControlValidator), - instances: new FormArray(this.config.fmus.map(fmu => - new FormArray(this.getInstances(fmu).map(instance => - new FormControl(instance.name, [Validators.required, - Validators.pattern("[^\.]*")])), uniqueControlValidator))) - }); - this.warnings = this.config.validate(); - /* }); */ - - }, error => this.parseError = error).catch(err => console.log(err)); /* this.zone.run(() => */ - } - - onNavigate(): boolean { - if (!this.editing) - return true; - - if (this.form.valid) { - if (confirm("Save your work before leaving?")) - this.onSubmit(); - - return true; - } else { - return confirm("The changes to the configuration are invalid and can not be saved. Continue anyway?"); - } - } - - onSubmit() { - if (!this.editing) return; - - this.warnings = this.config.validate(); - - if (this.warnings.length > 0) return; - this.config.save() - .then(() => { - this.selectOutputInstance(null); - this.selectParameterInstance(null); - this.change.emit(this.path); - }).catch(error => console.error("Error when submitting changes to mm: " + error)); - - this.editing = false; - } - - addFmu() { - let fmu = this.config.addFmu(); - - let formArray = this.form.get('fmus'); - let fmuArray = this.form.get('instances'); - - fmuArray.push(new FormArray([], uniqueControlValidator)); - formArray.push(new FormControl(this.getFmuName(fmu), [Validators.required, Validators.pattern("[^{^}]*")])); - } - - removeFmu(fmu: Fmu) { - let fmuArray = this.form.get('fmus'); - let index = this.config.fmus.indexOf(fmu); - - if (this.selectedInstanceFmu === fmu) - this.selectInstanceFmu(null); - - this.config.fmuInstances - .filter(instance => instance.fmu === fmu) - .forEach(instance => this.removeInstanceFromForm(instance)); - - fmuArray.removeAt(index); - this.config.removeFmu(fmu); - } - - getScalarTypeName(type: number) { - return ['Real', 'Bool', 'Int', 'String', 'Unknown'][type]; - } - - getFmuName(fmu: Fmu): string { - return fmu.name.substring(1, fmu.name.length - 1); - } - - setFmuName(fmu: Fmu, name: string) { - fmu.name = `{${name}}`; - } - - setFmuPath(fmu: Fmu, path: string) { - fmu - .updatePath(path) - .then(() => this.zone.run(() => { })).catch(error => console.error("Error in setting FMUpath: " + error)); - - this.selectOutputInstance(null); - } - - addInstance(fmu: Fmu) { - let instance = this.config.addInstance(fmu); - - let fmuIndex = this.config.fmus.indexOf(fmu); - let fmuArray = this.form.get('instances'); - let instanceArray = fmuArray.controls[fmuIndex]; - - instanceArray.push(new FormControl(instance.name, [Validators.required, Validators.pattern("[^\.]*")])); - } - - removeInstance(instance: Instance) { - this.removeInstanceFromForm(instance); - this.config.removeInstance(instance); - } - - removeInstanceFromForm(instance: Instance) { - let fmuIndex = this.config.fmus.indexOf(instance.fmu); - let fmuArray = this.form.get('instances'); - let instanceArray = fmuArray.controls[fmuIndex]; - let index = this.getInstances(instance.fmu).indexOf(instance); - - if (this.selectedInputInstance === instance) - this.selectInputInstance(null); - - if (this.selectedOutputInstance === instance) - this.selectOutputInstance(null); - - if (this.selectedParameterInstance === instance) - this.selectParameterInstance(null); - - instanceArray.removeAt(index); - } - - getInstances(fmu: Fmu) { - return this.config.fmuInstances.filter(instance => instance.fmu === fmu); - } - - getInstanceFormControl(fmu: Fmu, index: number): FormControl { - let fmuIndex = this.config.fmus.indexOf(fmu); - let fmuArray = this.form.get('instances'); - let instanceArray = fmuArray.controls[fmuIndex]; - - return instanceArray.controls[index]; - } - - selectInstanceFmu(fmu: Fmu) { - this.selectedInstanceFmu = fmu; - } - - selectParameterInstance(instance: Instance) { - this.selectedParameterInstance = instance; - this.newParameter = this.getParameters()[0]; - } - - selectOutputInstance(instance: Instance) { - this.selectedOutputInstance = instance; - this.selectOutput(null); - } - - selectOutput(variable: ScalarVariable) { - this.selectedOutput = variable; - this.selectInputInstance(null); - } - - selectInputInstance(instance: Instance) { - this.selectedInputInstance = instance; - } - - getInitialValues(): Array { - let initialValues: Array = []; - - this.selectedParameterInstance.initialValues.forEach((value, variable) => { - initialValues.push(new ScalarValuePair(variable, value)); - }); - - return initialValues; - } - - addParameter() { - if (!this.newParameter) return; - - this.selectedParameterInstance.initialValues.set(this.newParameter, ''); - this.newParameter = this.getParameters()[0]; - } - - isTypeBool(type: ScalarVariableType) { - return type === ScalarVariableType.Bool; - } - - setParameter(parameter: ScalarVariable, value: any) { - if (parameter.type === ScalarVariableType.Real) - value = parseFloat(value); - else if (parameter.type === ScalarVariableType.Int) - value = parseInt(value); - else if (parameter.type === ScalarVariableType.Bool) - value = !!value; - - this.selectedParameterInstance.initialValues.set(parameter, value); - } - - removeParameter(instance: Instance, parameter: ScalarVariable) { - instance.initialValues.delete(parameter); - this.newParameter = this.getParameters()[0]; - } - - getParameters() { - if (!this.selectedParameterInstance) - return [null]; - - return this.selectedParameterInstance.fmu.scalarVariables - .filter(variable => isCausalityCompatible(variable.causality, CausalityType.Parameter) && !this.selectedParameterInstance.initialValues.has(variable)); - } - - getOutputs() { - return this.selectedOutputInstance.fmu.scalarVariables - .filter(variable => isCausalityCompatible(variable.causality, CausalityType.Output)); - } - - getInputs() { - return this.selectedInputInstance.fmu.scalarVariables - .filter(variable => isCausalityCompatible(variable.causality, CausalityType.Input) && isTypeCompatiple(variable.type, this.selectedOutput.type)); - } - - isInputConnected(input: ScalarVariable) { - let pairs = this.selectedOutputInstance.outputsTo.get(this.selectedOutput); - - if (!pairs) - return false; - - return pairs.filter(pair => pair.instance === this.selectedInputInstance && pair.scalarVariable === input).length > 0; - } - - onConnectionChange(checked: boolean, input: ScalarVariable) { - let outputsTo: InstanceScalarPair[] = this.selectedOutputInstance.outputsTo.get(this.selectedOutput); - - if (checked) { - if (outputsTo == null) { - outputsTo = []; - this.selectedOutputInstance.outputsTo.set(this.selectedOutput, outputsTo); - } - outputsTo.push(new InstanceScalarPair(this.selectedInputInstance, input)); - } else { - outputsTo.splice(outputsTo.findIndex(pair => pair.instance === this.selectedInputInstance && pair.scalarVariable === input), 1); - - if (outputsTo.length === 0) - this.selectedOutputInstance.outputsTo.delete(this.selectedOutput); - } - } - - - createDisplayFmuPath(fmusRootPath: string, path: string): string { - - if (path.startsWith(fmusRootPath)) { - return Path.basename(path); - } - else { - return path; - } - } - - - getWarnings() { - return this.warnings.filter(w => !(w instanceof ErrorMessage)); - } - - getErrors() { - return this.warnings.filter(w => w instanceof ErrorMessage); - } -} diff --git a/src/angular2-app/mm/mm-overview.component.html b/src/angular2-app/mm/mm-overview.component.html deleted file mode 100644 index a318244..0000000 --- a/src/angular2-app/mm/mm-overview.component.html +++ /dev/null @@ -1,36 +0,0 @@ -
-
- -
-
- -
-
- -
-
-
- -
-
{{output.name}}
-
-
-
- {{connection.instance.fmu.name}}.{{connection.instance.name}}.{{connection.scalarVariable.name}} -
-
-
- -
- -
- Please fix the following issues before saving: -
-
{{error.message}}
-
-
-
{{warning.message}}
-
-
-
-
\ No newline at end of file diff --git a/src/angular2-app/mm/mm-overview.component.ts b/src/angular2-app/mm/mm-overview.component.ts deleted file mode 100644 index 9462e9d..0000000 --- a/src/angular2-app/mm/mm-overview.component.ts +++ /dev/null @@ -1,91 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import { OnInit, Component, Input, NgZone } from "@angular/core"; -import { MultiModelConfig } from "../../intocps-configurations/MultiModelConfig"; -import { Serializer } from "../../intocps-configurations/Parser"; -import { OutputConnectionsPair } from "../coe/models/Fmu"; -import IntoCpsApp from "../../IntoCpsApp"; -import { WarningMessage, ErrorMessage } from "../../intocps-configurations/Messages"; - -@Component({ - selector: "mm-overview", - templateUrl: "./angular2-app/mm/mm-overview.component.html" -}) -export class MmOverviewComponent { - private _path: string; - - @Input() - set path(path: string) { - this._path = path; - - if (path) - this.parseConfig(); - } - get path(): string { - return this._path; - } - - private config: MultiModelConfig; - warnings: WarningMessage[] = []; - - constructor(private zone: NgZone) { - - } - - parseConfig() { - let project = IntoCpsApp.getInstance().getActiveProject(); - - MultiModelConfig - .parse(this.path, project.getFmusPath()) - .then(config => this.zone.run(() => { this.config = config; this.warnings = this.config.validate(); })).catch(err => console.log(err)); - } - - getOutputs() { - let outputs: OutputConnectionsPair[] = []; - - this.config.fmuInstances.forEach(instance => { - instance.outputsTo.forEach((connections, scalarVariable) => { - outputs.push(new OutputConnectionsPair(Serializer.getIdSv(instance, scalarVariable), connections)); - }); - }); - - return outputs; - } - - getWarnings() { - return this.warnings.filter(w => !(w instanceof ErrorMessage)); - } - - getErrors() { - return this.warnings.filter(w => w instanceof ErrorMessage); - } -} diff --git a/src/angular2-app/mm/mm-page.component.html b/src/angular2-app/mm/mm-page.component.html deleted file mode 100644 index 6ac39fe..0000000 --- a/src/angular2-app/mm/mm-page.component.html +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/angular2-app/mm/mm-page.component.ts b/src/angular2-app/mm/mm-page.component.ts deleted file mode 100644 index ef47e00..0000000 --- a/src/angular2-app/mm/mm-page.component.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import {Component, Input} from "@angular/core"; -/* import {MmConfigurationComponent} from "./mm-configuration.component"; -import {MmOverviewComponent} from "./mm-overview.component"; -import {MultiModelConfig} from "../../intocps-configurations/MultiModelConfig"; -import IntoCpsApp from "../../IntoCpsApp"; -import {PanelComponent} from "../shared/panel.component"; */ - -@Component({ - selector: "mm-page", - templateUrl: "./angular2-app/mm/mm-page.component.html", -}) -export class MmPageComponent { - @Input() - path:string; - constructor() { - console.log("MMPAGECOMPONENT"); - } -} diff --git a/src/angular2-app/mm/mm.module.ts b/src/angular2-app/mm/mm.module.ts deleted file mode 100644 index ba0451c..0000000 --- a/src/angular2-app/mm/mm.module.ts +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ -import {NgModule} from "@angular/core"; -import {MmPageComponent} from "./mm-page.component"; -import {MmConfigurationComponent} from "./mm-configuration.component"; -import {MmOverviewComponent} from "./mm-overview.component"; -import {PanelComponent} from "../shared/panel.component"; -import { SharedModule } from "../shared/shared.module"; -import { BrowserModule } from '@angular/platform-browser' -import { FormsModule, ReactiveFormsModule } from "@angular/forms"; -import {FileBrowserComponent} from "./inputs/file-browser.component" -@NgModule({ - imports: [ BrowserModule, FormsModule, ReactiveFormsModule, SharedModule], // module dependencies - declarations: [ MmPageComponent, - MmConfigurationComponent, - MmOverviewComponent], // components and directives - exports: [MmPageComponent] - }) - export class MmModule { - - constructor(){ - console.log("MM-MODULE") - } - } diff --git a/src/angular2-app/shared/coe-launch.component.html b/src/angular2-app/shared/coe-launch.component.html deleted file mode 100644 index 3a1b5f4..0000000 --- a/src/angular2-app/shared/coe-launch.component.html +++ /dev/null @@ -1,13 +0,0 @@ -
- Co-Simulation Engine offline. No connection at {{ coeSimulationService.coeUrl }}. - -
-
- {{coeVersions[coeSimulationService.getMaestroVersion()]}}, version {{ coeSimulationService.coeVersionNumber }}, online at {{ coeSimulationService.coeUrl }}. -
-
- {{coeVersions[required_coe_version]}} is required!! - {{coeVersions[coeSimulationService.getMaestroVersion()]}}, version {{ coeSimulationService.coeVersionNumber }}, is online at {{ coeSimulationService.coeUrl }}. -
\ No newline at end of file diff --git a/src/angular2-app/shared/coe-launch.component.ts b/src/angular2-app/shared/coe-launch.component.ts deleted file mode 100644 index 5243756..0000000 --- a/src/angular2-app/shared/coe-launch.component.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Component, Input, OnDestroy } from "@angular/core"; -import { Subject, Subscription } from "rxjs"; -import { MaestroApiService, maestroVersions } from "./maestro-api.service"; - -@Component({ - selector: "coe-launch", - templateUrl: "./angular2-app/shared/coe-launch.component.html" - }) -export class CoeLaunchComponent implements OnDestroy { - private _coeIsOnlineSub: Subscription; - private online: boolean = false; - private correctCoeVersion: boolean = true; - private coeVersions = maestroVersions; - - @Input() - required_coe_version: maestroVersions = undefined; - - @Input() - coeLaunchClick: Subject; - - constructor(private coeSimulationService: MaestroApiService) { - this._coeIsOnlineSub = coeSimulationService.startMonitoringOnlineStatus(isOnline => { - if(this.required_coe_version) { - this.correctCoeVersion = this.required_coe_version == coeSimulationService.getMaestroVersion(); - } - this.online = isOnline; - } ); - } - ngOnDestroy(): void { - this.coeSimulationService.stopMonitoringOnlineStatus(this._coeIsOnlineSub); - } - - private onCoeLaunchClick() { - if(this.coeLaunchClick) { - this.coeLaunchClick.next(); - } - this.coeSimulationService.launchCOE(); - } -} \ No newline at end of file diff --git a/src/angular2-app/shared/file-system.service.ts b/src/angular2-app/shared/file-system.service.ts deleted file mode 100644 index e120692..0000000 --- a/src/angular2-app/shared/file-system.service.ts +++ /dev/null @@ -1,96 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import {Injectable, NgZone} from "@angular/core"; -import * as fs from "fs"; - -// This service wraps the Node.JS filesystem API. - -@Injectable() -export class FileSystemService { - constructor(private zone:NgZone) { - - } - - // Wrap the filesystem API in a promise and the Angular zone - private wrap(fn:(resolve:Function, reject:Function) => void) { - return new Promise((resolve, reject) => { - this.zone.run(() => fn(resolve, reject)); - }); - } - - // this causes a flaw in coe-simulation.service - readFile(path:string):Promise { - return this.wrap((reject, resolve) => { - fs.readFile(path, "utf8", (error, data) => { - if (error) - reject(error); - else - resolve(data); - }); - }); - } - - writeFile(path:string, content:string) { - return this.wrap((resolve, reject) => { - fs.writeFile(path, content, "utf8", (error) => { - if (error) - reject(error); - else - resolve(); - }); - }); - } - - copyFile(source:string, target:string) { - return this.wrap((resolve, reject) => { - let read = fs.createReadStream(source); - read.on("error", (error:Error) => reject(error)); - - let write = fs.createWriteStream(target); - write.on("error", (error:Error) => reject(error)); - write.on("close", () => resolve()); - - read.pipe(write); - }); - } - - mkdir(path:string) { - return this.wrap((resolve, reject) => { - fs.mkdir(path, error => { - if (error) - reject(error); - else - resolve(); - }); - }); - } -} diff --git a/src/angular2-app/shared/graph.ts b/src/angular2-app/shared/graph.ts deleted file mode 100644 index 4e54da1..0000000 --- a/src/angular2-app/shared/graph.ts +++ /dev/null @@ -1,202 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import { BehaviorSubject } from "rxjs"; -import { CoSimulationConfig, LiveGraph } from "../../intocps-configurations/CoSimulationConfig"; -import { SettingsService, SettingKeys } from "../shared/settings.service"; -import { Serializer } from "../../intocps-configurations/Parser"; - -export class Graph { - private config: CoSimulationConfig; - graphMap: Map>> = new Map(); - private counter: number = 0; - private graphMaxDataPoints: number = 100; - private webSocket: WebSocket; - private external = false; - private progressCallback: (n: number) => void; - finished : boolean ; - - public webSocketOnOpenCallback: () => void; - - public setFinished() - { - this.finished = true; - } - - public setProgressCallback(progressCallback?: (n: number) => void) { - if (progressCallback) - this.progressCallback = progressCallback; - } - - public setExternal(external: boolean) { this.external = external; } - - public setGraphMaxDataPoints(graphMaxDataPoints: number, ) { - this.graphMaxDataPoints = graphMaxDataPoints; - } - - public setCoSimConfig(config: CoSimulationConfig) { - this.config = config; - } - - public reset() { - this.finished = false; - this.graphMap.clear(); - } - - public getDataset(graph: LiveGraph): BehaviorSubject> { - return this.graphMap.get(graph); - } - - public getGraphs(): LiveGraph[] { - return Array.from(this.graphMap.keys()); - } - public getInternalGraphs() : LiveGraph[] { - return Array.from(this.graphMap.keys()).filter((x: LiveGraph) => { return !x.externalWindow; }); - } - - public initializeSingleDataset(g: LiveGraph) { - this.graphMap.clear(); - let ds = new BehaviorSubject([]); - this.graphMap.set(g, ds); - this.getGraphs(); - let datasets: Array = []; - g.getSerializedLiveStream().forEach((value: any, index: any) => { - value.forEach((sv: any) => { - let qualifiedName = index + "." + sv; - datasets.push({ - name: qualifiedName, - y: [], - x: [] - }); - }); - }); - ds.next(datasets); - } - public initializeDatasets() { - this.finished = false; - this.graphMap.clear(); - - this.config.liveGraphs.forEach(g => { - - let ds = new BehaviorSubject([]); - this.graphMap.set(g, ds); - - let datasets: Array = []; - - g.getLivestream().forEach((value: any, index: any) => { - - value.forEach((sv: any) => { - let qualifiedName = Serializer.getIdSv(index, sv); - datasets.push({ - name: qualifiedName, - y: [], - x: [] - }) - }); - }); - - ds.next(datasets); - }); - } - public launchWebSocket(webSocket: string) { - console.log("launching websocket: " + webSocket); - this.counter = 0; - this.webSocket = new WebSocket(webSocket); - this.webSocket.onopen = this.webSocketOnOpenCallback - - this.webSocket.addEventListener("error", event => console.error(event)); - this.webSocket.addEventListener("message", event => this.onMessage(event)); - } - private onMessage(event: MessageEvent) { - let rawData = JSON.parse(event.data); - let graphDatasets: Map>, any> = new Map>, any>(); - this.graphMap.forEach(ds => { graphDatasets.set(ds, ds.getValue()) }); - - let newCOE = false; - let xValue = this.counter++; - //Preparing for new livestream messages. It has the following structure: - // {"data":{"{integrate}":{"inst2":{"output":"0.0"}},"{sine}":{"sine":{"output":"0.0"}}},"time":0.0}} - if ("time" in rawData) { - xValue = rawData.time; - if (this.progressCallback) { - if (rawData.time < this.config.endTime) { - let pct = (rawData.time / this.config.endTime) * 100; - this.progressCallback(Math.round(pct)); - } else { - this.progressCallback(100); - } - } - rawData = rawData.data; - } - - Object.keys(rawData).forEach(fmuKey => { - if (fmuKey.indexOf("{") !== 0) return; - - Object.keys(rawData[fmuKey]).forEach(instanceKey => { - - Object.keys(rawData[fmuKey][instanceKey]).forEach(outputKey => { - let value = rawData[fmuKey][instanceKey][outputKey]; - - if (value == "true") value = 1; - else if (value == "false") value = 0; - - graphDatasets.forEach((ds: any, index: any) => { - - let dataset = ds.find((dataset: any) => dataset.name === `${fmuKey}.${instanceKey}.${outputKey}`); - if (dataset) { - dataset.y.push(value); - dataset.x.push(xValue); - if(this.graphMaxDataPoints > 0) - this.truncateDataset(dataset, this.graphMaxDataPoints); - } - }) - }); - }); - }); - - graphDatasets.forEach((value: any, index: BehaviorSubject) => { - index.next(value); - }); - } - - private truncateDataset(ds: any, maxLen: number) { - let x: Number[] = ds.x; - let size = x.length; - if (size > maxLen) { - ds.x = x.slice(size - maxLen, size) - ds.y = ds.y.slice(size - maxLen, size) - } - } - - public closeSocket() { - this.webSocket.close(); - } -} diff --git a/src/angular2-app/shared/line-chart.component.ts b/src/angular2-app/shared/line-chart.component.ts deleted file mode 100644 index 570181f..0000000 --- a/src/angular2-app/shared/line-chart.component.ts +++ /dev/null @@ -1,177 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import { OnInit, Component, ElementRef, Input, OnDestroy } from "@angular/core"; -import { BehaviorSubject } from "rxjs"; -var Plotly = require('plotly.js-dist') - -@Component({ - selector: 'line-chart', - template: '' -}) -export class LineChartComponent implements OnInit, OnDestroy { - private loading: boolean = true; - private redrawCooldown: boolean = false; - private _resizeNode: any; - - private lastUpdateTime: number = 0; - private lastDatasets: Array; - //https://plot.ly/javascript/reference/#layout - private layout = { - legend: { - orientation: "v", - x: 0, - y: -0.1, - xanchor: "left", - yanchor: "top", - tracegroupgap: 20 - }, - margin: { - l: 25, r: 25, b: 25, t: 25, pad: 0 - }, - xaxis: { - showgrid: false, - zeroline: false - }, - yaxis: { - showline: false - }, - showlegend: true, - }; - - private options = { - displaylogo: false - }; - - constructor(private element: ElementRef) { - - } - - ngOnDestroy(): void { - window.removeEventListener('resize', this.resizeEventListener); - } - - @Input() - set datasets(datasets: BehaviorSubject) { - datasets.subscribe(datasets => { this.lastDatasets = datasets; this.redraw(datasets) }); - } - - @Input() - set finished(isFinished: boolean){ - - if(isFinished) { - this.draw(this.lastDatasets); - } - } - - @Input() - set something(something: any) { - this.redrawLayoutChange(); - } - - private redrawLayoutChange() { - let node = Plotly.d3 - .select(this.element.nativeElement) - .style({ - width: '100%', - height: '80vh', - display: 'block', - - }) - .node(); - - Plotly - .newPlot(node, [], this.layout, this.options) - .then(() => this.loading = false); - - Plotly.Plots.resize(node); - } - - private visibleRows: number = 1; - - @Input() - set livegraphvisiblerowcount(rows: number) { - if (rows < 1) - rows = 1; - this.visibleRows = rows; - // let node = Plotly.d3 - // .select(this.element.nativeElement) - // .style({ - // width: '100%', - // height: this.visibleRows + 'vh', - // display: 'block', - - // }) - // .node(); - this.redrawLayoutChange(); - } - - ngOnInit() { - this._resizeNode = Plotly.d3 - .select(this.element.nativeElement) - .style({ - width: '100%', - height: (80 / this.visibleRows) + 'vh', - display: 'block', - - }) - .node(); - - Plotly - .newPlot(this._resizeNode, [], this.layout, this.options) - .then(() => this.loading = false); - - window.addEventListener('resize', this.resizeEventListener); - } - - private resizeEventListener = () => { - Plotly.Plots.resize(this._resizeNode) - }; - - private draw(datasets: Array) - { - this.element.nativeElement.data = datasets; - requestAnimationFrame(() => { - Plotly.redraw(this.element.nativeElement); - this.redrawCooldown = false; - this.lastUpdateTime = Date.now(); - }); - } - - private redraw(datasets: Array) { - if (this.loading) return; - - if (this.redrawCooldown === false && Date.now() - this.lastUpdateTime > 150) { - this.redrawCooldown = true; - this.draw(datasets); - } - } -} diff --git a/src/angular2-app/shared/maestro-api.service.ts b/src/angular2-app/shared/maestro-api.service.ts deleted file mode 100644 index 84faaa8..0000000 --- a/src/angular2-app/shared/maestro-api.service.ts +++ /dev/null @@ -1,291 +0,0 @@ -import { HttpClient, HttpErrorResponse } from '@angular/common/http'; -import { Injectable, OnDestroy } from "@angular/core"; -import { CoeProcess } from "../../coe-server-status/CoeProcess"; -import { IntoCpsApp } from "../../IntoCpsApp"; -import { map, timeout } from 'rxjs/operators'; -import { Subject, Subscription } from 'rxjs'; -import * as http from "http" -import { SettingsService, SettingKeys } from "./settings.service"; -import * as fs from 'fs' -import { timer } from 'rxjs'; -const JSZip = require("jszip"); - -// Verificaiton DTO utilised by Maestro -interface IVerificationDTO { - verifiedSuccessfully: boolean; - uppaalModel: string; - errorMessage: string; -}; - -// The json error format of Maestro -interface IVndError { - logref: string; - message: string; -} - -export enum simulationEndpoints { - simulate = "simulate", - sigverSimulate = "sigverSimulate" -} - -export enum maestroVersions { - maestroV1 = 1, - maestroV2 = 2 -} - -@Injectable({ - providedIn: 'root', -}) -export class MaestroApiService implements OnDestroy { - private _coe: CoeProcess; - private _coeIsOnline = new Subject(); - private _timerSubscription: Subscription; - - coeVersionNumber: string = ""; - coeUrl: string = ""; - - constructor(private httpClient: HttpClient, private settings: SettingsService) { - this.coeUrl = this.settings.get(SettingKeys.COE_URL); - this._coe = IntoCpsApp.getInstance().getCoeProcess(); - } - - ngOnDestroy() { - this._timerSubscription.unsubscribe(); - } - - /* - Simulation API entry points methods - */ - getCoeVersionNumber(): Promise { - return this.httpClient.get(`http://${this.coeUrl}/version`).pipe(timeout(2000), map((response: any) => { - //This regex match expects the coe version number to have the format x.x.x - this.coeVersionNumber = response.version.match('[\\d\\.]+')[0]; - return this.coeVersionNumber; - })).toPromise(); - } - - stopSimulation(simulationSessionId: string): Promise { - return new Promise((resolve, reject) => { - this.httpClient.get(`http://${this.coeUrl}/stopsimulation/${simulationSessionId}`) - .subscribe((res: Response) => { resolve(res) }, (err: Response) => reject(err)); - }); - } - - launchCOE() { - if (!this._coe.isRunning()) IntoCpsApp.getInstance().getCoeProcess().start(); - } - - createSimulationSession(): Promise { - return new Promise ((resolve, reject) => { - this.httpClient.get(`http://${this.coeUrl}/createSession`).subscribe((response: any) => resolve(response.sessionId), (err: Response) => reject(err)); - }); - } - - uploadFmus(fmus: FormData, simulationSessionId: string): Promise { - return new Promise ((resolve, reject) => { - this.httpClient.post(`http://${this.coeUrl}/upload/${simulationSessionId}`, fmus) - .subscribe((res: Response) => { resolve(res) }, (err: Response) => reject(err)); - }); - } - - initializeCoe(configJson: any, simulationSessionId: string): Promise { - return new Promise ((resolve, reject) => { - this.httpClient.post(`http://${this.coeUrl}/initialize/${simulationSessionId}`, configJson) - .subscribe((res: Response) => { resolve(res) }, (err: Response) => reject(err)); - }); - } - - getPlainResult(simulationSessionId: string): Promise { - return new Promise ((resolve, reject) => { - this.httpClient.get(`http://${this.coeUrl}/result/${simulationSessionId}/plain`, {responseType: 'text'}) - .subscribe((res) => resolve(res), (err: Response) => reject(err)) - }); - } - - getResults(resultsPath: string, simulationSessionId: string): Promise { - return new Promise ((resolve, reject) => { - var resultsStream = fs.createWriteStream(resultsPath); - http.get(`http://${this.coeUrl}/result/${simulationSessionId}/zip`, (response: http.IncomingMessage) => { - if(response.statusCode != 200) { - reject(response); - } - response.pipe(resultsStream); - response.on('end', () => { - resolve(); - }); - }); - }); - } - - destroySession(simulationSessionId: string): Promise { - return new Promise ((resolve, reject) => { - http.get(`http://${this.coeUrl}/destroy/${simulationSessionId}`, (response: any) => { - if (response.statusCode != 200) { - reject(response); - } else { - resolve(); - } - }); - }); - } - - simulate(simulationData: any, simulationEndpoint: simulationEndpoints, simulationSessionId: string): Promise { - return new Promise ((resolve, reject) => { - this.httpClient.post(`http://${this.coeUrl}/${simulationEndpoint}/${simulationSessionId}`, simulationData) - .subscribe((res: Response) => { resolve(res) }, (err: Response) => reject(err)); - }); - } - - executeViaCLI(simulationSessionId: string): Promise { - return new Promise ((resolve, reject) => { - this.httpClient.post(`http://${this.coeUrl}/executeViaCLI/${simulationSessionId}`, {"executeViaCLI": true}).subscribe(() => resolve(), (err: Response) => reject(err)); - }); - } - - /* - Scenario verifier API entry points methods - */ - generateScenario(extendedMultiModelObj: Object): Promise { - return new Promise((resolve, reject) => { - this.httpClient.post(`http://${this.coeUrl}/generateAlgorithmFromMultiModel`, extendedMultiModelObj, { responseType: 'text' }).toPromise().then(response => { - const blob = new Blob([response], { type: 'text/plain' }); - resolve(new File([blob], "masterModel.conf", { type: blob.type })); - }, (errorResponse: HttpErrorResponse) => { - this.errorJsonToMsg(errorResponse).then(msg => reject(msg)).catch(err => { console.log(err); reject(errorResponse.message) }); - }) - }); - } - - verifyAlgorithm(masterModelAsString: string): Promise { - return new Promise((resolve, reject) => { - this.httpClient.post(`http://${this.coeUrl}/verifyAlgorithm`, masterModelAsString).toPromise().then(response => { - resolve(response as IVerificationDTO); - }, (errorResponse: HttpErrorResponse) => { - this.errorJsonToMsg(errorResponse).then(msg => reject(msg)).catch(err => { console.log(err); reject(errorResponse.message) }); - }) - }); - } - - visualizeTrace(masterModelAsString: string): Promise { - return new Promise((resolve, reject) => { - this.httpClient.post(`http://${this.coeUrl}/visualizeTrace`, masterModelAsString).toPromise().then(response => { - resolve(new File([response as Blob], "trace_visualization.mp4", { lastModified: new Date().getTime(), type: 'blob' })); - }, (errorResponse: HttpErrorResponse) => { - this.errorJsonToMsg(errorResponse).then(msg => reject(msg)).catch(err => { console.log(err); reject(errorResponse.message) }); - }) - }); - } - - /* - Non API methods - */ - startMonitoringOnlineStatus(callback: (n: boolean) => void): Subscription { - if(!this._timerSubscription || this._timerSubscription.closed){ - this._timerSubscription = timer(0, 2000).subscribe(() => this.isCoeOnline()); - } - return this._coeIsOnline.asObservable().subscribe(callback); - } - - stopMonitoringOnlineStatus(subscription: Subscription) { - subscription.unsubscribe(); - if(this._coeIsOnline.observers.length < 1){ - this._timerSubscription.unsubscribe(); - } - } - - getWebSocketSessionUrl(simulationSessionId: string): string { - return `ws://${this.coeUrl}/attachSession/${simulationSessionId}`; - } - - getMaestroVersion(): maestroVersions { - if(!this.coeVersionNumber) { - return undefined; - } - - let version: maestroVersions; - - switch(Number.parseInt(this.coeVersionNumber.split('.')[0])) { - case 1: - version = maestroVersions.maestroV1; - break; - case 2: - version = maestroVersions.maestroV2; - break; - } - - if(!version){ - console.warn("Unknown Maestro version: " + this.coeVersionNumber); - } - return version; - } - - isRemoteCoe(): boolean { - return this.settings.get(SettingKeys.COE_REMOTE_HOST); - } - - getCoeProcess(): CoeProcess { - if(!this._coe){ - this._coe = IntoCpsApp.getInstance().getCoeProcess(); - } - return this._coe; - } - - inferMaestroVersionFromJarContent(): Promise { - return new Promise (async (resolve, reject) => { - // read the contents of the maestro jar - fs.readFile(this._coe.getCoePath(), (err, data) => { - if (err) { - reject("Unable to infer maestro version from jar: " + err); - } else { - JSZip.loadAsync(data).then((zip: any) => { - if(Object.keys(zip.files).findIndex(file => file.toLowerCase().endsWith(".mabl")) > -1){ - resolve(maestroVersions.maestroV2); - } else { - resolve(maestroVersions.maestroV1); - } - }); - } - }); - }); - } - - private isCoeOnline() { - this.getCoeVersionNumber().then(() => this._coeIsOnline.next(true)).catch(() => this._coeIsOnline.next(false)); - } - - private formatErrorMessage(statusCode: number, IVndErrors: IVndError[]): string { - return statusCode + " => " + IVndErrors.map(vndErr => vndErr.message).reduce((msg, currMsg) => currMsg + "<" + msg + ">"); - } - - // Convert the error message returned from Maestro into a string format. - private errorJsonToMsg(err: HttpErrorResponse): Promise { - return new Promise((resolve, reject) => { - if (typeof err.error === "string") { - const IVndErrors: IVndError[] = JSON.parse(err.error as string); - resolve(this.formatErrorMessage(err.status, IVndErrors));; - } - else if (err.error instanceof Blob && err.error.type === "application/json") { - const reader = new FileReader(); - reader.onload = (e: Event) => { - const IVndErrors: IVndError[] = JSON.parse((e.target).result); - resolve(this.formatErrorMessage(err.status, IVndErrors)); - } - reader.onerror = (e) => { - reject(err); - }; - reader.readAsText(err.error); - } - else if (err.error.type === "application/json") { - try { - resolve(this.formatErrorMessage(err.status, (err.error as IVndError[]))); - } - catch (exc) { - reject(`Unable to convert to error format: ${exc}`); - } - } - else { - reject("Unable to convert to error format"); - } - }); - } -} \ No newline at end of file diff --git a/src/angular2-app/shared/navigation.service.ts b/src/angular2-app/shared/navigation.service.ts deleted file mode 100644 index f0b7093..0000000 --- a/src/angular2-app/shared/navigation.service.ts +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import {Injectable} from "@angular/core"; - -@Injectable() -export class NavigationService { - openComponent:any; - - registerComponent(component: any) { - this.openComponent = component; - } - - canNavigate() { - if (!this.openComponent) - return true; - - if (this.openComponent.onNavigate()) { - this.openComponent = null; - return true; - } else { - return false; - } - } -} diff --git a/src/angular2-app/shared/panel.component.html b/src/angular2-app/shared/panel.component.html deleted file mode 100644 index c388e0f..0000000 --- a/src/angular2-app/shared/panel.component.html +++ /dev/null @@ -1,11 +0,0 @@ -
-
- -

{{title}}

-
-
- -
-
diff --git a/src/angular2-app/shared/panel.component.ts b/src/angular2-app/shared/panel.component.ts deleted file mode 100644 index 6cf6b2a..0000000 --- a/src/angular2-app/shared/panel.component.ts +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import { Input, Component } from '@angular/core'; - -@Component({ - selector: 'panel', - templateUrl: "./angular2-app/shared/panel.component.html", -}) -export class PanelComponent { - @Input() - open:boolean; - - @Input() - title:string = ""; -} diff --git a/src/angular2-app/shared/settings.service.ts b/src/angular2-app/shared/settings.service.ts deleted file mode 100644 index 7cd95e9..0000000 --- a/src/angular2-app/shared/settings.service.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import {Injectable} from "@angular/core"; -import IntoCpsApp from "../../IntoCpsApp"; -import Settings from "../../settings/settings"; - -export {SettingKeys} from "../../settings/SettingKeys"; - -@Injectable() -export class SettingsService { - private settings:Settings; - - constructor() { - this.settings = IntoCpsApp.getInstance().getSettings(); - } - - get(key:string) { - return this.settings.getSetting(key); - } -} diff --git a/src/angular2-app/shared/shared.module.ts b/src/angular2-app/shared/shared.module.ts deleted file mode 100644 index 7fb3b5b..0000000 --- a/src/angular2-app/shared/shared.module.ts +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import { NgModule } from '@angular/core' -import {PanelComponent} from "./panel.component" -import { FormsModule } from '@angular/forms'; -import { CommonModule } from '@angular/common'; -import { FileBrowserComponent } from '../mm/inputs/file-browser.component'; -import { CoeLaunchComponent } from './coe-launch.component'; -@NgModule({ - imports: [FormsModule, CommonModule], - declarations: [ // components and directives - PanelComponent, - FileBrowserComponent, - CoeLaunchComponent], - exports: [PanelComponent, FileBrowserComponent, CoeLaunchComponent] - }) - export class SharedModule { - - constructor(){ - console.log("Shared MODULE") - } - } \ No newline at end of file diff --git a/src/angular2-app/shared/validators.ts b/src/angular2-app/shared/validators.ts deleted file mode 100644 index edb4584..0000000 --- a/src/angular2-app/shared/validators.ts +++ /dev/null @@ -1,135 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import {FormControl, FormArray, FormGroup, AsyncValidatorFn, AbstractControl} from "@angular/forms"; -import {Observable} from 'rxjs'; - -function isString(x:any) { - return typeof x === 'string'; -} - -function isNumber(x:any) { - let number = Number(x); - - return !isNaN(number) && isFinite(number); -} - -function isInteger(x:any) { - let number = Number(x); - - // TODO: It sees 1.0000000000000001 as an integer, due to floating point rounding error. - return !isNaN(number) && isFinite(number) && number % 1 === 0; -} - -export function numberValidator(control: FormControl): { [s: string]: boolean } { - if (!isNumber(control.value)) - return {invalidNumber: true}; -} - -export function integerValidator(control: FormControl): { [s: string]: boolean } { - if (!isInteger(control.value)) - return {invalidInteger: true}; -} - -export function lengthValidator(min: number = null, max: number = null) { - return (control: FormControl) => { - let length = control.value.length; - - if (length === undefined || min !== null && length < min || max !== null && length > max) - return {invalidLength: true}; - } -} - -export function uniqueGroupPropertyValidator(propertyName: string) { - return (control: FormArray) => { - for(let i = 0; i < control.length; i++) { - let group:FormGroup = control.at(i); - let value = group.controls[propertyName].value; - - for(let j = i+1; j < control.length; j++) { - let other:FormGroup = control.at(j); - let otherValue = other.controls[propertyName].value; - - if (value === otherValue) - return {notUnique: value}; - } - } - } -} - -export function uniqueValidator(control: FormControl) { - var elements = control.value; - - for(let i = 0; i < elements.length; i++) { - for(let j = i+1; j < elements.length; j++) { - if (elements[i] === elements[j]) - return {notUnique: true}; - } - } -} - -export function uniqueControlValidator(control: FormArray) { - for(let i = 0; i < control.length; i++) { - for(let j = i+1; j < control.length; j++) { - if (control.at(i).value === control.at(j).value) - return {notUnique: control.at(i).value}; - } - } -} - -// from angular v6 their is a pending call which is new to abstractControls if problems should arise with this function look into that. -export function lessThanValidator(selfName:string, otherName:string): AsyncValidatorFn { - return (group: AbstractControl) : Promise<{ [key: string]: any } | null> | Observable<{ [key: string]: any } | null>=> { - return new Promise((resolve, reject) => { - let self = group.get(selfName); - let other = group.get(otherName); - - if (self.value && other.value && Number(self.value) >= Number(other.value)) { - resolve({ notLessThan: true }); - } else { - resolve(null); - }}); - } - - -} - -export function lessThanValidator2(selfName:string, otherName:string) { - return (group: FormGroup) => { - let self = group.get(selfName); - let other = group.get(otherName); - - if (self.value && other.value && Number(self.value) >= Number(other.value)) { - return {notLessThan:true}; - } - else return null; - } -} diff --git a/src/angular2-app/sigver/SigverViewController.ts b/src/angular2-app/sigver/SigverViewController.ts deleted file mode 100644 index f80ffbf..0000000 --- a/src/angular2-app/sigver/SigverViewController.ts +++ /dev/null @@ -1,62 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import { ViewController } from "../../iViewController"; -import IntoCpsApp from "../../IntoCpsApp"; -import { AppComponent } from "../app.component"; -import * as Path from "path"; - -interface MyWindow extends Window { - ng2app: AppComponent; -} - -declare var window: MyWindow; - -export class SigverViewController extends ViewController { - constructor(private view: HTMLDivElement, private path: string) { - super(view); - } - - initialize() { - $(this.view).css("height", 0); - IntoCpsApp.setTopName(Path.basename(Path.join(this.path, "../"))); - window.ng2app.openSV(this.path); - } - - deInitialize() { - if (window.ng2app.navigationService.canNavigate()) { - window.ng2app.closeAll(); - $(this.view).css("height", "calc(100% - 80px)"); - return true; - } - return false; - } -} diff --git a/src/angular2-app/sigver/sigver-coe-interaction.component.html b/src/angular2-app/sigver/sigver-coe-interaction.component.html deleted file mode 100644 index 481c575..0000000 --- a/src/angular2-app/sigver/sigver-coe-interaction.component.html +++ /dev/null @@ -1,72 +0,0 @@ - - -
- -
Generation requires that MaestroV2 is running
-
-

Master model

-
{{ sigverConfigurationService.configuration.masterModel }}
-

-		
- -
- -
-
- - -
Verification requires that MaestroV2 is running
-
- - - - -
- -
-

{{ verificationErrMsg }}

-
- -
- -
- -
- - - -
- -
-
-
diff --git a/src/angular2-app/sigver/sigver-coe-interaction.component.ts b/src/angular2-app/sigver/sigver-coe-interaction.component.ts deleted file mode 100644 index d4f88e6..0000000 --- a/src/angular2-app/sigver/sigver-coe-interaction.component.ts +++ /dev/null @@ -1,141 +0,0 @@ -import { Component, Input, OnDestroy } from "@angular/core"; -import { DomSanitizer } from "@angular/platform-browser"; -import { Subscription } from "rxjs"; -import * as Fs from "fs"; -import * as Path from "path"; -import { SigverConfigurationService as SigverConfigurationService } from "./sigver-configuration.service"; -import { MaestroApiService, maestroVersions } from "../shared/maestro-api.service"; - -@Component({ - selector: "sigver-coe-interaction", - templateUrl: "./angular2-app/sigver/sigver-coe-interaction.component.html", -}) -export class SigverCoeInteractionComponent implements OnDestroy { - private _configurationChangedSub: Subscription; - private _coeIsOnlineSub: Subscription; - - videoUrl: any; - - @Input() - generationresultspath: string = ""; - - @Input() - verificationresultspath: string = ""; - - verificationErrMsg: string = ""; - - // View state bools - isVerificationFailed: boolean = false; - isCoeOnline: boolean = false; - isGeneratingTraces: boolean = false; - isMasterModelValid: boolean = false; - isVerified: boolean = false; - isGeneratingMasterModel: boolean = false; - isVerifying: boolean = false; - - constructor(private maestroApiService: MaestroApiService, private sanitizer: DomSanitizer, private sigverConfigurationService: SigverConfigurationService) { - this._coeIsOnlineSub = this.maestroApiService.startMonitoringOnlineStatus( - (isOnline) => (this.isCoeOnline = isOnline && maestroApiService.getMaestroVersion() == maestroVersions.maestroV2) - ); - - this._configurationChangedSub = this.sigverConfigurationService.configurationChangedObservable.subscribe(() => { - this.handleConfigurationChanges(); - }); - } - - ngOnDestroy(): void { - this.maestroApiService.stopMonitoringOnlineStatus(this._coeIsOnlineSub); - this._configurationChangedSub.unsubscribe(); - } - - onGenerateMasterModelClick() { - this.isGeneratingMasterModel = true; - this.maestroApiService - .generateScenario(this.sigverConfigurationService.configurationToExtendedMultiModelDTO()) - .then( - (masterModelFile) => { - masterModelFile.text().then((masterModel) => { - this.sigverConfigurationService.configuration.masterModel = masterModel; - this.sigverConfigurationService.configurationChanged(); - this.sigverConfigurationService.saveConfiguration(); - this.isMasterModelValid = true; - }); - this.writeFileToDir(masterModelFile, this.generationresultspath); - }, - (errMsg) => { - console.error(`Error occurred when generating the master model: ${errMsg}`); - } - ) - .finally(() => { - this.isGeneratingMasterModel = false; - }); - } - - onVerifyClick() { - this.isVerifying = true; - this.maestroApiService - .verifyAlgorithm(this.sigverConfigurationService.configuration.masterModel) - .then( - (res) => { - this.isVerified = true; - this.isVerificationFailed = !res.verifiedSuccessfully; - if (this.isVerificationFailed) { - this.verificationErrMsg = res.errorMessage; - } - const blob = new Blob([res.uppaalModel], { type: "text/plain" }); - const uppaalFile = new File([blob], "uppaalModel.xml", { - type: blob.type, - }); - this.writeFileToDir(uppaalFile, this.verificationresultspath); - }, - (errMsg) => { - console.error(`Error occurred when verifying the master model: ${errMsg}`); - } - ) - .finally(() => { - this.isVerifying = false; - }); - } - - onVisualizeTracesClick() { - this.isGeneratingTraces = true; - this.maestroApiService - .visualizeTrace(this.sigverConfigurationService.configuration.masterModel) - .then( - (videoFile) => { - this.videoUrl = this.sanitizer.bypassSecurityTrustUrl(window.URL.createObjectURL(videoFile)); - this.writeFileToDir(videoFile, this.verificationresultspath); - }, - (errMsg) => { - console.error(`Error occurred when visualizing traces: ${errMsg}`); - } - ) - .finally(() => (this.isGeneratingTraces = false)) - .finally(() => { - this.isGeneratingTraces = false; - }); - } - - handleConfigurationChanges() { - this.isMasterModelValid = this.sigverConfigurationService.configuration.masterModel != ""; - this.isVerified = this.isMasterModelValid && this.isVerified; - this.isVerificationFailed = this.isVerified ? this.isVerificationFailed : false; - if (!this.isVerificationFailed) { - this.videoUrl = null; - } - } - - writeFileToDir(file: File, dirPath: string): Promise { - return new Promise((resolve, reject) => { - file - .arrayBuffer() - .then((arrBuff) => { - const writeStream = Fs.createWriteStream(Path.join(dirPath, file.name)); - writeStream.write(Buffer.from(arrBuff)); - writeStream.close(); - resolve(); - }) - .catch((err) => reject(`Error occurred when writing file to path ${dirPath}: ${err}`)); - }); - } -} diff --git a/src/angular2-app/sigver/sigver-configuration.component.html b/src/angular2-app/sigver/sigver-configuration.component.html deleted file mode 100644 index 6b8c82a..0000000 --- a/src/angular2-app/sigver/sigver-configuration.component.html +++ /dev/null @@ -1,95 +0,0 @@ - -
-
-
-

Multi-model

-
-
-
- -

- {{ getNameOfSelectedExperiment() }} -

- -
- -
- -
-
-

- Unable to locate {{ getExperimentNameFromPath(priorExperimentPath, "3") }} -

- -
-
-
-
- -
-

Input Port Reactivity

-
- - - - - - - - - - - - - -
PortReactivity
-

{{ entry.key }}

-
- -

{{ entry.value }}

-
-
-
- -
- - - -
-
diff --git a/src/angular2-app/sigver/sigver-configuration.component.ts b/src/angular2-app/sigver/sigver-configuration.component.ts deleted file mode 100644 index 3dbe087..0000000 --- a/src/angular2-app/sigver/sigver-configuration.component.ts +++ /dev/null @@ -1,252 +0,0 @@ -import { Component, OnDestroy } from "@angular/core"; -import IntoCpsApp from "../../IntoCpsApp"; -import * as Path from "path"; -import * as Fs from "fs"; -import * as FsE from "fs-extra"; -import { Project } from "../../proj/Project"; -import { Reactivity, SigverConfiguration } from "../../intocps-configurations/sigver-configuration"; -import { SigverConfigurationService } from "./sigver-configuration.service"; -import { Subscription } from "rxjs"; -import { CoSimulationConfig } from "../../intocps-configurations/CoSimulationConfig"; - -@Component({ - selector: "sigver-configuration", - templateUrl: "./angular2-app/sigver/sigver-configuration.component.html", -}) -export class SigverConfigurationComponent implements OnDestroy { - private coePath: string = ""; - private _configurationLoadedSub: Subscription; - - public reactivityKeys = Object.keys(Reactivity); - public editing: boolean = false; - public usePriorExperiment: boolean = false; - public cantLocatePriorExperiment = false; - public experimentPath: string = ""; - public priorExperimentPath: string = ""; - public experimentsPaths: string[] = this.getExperimentsPaths(Path.join(IntoCpsApp.getInstance().getActiveProject().getRootFilePath(), Project.PATH_MULTI_MODELS)); - public priorExperimentsPaths: string[] = []; - public coeConfig: CoSimulationConfig; - public portsToReactivity: Map = new Map(); - - constructor(private sigverConfigurationService: SigverConfigurationService) { - this._configurationLoadedSub = this.sigverConfigurationService.configurationLoadedObservable.subscribe(() => this.handleConfigurationLoaded()); - } - - ngOnDestroy(): void { - this._configurationLoadedSub.unsubscribe(); - } - - public getNameOfSelectedExperiment(): string { - return this.getExperimentNameFromPath(this.usePriorExperiment ? this.priorExperimentPath : this.experimentPath, this.usePriorExperiment ? 3 : 2); - } - - public onExperimentPathChanged(experimentPath: string) { - this.loadPriorExperimentsPaths(); - this.experimentPath = experimentPath; - this.usePriorExperiment = false; - this.priorExperimentPath = ""; - this.cantLocatePriorExperiment = false; - this.locateAndsetCoePath(experimentPath) - .then(() => { - this.parseAndSetCoeConfig(this.coePath).then(() => this.resetConfigurationOptionsViewElements()); - }) - .catch((err) => console.error(err)); - } - - public onPriorExperimentPathChanged(experimentPath: string) { - this.priorExperimentPath = experimentPath; - this.usePriorExperiment = true; - this.locateAndsetCoePath(experimentPath) - .then(() => { - this.parseAndSetCoeConfig(this.coePath).then(() => this.resetConfigurationOptionsViewElements()); - }) - .catch((err) => console.error(err)); - } - - public onReactivityChanged(key: string, reactivity: string) { - this.portsToReactivity.set(key, Reactivity[reactivity as keyof typeof Reactivity]); - } - - public async onSubmit() { - if (!this.editing) return; - - const updatedSigverConfiguration = new SigverConfiguration(); - - // Set changes from the view models in a new configuration - updatedSigverConfiguration.experimentPath = this.experimentPath; - updatedSigverConfiguration.masterModel = this.sigverConfigurationService.configuration.masterModel; - updatedSigverConfiguration.priorExperimentPath = !this.usePriorExperiment ? "" : this.priorExperimentPath; - updatedSigverConfiguration.reactivity = new Map(this.portsToReactivity); - const relative = Path.relative(Path.dirname(this.sigverConfigurationService.configurationPath), this.coePath); - const coeFileChanged = Path.basename(this.coePath) != relative; - - if (coeFileChanged) { - await this.updateCoeFileInConfPath() - .then(async () => { - updatedSigverConfiguration.coePath = this.coePath; - const project = IntoCpsApp.getInstance().getActiveProject(); - - await CoSimulationConfig.parse(this.coePath, project.getRootFilePath(), project.getFmusPath()).then((coeConfig) => { - updatedSigverConfiguration.coeConfig = coeConfig; - }); - }) - .catch((err) => console.warn(err)); - } else { - updatedSigverConfiguration.coeConfig = this.sigverConfigurationService.configuration.coeConfig; - } - - updatedSigverConfiguration.coePath = this.coePath; - - //Update and save the configuration - this also triggers a configuration updated event - this.sigverConfigurationService.configuration = updatedSigverConfiguration; - this.sigverConfigurationService.saveConfiguration(); - - this.editing = false; - } - - private parseAndSetCoeConfig(coePath: string): Promise { - return new Promise((resolve, reject) => { - const project = IntoCpsApp.getInstance().getActiveProject(); - CoSimulationConfig.parse(coePath, project.getRootFilePath(), project.getFmusPath()).then( - (coeConf) => { - this.coeConfig = coeConf; - resolve(); - }, - (err) => { - console.error(`Error during parsing of coe config: ${err}`); - reject(); - } - ); - }); - } - - private getExperimentNameFromPath(path: string, depth: number): string { - let elems = path.split(Path.sep); - if (elems.length <= 1) { - return path; - } - let pathToReturn = ""; - for (let i = depth; i >= 1; i--) { - pathToReturn += elems[elems.length - i] + (i == 1 ? "" : " | "); - } - return pathToReturn; - } - - private getExperimentsPaths(path: string): string[] { - let experimentPaths: string[] = []; - const files = Fs.readdirSync(path); - const coeFileName = files.find((f) => f.endsWith("coe.json")); - if (coeFileName && FsE.readJsonSync(Path.join(path, coeFileName)).algorithm.type != "var-step") { - experimentPaths.push(path); - } else { - for (let i in files) { - let fileName = Path.join(path, files[i]); - if (Fs.statSync(fileName).isDirectory()) { - experimentPaths = experimentPaths.concat(this.getExperimentsPaths(fileName)); - } - } - } - return experimentPaths; - } - - private resetConfigurationOptionsViewElements() { - // Set port reactivities to delayed - const inputPorts: string[] = Object.values(this.coeConfig.multiModel.toObject().connections as Map).reduce((prevVal, currVal) => prevVal.concat(currVal), []); - this.portsToReactivity = new Map(inputPorts.map((p) => [p, Reactivity.Delayed])); - } - - private locateAndsetCoePath(coeDir: string): Promise { - return new Promise((resolve, reject) => { - if (!coeDir) { - resolve(); - } - if (!Fs.existsSync(coeDir) || !Fs.lstatSync(coeDir).isDirectory()) { - reject(`"${coeDir}" is not a valid directory`); - } - Fs.promises - .readdir(coeDir) - .then((filesInCOEDir) => { - var coeFileName = filesInCOEDir.find((fileName) => fileName.toLowerCase().endsWith("coe.json")); - if (coeFileName) { - this.coePath = Path.join(coeDir, coeFileName); - resolve(); - } else { - reject("Unable to locate coe file in directory: " + coeDir); - } - }) - .catch((err) => reject(err)); - }); - } - - private loadPriorExperimentsPaths() { - let priorExperimentsPaths: string[] = []; - let files = Fs.readdirSync(this.experimentPath); - for (let i in files) { - let fileName = Path.join(this.experimentPath, files[i]); - if (Fs.statSync(fileName).isDirectory()) { - priorExperimentsPaths = priorExperimentsPaths.concat(this.getExperimentsPaths(fileName)); - } - } - this.priorExperimentsPaths = priorExperimentsPaths; - } - - private updateCoeFileInConfPath(): Promise { - return new Promise((resolve, reject) => { - Fs.promises - .readdir(Path.dirname(this.sigverConfigurationService.configurationPath)) - .then((filesInDir) => { - //Find the old co-simulation file and delete it if present. - const existingCoeFile = filesInDir.find((fileName) => fileName.toLowerCase().endsWith("cos.json")); - if (existingCoeFile) { - const pathToFile = Path.join(Path.dirname(this.sigverConfigurationService.configurationPath), existingCoeFile); - Fs.unlinkSync(pathToFile); - } - //Copy the new file to the sigver project - this.copyCoeToConfigPath().then((newCoePath) => { - this.coePath = newCoePath; - resolve(); - }); - }) - .catch((err) => reject(err)); - }); - } - - private copyCoeToConfigPath(): Promise { - return new Promise((resolve, reject) => { - const expName = this.experimentPath.split(Path.sep); - - const newCoeFileName = "sigver_" + expName[expName.length - 2] + "_" + expName[expName.length - 1] + "_" + "cos.json"; - const destinationPath = Path.join(Path.dirname(this.sigverConfigurationService.configurationPath), newCoeFileName); - Fs.copyFile(this.coePath, destinationPath, (err) => { - if (err) reject(err); - resolve(destinationPath); - }); - }); - } - - private handleConfigurationLoaded() { - // Set view element values from the configuration - this.experimentPath = this.sigverConfigurationService.configuration.experimentPath; - let coeFolderPath = this.experimentPath; - this.usePriorExperiment = this.sigverConfigurationService.configuration.priorExperimentPath != ""; - - if (this.experimentPath != "") { - this.loadPriorExperimentsPaths(); - } - - if (this.usePriorExperiment) { - this.priorExperimentPath = this.sigverConfigurationService.configuration.priorExperimentPath; - this.cantLocatePriorExperiment = this.priorExperimentsPaths.findIndex((p) => p.includes(this.priorExperimentPath)) == -1; - coeFolderPath = this.priorExperimentPath; - } - - if (coeFolderPath) { - this.locateAndsetCoePath(coeFolderPath) - .then(() => this.parseAndSetCoeConfig(this.coePath)) - .catch((err) => { - console.error(err); - }); - } - this.portsToReactivity = new Map(this.sigverConfigurationService.configuration.reactivity); - } -} diff --git a/src/angular2-app/sigver/sigver-configuration.service.ts b/src/angular2-app/sigver/sigver-configuration.service.ts deleted file mode 100644 index 3856c08..0000000 --- a/src/angular2-app/sigver/sigver-configuration.service.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { Injectable } from "@angular/core"; -import { Subject } from "rxjs"; -import { Reactivity, SigverConfiguration } from "../../intocps-configurations/sigver-configuration"; -import * as fs from "fs"; - -@Injectable() -export class SigverConfigurationService { - private _configuration: SigverConfiguration = new SigverConfiguration(); - private _configurationChanged = new Subject(); - private _configurationLoaded = new Subject(); - - public configurationChangedObservable = this._configurationChanged.asObservable(); - public configurationLoadedObservable = this._configurationLoaded.asObservable(); - public configurationPath: string; - public automaticallySaveOnChanges: boolean = true; - public isDefaultConfiguration: boolean = true; - - public set configuration(sigverConfiguration: SigverConfiguration) { - // Search for changes that invalidates the masterModel - let resetMasterModel: boolean = false; - if (sigverConfiguration.masterModel != "") { - for (const entry of Array.from(this._configuration.reactivity.entries())) { - if (!sigverConfiguration.reactivity.has(entry[0]) || sigverConfiguration.reactivity.get(entry[0]) != entry[1]) { - resetMasterModel = true; - break; - } - } - } - this._configuration = sigverConfiguration; - this.isDefaultConfiguration = this._configuration.experimentPath == ""; - if (resetMasterModel) { - this._configuration.masterModel = ""; - } - - this.configurationChanged(); - } - - public get configuration(): SigverConfiguration { - return this._configuration; - } - - loadConfigurationFromPath(path: string = ""): Promise { - return new Promise((resolve, reject) => { - let filePath = path == "" ? this.configurationPath : path; - fs.readFile(filePath, (fileErr, fileData) => { - if (fileErr) { - reject(`Unable to read configuration file from: ${filePath} due to: ${fileErr}`); - } - SigverConfiguration.parse(JSON.parse(fileData.toString())) - .then((res) => { - this.configuration = res; - this.configurationLoaded(); - resolve(); - }) - .catch((err) => { - reject(`Unable to set configuration from file: ${filePath} due to: ${err}`); - }); - }); - }); - } - - configurationChanged() { - this._configurationChanged.next(true); - } - - saveConfiguration(path: string = ""): boolean { - try { - fs.writeFileSync(path == "" ? this.configurationPath : path, JSON.stringify(this._configuration.toObject())); - fs.writeFileSync(this.configuration.coePath, JSON.stringify(this._configuration.coeConfig.toObject())); - } catch (err) { - console.error(`Unable to write configuration to file: ${err}`); - return false; - } - return true; - } - - configurationToExtendedMultiModelDTO(verify: boolean = false): any { - const extendedMultiModelDTO = this._configuration.coeConfig.multiModel.toObject(); - let fmus: any = {}; - this._configuration.coeConfig.multiModel.fmus.forEach((fmu) => { - let fmuPath; - if (fmu.isNested()) { - fmuPath = "coe:/" + fmu.path; - } else { - fmuPath = "file:///" + fmu.path; - } - fmus[fmu.name] = fmuPath.replace(/\\/g, "/").replace(/ /g, "%20"); - }); - extendedMultiModelDTO["fmus"] = fmus; - - const reactivity: { [key: string]: Reactivity } = {}; - this._configuration.reactivity.forEach((value: Reactivity, key: string) => (reactivity[key] = value)); - - const scenarioVerifierDTO: any = {}; - scenarioVerifierDTO[SigverConfiguration.REACTIVITY_TAG] = reactivity; - scenarioVerifierDTO["verification"] = verify; - scenarioVerifierDTO["traceVisualization"] = false; - - extendedMultiModelDTO["sigver"] = scenarioVerifierDTO; - - return extendedMultiModelDTO; - } - - private configurationLoaded() { - this._configurationLoaded.next(true); - } -} diff --git a/src/angular2-app/sigver/sigver-page.component.html b/src/angular2-app/sigver/sigver-page.component.html deleted file mode 100644 index d5b3f7a..0000000 --- a/src/angular2-app/sigver/sigver-page.component.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - -
Scenario needs to be configured
-
- - - -
A master model needs to be generated before running the simulation.
- -
-
diff --git a/src/angular2-app/sigver/sigver-page.component.ts b/src/angular2-app/sigver/sigver-page.component.ts deleted file mode 100644 index e3a96dc..0000000 --- a/src/angular2-app/sigver/sigver-page.component.ts +++ /dev/null @@ -1,111 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - -import { Component, Input, OnDestroy } from "@angular/core"; -import { Subscription } from "rxjs"; -import { SigverConfigurationService } from "./sigver-configuration.service"; -import * as Path from "path"; -import * as Fs from "fs"; -import { maestroVersions } from "../shared/maestro-api.service"; - -@Component({ - selector: "sv-page", - templateUrl: "./angular2-app/sigver/sigver-page.component.html", - providers: [SigverConfigurationService], -}) -export class SigverPageComponent implements OnDestroy { - private _configurationChangedSub: Subscription; - private _path: string = ""; - masterModel: string = ""; - cosConfPath: string = ""; - generationResultsPath: string = ""; - verificationResultsPath: string = ""; - executionResultsPath: string = ""; - disableSimulationBtn: boolean = true; - requiredMaestroVersion: maestroVersions = maestroVersions.maestroV2; - - @Input() - set path(path: string) { - this._path = path; - this.sigverConfigurationService.configurationPath = this._path; - this.sigverConfigurationService - .loadConfigurationFromPath() - .then(() => this.ensureResultPaths(Path.join(this.sigverConfigurationService.configurationPath, "..", "results", Path.sep))) - .catch((err) => console.error(err)); - } - get path(): string { - return this._path; - } - - constructor(private sigverConfigurationService: SigverConfigurationService) { - this._configurationChangedSub = this.sigverConfigurationService.configurationChangedObservable.subscribe(() => { - this.cosConfPath = sigverConfigurationService.configuration.coePath; - this.masterModel = sigverConfigurationService.configuration.masterModel; - this.disableSimulationBtn = this.masterModel == ""; - }); - } - - ngOnDestroy(): void { - this._configurationChangedSub.unsubscribe(); - } - - ensureResultPaths(rootResultsPath: string): Promise { - return new Promise((resolve, reject) => { - this.verificationResultsPath = Path.join(rootResultsPath, "verification"); - this.executionResultsPath = Path.join(rootResultsPath, "execution"); - this.generationResultsPath = Path.join(rootResultsPath, "generation"); - - Promise.all([ - this.ensureDirectoryExistence(this.verificationResultsPath).catch((err) => reject(err)), - this.ensureDirectoryExistence(this.executionResultsPath).catch((err) => reject(err)), - this.ensureDirectoryExistence(this.generationResultsPath).catch((err) => console.log(err)), - ]) - .then(() => resolve()) - .catch((err) => reject(err)); - }); - } - - ensureDirectoryExistence(filePath: string): Promise { - return new Promise((resolve, reject) => { - if (Fs.existsSync(filePath)) { - resolve(); - } - Fs.promises.mkdir(filePath, { recursive: true }).then( - () => { - resolve(); - }, - (err) => { - reject(err); - } - ); - }); - } -} diff --git a/src/angular2-app/sigver/sigver.module.ts b/src/angular2-app/sigver/sigver.module.ts deleted file mode 100644 index b7edada..0000000 --- a/src/angular2-app/sigver/sigver.module.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { NgModule } from "@angular/core"; -import { CoeConfigurationComponent } from "../coe/coe-configuration.component"; -import { CoeSimulationComponent } from "../coe/coe-simulation.component"; -import { CoeLaunchComponent } from "../shared/coe-launch.component"; -import { SigverCoeInteractionComponent } from "./sigver-coe-interaction.component"; -import { SigverConfigurationComponent } from "./sigver-configuration.component"; -import { SigverPageComponent } from "./sigver-page.component"; - -@NgModule({ - declarations: [SigverPageComponent, SigverConfigurationComponent, SigverCoeInteractionComponent], - imports: [CoeConfigurationComponent, CoeSimulationComponent, CoeLaunchComponent], - exports: [SigverPageComponent], -}) -export class SIGVERModule { - constructor() { - console.log("SIGVER MODULE"); - } -} diff --git a/src/bottom.html b/src/bottom.html index 7589cb3..8e47e29 100644 --- a/src/bottom.html +++ b/src/bottom.html @@ -1,17 +1,34 @@ -
-
'; - } - } - if (typeof col.render == 'object') { - data = '
' + infoBubble + (col.render[data] || '') + '
'; - } - if (typeof col.render == 'string') { - var t = col.render.toLowerCase().indexOf(':'); - var tmp = []; - if (t == -1) { - tmp[0] = col.render.toLowerCase(); - tmp[1] = ''; - } else { - tmp[0] = col.render.toLowerCase().substr(0, t); - tmp[1] = col.render.toLowerCase().substr(t+1); - } - // formatters - var func = w2utils.formatters[tmp[0]]; - data = '
' + infoBubble + (typeof func == 'function' ? func(data, tmp[1]) : '') + '
'; - } - } else { - // if editable checkbox - if (edit && ['checkbox', 'check'].indexOf(edit.type) != -1) { - var changeInd = summary ? -(ind + 1) : ind; - style += 'text-align: center;'; - data = ''; - infoBubble = ''; - } - if (this.show.recordTitles) { - // title overwrite - var title = w2utils.stripTags(String(data).replace(/"/g, "''")); - if (col.title != null) { - if (typeof col.title == 'function') title = col.title.call(this, record, ind, col_ind); - if (typeof col.title == 'string') title = col.title; - } - } - data = '
'+ infoBubble + String(data) +'
'; - } - if (data == null) data = ''; - // --> cell TD - if (typeof col.render == 'string') { - var tmp = col.render.toLowerCase().split(':'); - if (['number', 'int', 'float', 'money', 'currency', 'percent', 'size'].indexOf(tmp[0]) != -1) addStyle += 'text-align: right;'; - } - if (record && record.w2ui && typeof record.w2ui.style == 'object') { - if (typeof record.w2ui.style[col_ind] == 'string') addStyle += record.w2ui.style[col_ind] + ';'; - if (typeof record.w2ui.style[col.field] == 'string') addStyle += record.w2ui.style[col.field] + ';'; - } - var isCellSelected = false; - if (isRowSelected && $.inArray(col_ind, sel.columns[ind]) != -1) isCellSelected = true; - // data - data = ' 1 ? 'colspan="'+ col_span + '"' : '') + - '>' + data + ''; - - return data; - }, - - showBubble: function (ind, col_ind) { - var html = ''; - var info = this.columns[col_ind].info; - var rec = this.records[ind]; - var el = $(this.box).find('#grid_'+ this.name +'_data_'+ ind +'_'+ col_ind + ' .w2ui-info'); - if (this.last.bubbleEl) $(this.last.bubbleEl).w2tag(); - if (info.fields == null && typeof info.render == 'function') info.fields = info.render; - this.last.bubbleEl = el; - // if no fields defined - show all - if (info.fields == null) { - info.fields = []; - for (var i = 0; i < this.columns.length; i++) { - var col = this.columns[i]; - info.fields.push(col.field + (typeof col.render == 'string' ? ':' + col.render : '')); - } - } - // generate html - if (typeof info.fields == 'function') { - html = info.fields(rec, ind, col_ind); // custom renderer - } else if ($.isArray(info.fields)) { - // display mentioned fields - html = ''; - for (var i = 0; i < info.fields.length; i++) { - var tmp = String(info.fields[i]).split(':'); - if (tmp[0] == '' || tmp[0] == '-' || tmp[0] == '--' || tmp[0] == '---') { - html += ''; - continue; - } - var col = this.getColumn(tmp[0]); - var val = this.parseField(rec, col.field); - if (tmp.length > 1) { - if (w2utils.formatters[tmp[1]]) { - val = w2utils.formatters[tmp[1]](val, tmp[2] || null); - } else { - console.log('ERROR: w2utils.formatters["'+ tmp[1] + '"] does not exists.') - } - } - if (info.showEmpty !== true && (val == null || val == '')) continue; - if (info.maxLength != null && typeof val == 'string' && val.length > info.maxLength) val = val.substr(0, info.maxLength) + '...'; - html += ''; - } - html += '
' + col.caption + '' + ((val === 0 ? '0' : val) || '') + '
'; - } else if ($.isPlainObject(info.fields)) { - // display some fields - html = ''; - for (var caption in info.fields) { - var fld = info.fields[caption]; - if (fld == '' || fld == '-' || fld == '--' || fld == '---') { - html += ''; - continue; - } - var tmp = String(fld).split(':'); - var col = this.getColumn(tmp[0]); - if (col == null) col = { field: tmp[0], caption: tmp[0] }; // if not found in columns - var val = (col ? this.parseField(rec, col.field) : ''); - if (tmp.length > 1) { - if (w2utils.formatters[tmp[1]]) { - val = w2utils.formatters[tmp[1]](val, tmp[2] || null); - } else { - console.log('ERROR: w2utils.formatters["'+ tmp[1] + '"] does not exists.') - } - } - if (typeof fld == 'function') { - val = fld(rec, ind, col_ind); - } - if (info.showEmpty !== true && (val == null || val == '')) continue; - if (info.maxLength != null && typeof val == 'string' && val.length > info.maxLength) val = val.substr(0, info.maxLength) + '...'; - html += ''; - } - html += '
' + caption + '' + (val || '') + '
'; - } - $(el).w2tag($.extend({ - html : html, - left : -4, - position : 'bottom', - className : 'w2ui-info-bubble', - style : '', - hideOnClick : true - }, info.options || {})); - }, - - getCellValue: function (ind, col_ind, summary) { - var col = this.columns[col_ind]; - var record = (summary !== true ? this.records[ind] : this.summary[ind]); - var data = this.parseField(record, col.field); - if (record && record.w2ui && record.w2ui.changes && record.w2ui.changes[col.field] != null) { - data = record.w2ui.changes[col.field]; - } - if ($.isPlainObject(data) && col.editable && col.editable.type == 'list') { - if (data.text != null) data = data.text; - if (data.id != null) data = data.id; - } - if (data == null) data = ''; - return data; - }, - - getFooterHTML: function () { - return '
'+ - ' '+ - ' '+ - ' '+ - '
'; - }, - - status: function (msg) { - if (msg != null) { - $('#grid_'+ this.name +'_footer').find('.w2ui-footer-left').html(msg); - } else { - // show number of selected - var msgLeft = ''; - var sel = this.getSelection(); - if (sel.length > 0) { - if (this.show.statusSelection && sel.length > 1) { - msgLeft = String(sel.length).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1,") + ' ' + w2utils.lang('selected'); - } - if (this.show.statusRecordID && sel.length == 1) { - var tmp = sel[0]; - if (typeof tmp == 'object') tmp = tmp.recid + ', '+ w2utils.lang('Column') +': '+ tmp.column; - msgLeft = w2utils.lang('Record ID') + ': '+ tmp + ' '; - } - } - $('#grid_'+ this.name +'_footer .w2ui-footer-left').html(msgLeft); - // toolbar - if (sel.length == 1) this.toolbar.enable('w2ui-edit'); else this.toolbar.disable('w2ui-edit'); - if (sel.length >= 1) this.toolbar.enable('w2ui-delete'); else this.toolbar.disable('w2ui-delete'); - } - }, - - lock: function (msg, showSpinner) { - var obj = this; - var args = Array.prototype.slice.call(arguments, 0); - args.unshift(this.box); - setTimeout(function () { - // hide empty msg if any - $(obj.box).find('#grid_'+ obj.name +'_empty_msg').remove(); - w2utils.lock.apply(window, args); - }, 10); - }, - - unlock: function (speed) { - var box = this.box; - setTimeout(function () { - // do not unlock if there is a message - if ($(box).find('.w2ui-message').not('.w2ui-closing').length > 0) return; - w2utils.unlock(box, speed); - }, 25); // needed timer so if server fast, it will not flash - }, - - stateSave: function (returnOnly) { - var obj = this; - if (!localStorage) return null; - var state = { - columns : [], - show : $.extend({}, this.show), - last : { - search : this.last.search, - multi : this.last.multi, - logic : this.last.logic, - caption : this.last.caption, - field : this.last.field, - scrollTop : this.last.scrollTop, - scrollLeft : this.last.scrollLeft - }, - sortData : [], - searchData : [] - }; - for (var i = 0; i < this.columns.length; i++) { - var col = this.columns[i]; - state.columns.push({ - field : col.field, - hidden : col.hidden ? true : false, - frozen : col.frozen ? true : false, - size : col.size ? col.size : null, - sizeCalculated : col.sizeCalculated ? col.sizeCalculated : null, - sizeOriginal : col.sizeOriginal ? col.sizeOriginal : null, - sizeType : col.sizeType ? col.sizeType : null - }); - } - for (var i = 0; i < this.sortData.length; i++) state.sortData.push($.extend({}, this.sortData[i])); - for (var i = 0; i < this.searchData.length; i++) state.searchData.push($.extend({}, this.searchData[i])); - // save into local storage - if (returnOnly !== true) { - // event before - var edata = this.trigger({ phase: 'before', type: 'stateSave', target: this.name, state: state }); - if (edata.isCancelled === true) { if (typeof callBack == 'function') callBack({ status: 'error', message: 'Request aborted.' }); return; } - try { - var savedState = $.parseJSON(localStorage.w2ui || '{}'); - if (!savedState) savedState = {}; - if (!savedState.states) savedState.states = {}; - savedState.states[this.name] = state; - localStorage.w2ui = JSON.stringify(savedState); - } catch (e) { - delete localStorage.w2ui; - return null; - } - // event after - this.trigger($.extend(edata, { phase: 'after' })); - } - return state; - }, - - stateRestore: function (newState) { - var obj = this; - var url = (typeof this.url != 'object' ? this.url : this.url.get); - if (!newState) { - // read it from local storage - try { - if (!localStorage) return false; - var tmp = $.parseJSON(localStorage.w2ui || '{}'); - if (!tmp) tmp = {}; - if (!tmp.states) tmp.states = {}; - newState = tmp.states[this.name]; - } catch (e) { - delete localStorage.w2ui; - return null; - } - } - // event before - var edata = this.trigger({ phase: 'before', type: 'stateRestore', target: this.name, state: newState }); - if (edata.isCancelled === true) { if (typeof callBack == 'function') callBack({ status: 'error', message: 'Request aborted.' }); return; } - // default behavior - if ($.isPlainObject(newState)) { - $.extend(this.show, newState.show); - $.extend(this.last, newState.last); - var sTop = this.last.scrollTop; - var sLeft = this.last.scrollLeft; - for (var c = 0; c < newState.columns.length; c++) { - var tmp = newState.columns[c]; - var col_index = this.getColumn(tmp.field, true); - if (col_index !== null) { - $.extend(this.columns[col_index], tmp); - // restore column order from saved state - if (c !== col_index) this.columns.splice(c, 0, this.columns.splice(col_index, 1)[0]); - } - } - this.sortData.splice(0, this.sortData.length); - for (var c = 0; c < newState.sortData.length; c++) this.sortData.push(newState.sortData[c]); - this.searchData.splice(0, this.searchData.length); - for (var c = 0; c < newState.searchData.length; c++) this.searchData.push(newState.searchData[c]); - // apply sort and search - setTimeout(function () { - // needs timeout as records need to be populated - // ez 10.09.2014 this --> - if (!url) { - if (obj.sortData.length > 0) obj.localSort(); - if (obj.searchData.length > 0) obj.localSearch(); - } - obj.last.scrollTop = sTop; - obj.last.scrollLeft = sLeft; - obj.refresh(); - }, 1); - } - // event after - this.trigger($.extend(edata, { phase: 'after' })); - return true; - }, - - stateReset: function () { - var obj = this; - this.stateRestore(this.last.state); - // remove from local storage - if (localStorage) { - try { - var tmp = $.parseJSON(localStorage.w2ui || '{}'); - if (tmp.states && tmp.states[this.name]) { - delete tmp.states[this.name]; - } - localStorage.w2ui = JSON.stringify(tmp); - } catch (e) { - delete localStorage.w2ui; - return null; - } - } - }, - - parseField: function (obj, field) { - var val = ''; - try { // need this to make sure no error in fields - val = obj; - var tmp = String(field).split('.'); - for (var i = 0; i < tmp.length; i++) { - val = val[tmp[i]]; - } - } catch (event) { - val = ''; - } - return val; - }, - - prepareData: function () { - var obj = this; - - // loops thru records and prepares date and time objects - for (var r = 0; r < this.records.length; r++) { - var rec = this.records[r]; - prepareRecord(rec); - } - - // prepare date and time objects for the 'rec' record and its closed children - function prepareRecord(rec) { - for (var c = 0; c < obj.columns.length; c++) { - var column = obj.columns[c]; - if (rec[column.field] == null || typeof column.render != 'string') continue; - // number - if (['number', 'int', 'float', 'money', 'currency', 'percent'].indexOf(column.render.split(':')[0]) != -1) { - if (typeof rec[column.field] != 'number') rec[column.field] = parseFloat(rec[column.field]); - } - // date - if (['date', 'age'].indexOf(column.render.split(':')[0]) != -1) { - if (!rec[column.field + '_']) { - var dt = rec[column.field]; - if (w2utils.isInt(dt)) dt = parseInt(dt); - rec[column.field + '_'] = new Date(dt); - } - } - // time - if (['time'].indexOf(column.render) != -1) { - if (w2utils.isTime(rec[column.field])) { // if string - var tmp = w2utils.isTime(rec[column.field], true); - var dt = new Date(); - dt.setHours(tmp.hours, tmp.minutes, (tmp.seconds ? tmp.seconds : 0), 0); // sets hours, min, sec, mills - if (!rec[column.field + '_']) rec[column.field + '_'] = dt; - } else { // if date object - var tmp = rec[column.field]; - if (w2utils.isInt(tmp)) tmp = parseInt(tmp); - var tmp = (tmp != null ? new Date(tmp) : new Date()); - var dt = new Date(); - dt.setHours(tmp.getHours(), tmp.getMinutes(), tmp.getSeconds(), 0); // sets hours, min, sec, mills - if (!rec[column.field + '_']) rec[column.field + '_'] = dt; - } - } - } - - if (rec.w2ui && rec.w2ui.children && rec.w2ui.expanded !== true) { - // there are closed children, prepare them too. - for (var r = 0; r < rec.w2ui.children.length; r++) { - var subRec = rec.w2ui.children[r]; - prepareRecord(subRec); - } - } - } - }, - - nextCell: function (index, col_ind, editable) { - var check = col_ind + 1; - if (this.columns.length == check) return null; - var tmp = this.records[index].w2ui; - var ccol = this.columns[col_ind]; - // if (tmp && tmp.colspan[ccol.field]) check += parseInt(tmp.colspan[ccol.field]) -1; // colspan of a column - var col = this.columns[check]; - var span = (tmp && tmp.colspan && !isNaN(tmp.colspan[col.field]) ? parseInt(tmp.colspan[col.field]) : 1); - var edit = col ? col.editable : null; - if (col == null) return null; - if (col && col.hidden || span === 0 - || (editable == true && (edit == null || ['checkbox', 'check'].indexOf(edit.type) != -1))) { - return this.nextCell(index, check, editable); - } - return check; - }, - - prevCell: function (index, col_ind, editable) { - var check = col_ind - 1; - if (check < 0) return null; - var tmp = this.records[index].w2ui; - var col = this.columns[check]; - var span = (tmp && tmp.colspan && !isNaN(tmp.colspan[col.field]) ? parseInt(tmp.colspan[col.field]) : 1); - var edit = col ? col.editable : null; - if (col == null) return null; - if (col && col.hidden || span === 0 - || (editable == true && (edit == null || ['checkbox', 'check'].indexOf(edit.type) != -1))) { - return this.prevCell(index, check, editable); - } - return check; - }, - - nextRow: function (ind, col_ind) { - var sids = this.last.searchIds; - var ret = null; - if ((ind + 1 < this.records.length && sids.length == 0) // if there are more records - || (sids.length > 0 && ind < sids[sids.length-1])) { - ind++; - if (sids.length > 0) while (true) { - if ($.inArray(ind, sids) != -1 || ind > this.records.length) break; - ind++; - } - // colspan - var tmp = this.records[ind].w2ui; - var col = this.columns[col_ind]; - var span = (tmp && tmp.colspan && col != null && !isNaN(tmp.colspan[col.field]) ? parseInt(tmp.colspan[col.field]) : 1); - if (span == 0) { - ret = this.nextRow(ind, col_ind); - } else { - ret = ind; - } - } - return ret; - }, - - prevRow: function (ind, col_ind) { - var sids = this.last.searchIds; - var ret = null; - if ((ind > 0 && sids.length == 0) // if there are more records - || (sids.length > 0 && ind > sids[0])) { - ind--; - if (sids.length > 0) while (true) { - if ($.inArray(ind, sids) != -1 || ind < 0) break; - ind--; - } - // colspan - var tmp = this.records[ind].w2ui; - var col = this.columns[col_ind]; - var span = (tmp && tmp.colspan && col != null && !isNaN(tmp.colspan[col.field]) ? parseInt(tmp.colspan[col.field]) : 1); - if (span == 0) { - ret = this.prevRow(ind, col_ind); - } else { - ret = ind; - } - } - return ret; - }, - - selectionSave: function () { - this.last._selection = this.getSelection(); - return this.last._selection; - }, - - selectionRestore: function (noRefresh) { - var time = (new Date()).getTime(); - this.last.selection = { indexes: [], columns: {} }; - var sel = this.last.selection; - var lst = this.last._selection; - for (var i = 0; i < lst.length; i++) { - if ($.isPlainObject(lst[i])) { - // selectType: cell - var tmp = this.get(lst[i].recid, true); - if (tmp != null) { - if (sel.indexes.indexOf(tmp) == -1) sel.indexes.push(tmp); - if (!sel.columns[tmp]) sel.columns[tmp] = []; - sel.columns[tmp].push(lst[i].column); - } - } else { - // selectType: row - var tmp = this.get(lst[i], true); - if (tmp != null) sel.indexes.push(tmp); - } - } - delete this.last._selection; - if (noRefresh !== true) this.refresh(); - return (new Date()).getTime() - time; - }, - - message: function(options, callBack) { - if (typeof options == 'string') { - options = { - width : (options.length < 300 ? 350 : 550), - height : (options.length < 300 ? 170: 250), - body : '
' + options + '
', - buttons : '', - onOpen : function (event) { - setTimeout(function () { - $(this.box).find('.w2ui-btn').focus(); - }, 25); - }, - onClose: function (even) { - if (typeof callBack == 'function') callBack(); - } - }; - } - w2utils.message.call(this, { - box : this.box, - path : 'w2ui.' + this.name, - title : '.w2ui-grid-header:visible', - body : '.w2ui-grid-box' - }, options); - } - }; - - $.extend(w2grid.prototype, w2utils.event); - w2obj.grid = w2grid; -})(jQuery); - -/************************************************************************ -* Library: Web 2.0 UI for jQuery (using prototypical inheritance) -* - Following objects defined -* - w2layout - layout widget -* - $().w2layout - jQuery wrapper -* - Dependencies: jQuery, w2utils, w2toolbar, w2tabs -* -* == NICE TO HAVE == -* - onResize for the panel -* - add more panel title positions (left=rotated, right=rotated, bottom) -* - bug: when you assign content before previous transition completed. -* 1.5 changes -* - message method -* -************************************************************************/ - -(function ($) { - var w2layout = function (options) { - this.box = null; // DOM Element that holds the element - this.name = null; // unique name for w2ui - this.panels = []; - this.tmp = {}; - this.padding = 1; // panel padding - this.resizer = 4; // resizer width or height - this.style = ''; - - $.extend(true, this, w2obj.layout, options); - }; - - var w2panels = ['top', 'left', 'main', 'preview', 'right', 'bottom']; - - // ==================================================== - // -- Registers as a jQuery plugin - - $.fn.w2layout = function(method) { - if ($.isPlainObject(method)) { - // check name parameter - if (!w2utils.checkName(method, 'w2layout')) return; - var panels = method.panels || []; - var object = new w2layout(method); - $.extend(object, { handlers: [], panels: [] }); - // add defined panels - for (var p = 0, len = panels.length; p < len; p++) { - object.panels[p] = $.extend(true, {}, w2layout.prototype.panel, panels[p]); - if ($.isPlainObject(object.panels[p].tabs) || $.isArray(object.panels[p].tabs)) initTabs(object, panels[p].type); - if ($.isPlainObject(object.panels[p].toolbar) || $.isArray(object.panels[p].toolbar)) initToolbar(object, panels[p].type); - } - // add all other panels - for (var p1 = 0; p1 < w2panels.length; p1++) { - if (object.get(w2panels[p1]) != null) continue; - object.panels.push($.extend(true, {}, w2layout.prototype.panel, { type: w2panels[p1], hidden: (w2panels[p1] !== 'main'), size: 50 })); - } - if ($(this).length > 0) { - object.render($(this)[0]); - } - w2ui[object.name] = object; - return object; - - } else { - var obj = w2ui[$(this).attr('name')]; - if (!obj) return null; - if (arguments.length > 0) { - if (obj[method]) obj[method].apply(obj, Array.prototype.slice.call(arguments, 1)); - return this; - } else { - return obj; - } - } - - function initTabs(object, panel, tabs) { - var pan = object.get(panel); - if (pan != null && tabs == null) tabs = pan.tabs; - if (pan == null || tabs == null) return false; - // instanciate tabs - if ($.isArray(tabs)) tabs = { tabs: tabs }; - $().w2destroy(object.name + '_' + panel + '_tabs'); // destroy if existed - pan.tabs = $().w2tabs($.extend({}, tabs, { owner: object, name: object.name + '_' + panel + '_tabs' })); - pan.show.tabs = true; - return true; - } - - function initToolbar(object, panel, toolbar) { - var pan = object.get(panel); - if (pan != null && toolbar == null) toolbar = pan.toolbar; - if (pan == null || toolbar == null) return false; - // instanciate toolbar - if ($.isArray(toolbar)) toolbar = { items: toolbar }; - $().w2destroy(object.name + '_' + panel + '_toolbar'); // destroy if existed - pan.toolbar = $().w2toolbar($.extend({}, toolbar, { owner: object, name: object.name + '_' + panel + '_toolbar' })); - pan.show.toolbar = true; - return true; - } - }; - - // ==================================================== - // -- Implementation of core functionality - - w2layout.prototype = { - onShow : null, - onHide : null, - onResizing : null, - onResizerClick: null, - onRender : null, - onRefresh : null, - onContent : null, - onResize : null, - onDestroy : null, - - // default setting for a panel - panel: { - type : null, // left, right, top, bottom - title : '', - size : 100, // width or height depending on panel name - minSize : 20, - maxSize : false, - hidden : false, - resizable : false, - overflow : 'auto', - style : '', - content : '', // can be String or Object with .render(box) method - tabs : null, - toolbar : null, - width : null, // read only - height : null, // read only - show : { - toolbar : false, - tabs : false - }, - onRefresh : null, - onShow : null, - onHide : null - }, - - // alias for content - html: function (panel, data, transition) { - return this.content(panel, data, transition); - }, - - content: function (panel, data, transition) { - var obj = this; - var p = this.get(panel); - // if it is CSS panel - if (panel == 'css') { - $('#layout_'+ obj.name +'_panel_css').html(''); - return true; - } - if (p == null) return false; - if (data == null) { - return p.content; - } else { - // event before - var edata = this.trigger({ phase: 'before', type: 'content', target: panel, object: p, content: data, transition: transition }); - if (edata.isCancelled === true) return; - - if (data instanceof jQuery) { - console.log('ERROR: You can not pass jQuery object to w2layout.content() method'); - return false; - } - var pname = '#layout_'+ this.name + '_panel_'+ p.type; - var current = $(pname + '> .w2ui-panel-content'); - var panelTop = 0; - if (current.length > 0) { - $(pname).scrollTop(0); - panelTop = $(current).position().top; - } - if (p.content === '') { - p.content = data; - this.refresh(panel); - } else { - p.content = data; - if (!p.hidden) { - if (transition != null && transition !== '') { - // apply transition - var div1 = $(pname + '> .w2ui-panel-content'); - div1.after('
'); - var div2 = $(pname + '> .w2ui-panel-content.new-panel'); - div1.css('top', panelTop); - div2.css('top', panelTop); - if (typeof data == 'object') { - data.box = div2[0]; // do not do .render(box); - data.render(); - } else { - div2.html(data); - } - w2utils.transition(div1[0], div2[0], transition, function () { - div1.remove(); - div2.removeClass('new-panel'); - div2.css('overflow', p.overflow); - // IE Hack - obj.resize(); - if (window.navigator.userAgent.indexOf('MSIE') != -1) setTimeout(function () { obj.resize(); }, 100); - }); - } - } - this.refresh(panel); - } - } - // event after - obj.trigger($.extend(edata, { phase: 'after' })); - // IE Hack - obj.resize(); - if (window.navigator.userAgent.indexOf('MSIE') != -1) setTimeout(function () { obj.resize(); }, 100); - return true; - }, - - message: function(panel, options) { - var obj = this; - if (typeof options == 'string') { - options = { - width : (options.length < 300 ? 350 : 550), - height : (options.length < 300 ? 170: 250), - body : '
' + options + '
', - buttons : '', - onOpen : function (event) { - setTimeout(function () { - $(this.box).find('.w2ui-btn').focus(); - }, 25); - } - }; - } - var p = this.get(panel); - var $el = $('#layout_'+ this.name + '_panel_'+ p.type); - var oldOverflow = $el.css('overflow'); - var oldOnClose; - if (options) { - if (options.onClose) oldOnClose = options.onClose; - options.onClose = function (event) { - if (typeof oldOnClose == 'function') oldOnClose(event); - event.done(function () { - $('#layout_'+ obj.name + '_panel_'+ p.type).css('overflow', oldOverflow); - }); - } - } - $('#layout_'+ this.name + '_panel_'+ p.type).css('overflow', 'hidden'); - w2utils.message.call(this, { - box : $('#layout_'+ this.name + '_panel_'+ p.type), - param : panel, - path : 'w2ui.' + this.name, - title : '.w2ui-panel-title:visible', - body : '.w2ui-panel-content' - }, options); - }, - - load: function (panel, url, transition, onLoad) { - var obj = this; - if (panel == 'css') { - $.get(url, function (data, status, xhr) { // should always be $.get as it is template - obj.content(panel, xhr.responseText); - if (onLoad) onLoad(); - }); - return true; - } - if (this.get(panel) != null) { - $.get(url, function (data, status, xhr) { // should always be $.get as it is template - obj.content(panel, xhr.responseText, transition); - if (onLoad) onLoad(); - // IE Hack - obj.resize(); - if (window.navigator.userAgent.indexOf('MSIE') != -1) setTimeout(function () { obj.resize(); }, 100); - }); - return true; - } - return false; - }, - - sizeTo: function (panel, size, instant) { - var obj = this; - var pan = obj.get(panel); - if (pan == null) return false; - // resize - $(obj.box).find(' > div > .w2ui-panel') - .css(w2utils.cssPrefix('transition', (instant !== true ? '.2s' : '0s'))); - setTimeout(function () { - obj.set(panel, { size: size }); - }, 1); - // clean - setTimeout(function () { - $(obj.box).find(' > div > .w2ui-panel').css(w2utils.cssPrefix('transition', '0s')); - obj.resize(); - }, 500); - return true; - }, - - show: function (panel, immediate) { - var obj = this; - // event before - var edata = this.trigger({ phase: 'before', type: 'show', target: panel, object: this.get(panel), immediate: immediate }); - if (edata.isCancelled === true) return; - - var p = obj.get(panel); - if (p == null) return false; - p.hidden = false; - if (immediate === true) { - $('#layout_'+ obj.name +'_panel_'+panel).css({ 'opacity': '1' }); - obj.trigger($.extend(edata, { phase: 'after' })); - obj.resize(); - } else { - // resize - $('#layout_'+ obj.name +'_panel_'+panel).css({ 'opacity': '0' }); - $(obj.box).find(' > div > .w2ui-panel').css(w2utils.cssPrefix('transition', '.2s')); - setTimeout(function () { obj.resize(); }, 1); - // show - setTimeout(function() { - $('#layout_'+ obj.name +'_panel_'+ panel).css({ 'opacity': '1' }); - }, 250); - // clean - setTimeout(function () { - $(obj.box).find(' > div > .w2ui-panel').css(w2utils.cssPrefix('transition', '0s')); - obj.trigger($.extend(edata, { phase: 'after' })); - obj.resize(); - }, 500); - } - return true; - }, - - hide: function (panel, immediate) { - var obj = this; - // event before - var edata = this.trigger({ phase: 'before', type: 'hide', target: panel, object: this.get(panel), immediate: immediate }); - if (edata.isCancelled === true) return; - - var p = obj.get(panel); - if (p == null) return false; - p.hidden = true; - if (immediate === true) { - $('#layout_'+ obj.name +'_panel_'+panel).css({ 'opacity': '0' }); - obj.trigger($.extend(edata, { phase: 'after' })); - obj.resize(); - } else { - // hide - $(obj.box).find(' > div > .w2ui-panel').css(w2utils.cssPrefix('transition', '.2s')); - $('#layout_'+ obj.name +'_panel_'+panel).css({ 'opacity': '0' }); - setTimeout(function () { obj.resize(); }, 1); - // clean - setTimeout(function () { - $(obj.box).find(' > div > .w2ui-panel').css(w2utils.cssPrefix('transition', '0s')); - obj.trigger($.extend(edata, { phase: 'after' })); - obj.resize(); - }, 500); - } - return true; - }, - - toggle: function (panel, immediate) { - var p = this.get(panel); - if (p == null) return false; - if (p.hidden) return this.show(panel, immediate); else return this.hide(panel, immediate); - }, - - set: function (panel, options) { - var ind = this.get(panel, true); - if (ind == null) return false; - $.extend(this.panels[ind], options); - // refresh only when content changed - if (options['content'] != null || options['resizable'] != null) { - this.refresh(panel); - } - // show/hide resizer - this.resize(); // resize is needed when panel size is changed - return true; - }, - - get: function (panel, returnIndex) { - for (var p = 0; p < this.panels.length; p++) { - if (this.panels[p].type == panel) { - if (returnIndex === true) return p; else return this.panels[p]; - } - } - return null; - }, - - el: function (panel) { - var el = $('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-content'); - if (el.length != 1) return null; - return el[0]; - }, - - hideToolbar: function (panel) { - var pan = this.get(panel); - if (!pan) return; - pan.show.toolbar = false; - $('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-toolbar').hide(); - this.resize(); - }, - - showToolbar: function (panel) { - var pan = this.get(panel); - if (!pan) return; - pan.show.toolbar = true; - $('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-toolbar').show(); - this.resize(); - }, - - toggleToolbar: function (panel) { - var pan = this.get(panel); - if (!pan) return; - if (pan.show.toolbar) this.hideToolbar(panel); else this.showToolbar(panel); - }, - - assignToolbar: function (panel, toolbar) { - if (typeof toolbar == 'string' && w2ui[toolbar] != null) toolbar = w2ui[toolbar]; - var pan = this.get(panel); - pan.toolbar = toolbar; - var tmp = $(this.box).find(panel +'> .w2ui-panel-toolbar'); - if (pan.toolbar != null) { - if (tmp.find('[name='+ pan.toolbar.name +']').length === 0) { - tmp.w2render(pan.toolbar); - } else if (pan.toolbar != null) { - pan.toolbar.refresh(); - } - this.showToolbar(panel); - this.refresh('main'); - } else { - tmp.html(''); - this.hideToolbar(panel); - } - }, - - hideTabs: function (panel) { - var pan = this.get(panel); - if (!pan) return; - pan.show.tabs = false; - $('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-tabs').hide(); - this.resize(); - }, - - showTabs: function (panel) { - var pan = this.get(panel); - if (!pan) return; - pan.show.tabs = true; - $('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-tabs').show(); - this.resize(); - }, - - toggleTabs: function (panel) { - var pan = this.get(panel); - if (!pan) return; - if (pan.show.tabs) this.hideTabs(panel); else this.showTabs(panel); - }, - - render: function (box) { - var obj = this; - // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection - var time = (new Date()).getTime(); - // event before - var edata = obj.trigger({ phase: 'before', type: 'render', target: obj.name, box: box }); - if (edata.isCancelled === true) return; - - if (box != null) { - if ($(obj.box).find('#layout_'+ obj.name +'_panel_main').length > 0) { - $(obj.box) - .removeAttr('name') - .removeClass('w2ui-layout') - .html(''); - } - obj.box = box; - } - if (!obj.box) return false; - $(obj.box) - .attr('name', obj.name) - .addClass('w2ui-layout') - .html('
'); - if ($(obj.box).length > 0) $(obj.box)[0].style.cssText += obj.style; - // create all panels - for (var p1 = 0; p1 < w2panels.length; p1++) { - var pan = obj.get(w2panels[p1]); - var html = '
'+ - '
'+ - '
'+ - '
'+ - '
'+ - '
'+ - '
'; - $(obj.box).find(' > div').append(html); - // tabs are rendered in refresh() - } - $(obj.box).find(' > div') - .append('
'); - obj.refresh(); // if refresh is not called here, the layout will not be available right after initialization - // process event - obj.trigger($.extend(edata, { phase: 'after' })); - // reinit events - setTimeout(function () { // needed this timeout to allow browser to render first if there are tabs or toolbar - initEvents(); - obj.resize(); - }, 0); - return (new Date()).getTime() - time; - - function initEvents() { - obj.tmp.events = { - resize : function (event) { - w2ui[obj.name].resize(); - }, - resizeStart : resizeStart, - mouseMove : resizeMove, - mouseUp : resizeStop - }; - $(window).on('resize', obj.tmp.events.resize); - } - - function resizeStart(type, evnt) { - if (!obj.box) return; - if (!evnt) evnt = window.event; - $(document).off('mousemove', obj.tmp.events.mouseMove).on('mousemove', obj.tmp.events.mouseMove); - $(document).off('mouseup', obj.tmp.events.mouseUp).on('mouseup', obj.tmp.events.mouseUp); - obj.tmp.resize = { - type : type, - x : evnt.screenX, - y : evnt.screenY, - diff_x : 0, - diff_y : 0, - value : 0 - }; - // lock all panels - for (var p1 = 0; p1 < w2panels.length; p1++) { - var $tmp = $(obj.el(w2panels[p1])).parent().find('.w2ui-lock'); - if ($tmp.length > 0) { - $tmp.attr('locked', 'previous'); - } else { - obj.lock(w2panels[p1], { opacity: 0 }); - } - } - if (type == 'left' || type == 'right') { - obj.tmp.resize.value = parseInt($('#layout_'+ obj.name +'_resizer_'+ type)[0].style.left); - } - if (type == 'top' || type == 'preview' || type == 'bottom') { - obj.tmp.resize.value = parseInt($('#layout_'+ obj.name +'_resizer_'+ type)[0].style.top); - } - } - - function resizeStop(evnt) { - if (!obj.box) return; - if (!evnt) evnt = window.event; - $(document).off('mousemove', obj.tmp.events.mouseMove); - $(document).off('mouseup', obj.tmp.events.mouseUp); - if (obj.tmp.resize == null) return; - // unlock all panels - for (var p1 = 0; p1 < w2panels.length; p1++) { - var $tmp = $(obj.el(w2panels[p1])).parent().find('.w2ui-lock'); - if ($tmp.attr('locked') == 'previous') { - $tmp.removeAttr('locked'); - } else { - obj.unlock(w2panels[p1]); - } - } - // set new size - if (obj.tmp.diff_x !== 0 || obj.tmp.resize.diff_y !== 0) { // only recalculate if changed - var ptop = obj.get('top'); - var pbottom = obj.get('bottom'); - var panel = obj.get(obj.tmp.resize.type); - var height = parseInt($(obj.box).height()); - var width = parseInt($(obj.box).width()); - var str = String(panel.size); - var ns, nd; - switch (obj.tmp.resize.type) { - case 'top': - ns = parseInt(panel.sizeCalculated) + obj.tmp.resize.diff_y; - nd = 0; - break; - case 'bottom': - ns = parseInt(panel.sizeCalculated) - obj.tmp.resize.diff_y; - nd = 0; - break; - case 'preview': - ns = parseInt(panel.sizeCalculated) - obj.tmp.resize.diff_y; - nd = (ptop && !ptop.hidden ? ptop.sizeCalculated : 0) + - (pbottom && !pbottom.hidden ? pbottom.sizeCalculated : 0); - break; - case 'left': - ns = parseInt(panel.sizeCalculated) + obj.tmp.resize.diff_x; - nd = 0; - break; - case 'right': - ns = parseInt(panel.sizeCalculated) - obj.tmp.resize.diff_x; - nd = 0; - break; - } - // set size - if (str.substr(str.length-1) == '%') { - panel.size = Math.floor(ns * 100 / (panel.type == 'left' || panel.type == 'right' ? width : height - nd) * 100) / 100 + '%'; - } else { - if (String(panel.size).substr(0, 1) == '-') { - panel.size = parseInt(panel.size) - panel.sizeCalculated + ns; - } else { - panel.size = ns; - } - } - obj.resize(); - } - $('#layout_'+ obj.name + '_resizer_'+ obj.tmp.resize.type).removeClass('active'); - delete obj.tmp.resize; - } - - function resizeMove(evnt) { - if (!obj.box) return; - if (!evnt) evnt = window.event; - if (obj.tmp.resize == null) return; - var panel = obj.get(obj.tmp.resize.type); - // event before - var tmp = obj.tmp.resize; - var edata = obj.trigger({ phase: 'before', type: 'resizing', target: obj.name, object: panel, originalEvent: evnt, - panel: tmp ? tmp.type : 'all', diff_x: tmp ? tmp.diff_x : 0, diff_y: tmp ? tmp.diff_y : 0 }); - if (edata.isCancelled === true) return; - - var p = $('#layout_'+ obj.name + '_resizer_'+ tmp.type); - var resize_x = (evnt.screenX - tmp.x); - var resize_y = (evnt.screenY - tmp.y); - var mainPanel = obj.get('main'); - - if (!p.hasClass('active')) p.addClass('active'); - - switch (tmp.type) { - case 'left': - if (panel.minSize - resize_x > panel.width) { - resize_x = panel.minSize - panel.width; - } - if (panel.maxSize && (panel.width + resize_x > panel.maxSize)) { - resize_x = panel.maxSize - panel.width; - } - if (mainPanel.minSize + resize_x > mainPanel.width) { - resize_x = mainPanel.width - mainPanel.minSize; - } - break; - - case 'right': - if (panel.minSize + resize_x > panel.width) { - resize_x = panel.width - panel.minSize; - } - if (panel.maxSize && (panel.width - resize_x > panel.maxSize)) { - resize_x = panel.width - panel.maxSize; - } - if (mainPanel.minSize - resize_x > mainPanel.width) { - resize_x = mainPanel.minSize - mainPanel.width; - } - break; - - case 'top': - if (panel.minSize - resize_y > panel.height) { - resize_y = panel.minSize - panel.height; - } - if (panel.maxSize && (panel.height + resize_y > panel.maxSize)) { - resize_y = panel.maxSize - panel.height; - } - if (mainPanel.minSize + resize_y > mainPanel.height) { - resize_y = mainPanel.height - mainPanel.minSize; - } - break; - - case 'preview': - case 'bottom': - if (panel.minSize + resize_y > panel.height) { - resize_y = panel.height - panel.minSize; - } - if (panel.maxSize && (panel.height - resize_y > panel.maxSize)) { - resize_y = panel.height - panel.maxSize; - } - if (mainPanel.minSize - resize_y > mainPanel.height) { - resize_y = mainPanel.minSize - mainPanel.height; - } - break; - } - tmp.diff_x = resize_x; - tmp.diff_y = resize_y; - - switch (tmp.type) { - case 'top': - case 'preview': - case 'bottom': - tmp.diff_x = 0; - if (p.length > 0) p[0].style.top = (tmp.value + tmp.diff_y) + 'px'; - break; - - case 'left': - case 'right': - tmp.diff_y = 0; - if (p.length > 0) p[0].style.left = (tmp.value + tmp.diff_x) + 'px'; - break; - } - // event after - obj.trigger($.extend(edata, { phase: 'after' })); - } - }, - - refresh: function (panel) { - var obj = this; - // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection - if (panel == null) panel = null; - var time = (new Date()).getTime(); - // event before - var edata = obj.trigger({ phase: 'before', type: 'refresh', target: (panel != null ? panel : obj.name), object: obj.get(panel) }); - if (edata.isCancelled === true) return; - // obj.unlock(panel); - if (typeof panel == 'string') { - var p = obj.get(panel); - if (p == null) return; - var pname = '#layout_'+ obj.name + '_panel_'+ p.type; - var rname = '#layout_'+ obj.name +'_resizer_'+ p.type; - // apply properties to the panel - $(pname).css({ display: p.hidden ? 'none' : 'block' }); - if (p.resizable) $(rname).show(); else $(rname).hide(); - // insert content - if (typeof p.content == 'object' && typeof p.content.render === 'function') { - p.content.box = $(pname +'> .w2ui-panel-content')[0]; - setTimeout(function () { - // need to remove unnecessary classes - if ($(pname +'> .w2ui-panel-content').length > 0) { - $(pname +'> .w2ui-panel-content') - .removeClass() - .removeAttr('name') - .addClass('w2ui-panel-content') - .css('overflow', p.overflow)[0].style.cssText += ';' + p.style; - } - if (p.content && typeof p.content.render == 'function') { - p.content.render(); // do not do .render(box); - } - }, 1); - } else { - // need to remove unnecessary classes - if ($(pname +'> .w2ui-panel-content').length > 0) { - $(pname +'> .w2ui-panel-content') - .removeClass() - .removeAttr('name') - .addClass('w2ui-panel-content') - .html(p.content) - .css('overflow', p.overflow)[0].style.cssText += ';' + p.style; - } - } - // if there are tabs and/or toolbar - render it - var tmp = $(obj.box).find(pname +'> .w2ui-panel-tabs'); - if (p.show.tabs) { - if (tmp.find('[name='+ p.tabs.name +']').length === 0 && p.tabs != null) tmp.w2render(p.tabs); else p.tabs.refresh(); - } else { - tmp.html('').removeClass('w2ui-tabs').hide(); - } - tmp = $(obj.box).find(pname +'> .w2ui-panel-toolbar'); - if (p.show.toolbar) { - if (tmp.find('[name='+ p.toolbar.name +']').length === 0 && p.toolbar != null) tmp.w2render(p.toolbar); else p.toolbar.refresh(); - } else { - tmp.html('').removeClass('w2ui-toolbar').hide(); - } - // show title - tmp = $(obj.box).find(pname +'> .w2ui-panel-title'); - if (p.title) { - tmp.html(p.title).show(); - } else { - tmp.html('').hide(); - } - } else { - if ($('#layout_'+ obj.name +'_panel_main').length == 0) { - obj.render(); - return; - } - obj.resize(); - // refresh all of them - for (var p1 = 0; p1 < this.panels.length; p1++) { obj.refresh(this.panels[p1].type); } - } - obj.trigger($.extend(edata, { phase: 'after' })); - return (new Date()).getTime() - time; - }, - - resize: function () { - // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection - if (!this.box) return false; - var time = (new Date()).getTime(); - // event before - var tmp = this.tmp.resize; - var edata = this.trigger({ phase: 'before', type: 'resize', target: this.name, - panel: tmp ? tmp.type : 'all', diff_x: tmp ? tmp.diff_x : 0, diff_y: tmp ? tmp.diff_y : 0 }); - if (edata.isCancelled === true) return; - if (this.padding < 0) this.padding = 0; - - // layout itself - var width = parseInt($(this.box).width()); - var height = parseInt($(this.box).height()); - $(this.box).find(' > div').css({ - width : width + 'px', - height : height + 'px' - }); - var obj = this; - // panels - var pmain = this.get('main'); - var pprev = this.get('preview'); - var pleft = this.get('left'); - var pright = this.get('right'); - var ptop = this.get('top'); - var pbottom = this.get('bottom'); - var smain = true; // main always on - var sprev = (pprev != null && pprev.hidden !== true ? true : false); - var sleft = (pleft != null && pleft.hidden !== true ? true : false); - var sright = (pright != null && pright.hidden !== true ? true : false); - var stop = (ptop != null && ptop.hidden !== true ? true : false); - var sbottom = (pbottom != null && pbottom.hidden !== true ? true : false); - var l, t, w, h, e; - // calculate % - for (var p = 0; p < w2panels.length; p++) { - if (w2panels[p] === 'main') continue; - var tmp = this.get(w2panels[p]); - if (!tmp) continue; - var str = String(tmp.size || 0); - if (str.substr(str.length-1) == '%') { - var tmph = height; - if (tmp.type == 'preview') { - tmph = tmph - - (ptop && !ptop.hidden ? ptop.sizeCalculated : 0) - - (pbottom && !pbottom.hidden ? pbottom.sizeCalculated : 0); - } - tmp.sizeCalculated = parseInt((tmp.type == 'left' || tmp.type == 'right' ? width : tmph) * parseFloat(tmp.size) / 100); - } else { - tmp.sizeCalculated = parseInt(tmp.size); - } - tmp.sizeCalculated = Math.max(tmp.sizeCalculated, parseInt(tmp.minSize)); - } - // negative size - if (String(pright.size).substr(0, 1) == '-') { - if (sleft && pleft.size.substr(0, 1) == '-') { - console.log('ERROR: you cannot have both left panel.size and right panel.size be negative.'); - } else { - pright.sizeCalculated = width - (sleft ? pleft.sizeCalculated : 0) + parseInt(pright.size); - } - } - if (String(pleft.size).substr(0, 1) == '-') { - if (sright && pright.size.substr(0, 1) == '-') { - console.log('ERROR: you cannot have both left panel.size and right panel.size be negative.'); - } else { - pleft.sizeCalculated = width - (sright ? pright.sizeCalculated : 0) + parseInt(pleft.size); - } - } - // top if any - if (ptop != null && ptop.hidden !== true) { - l = 0; - t = 0; - w = width; - h = ptop.sizeCalculated; - $('#layout_'+ this.name +'_panel_top').css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px' - }).show(); - ptop.width = w; - ptop.height = h; - // resizer - if (ptop.resizable) { - t = ptop.sizeCalculated - (this.padding === 0 ? this.resizer : 0); - h = (this.resizer > this.padding ? this.resizer : this.padding); - $('#layout_'+ this.name +'_resizer_top').show().css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px', - 'cursor': 'ns-resize' - }).off('mousedown').on('mousedown', function (event) { - // event before - var edata = obj.trigger({ phase: 'before', type: 'resizerClick', target: 'top', originalEvent: event }); - if (edata.isCancelled === true) return; - // default action - w2ui[obj.name].tmp.events.resizeStart('top', event); - // event after - obj.trigger($.extend(edata, { phase: 'after' })); - return false; - }); - } - } else { - $('#layout_'+ this.name +'_panel_top').hide(); - $('#layout_'+ this.name +'_resizer_top').hide(); - } - // left if any - if (pleft != null && pleft.hidden !== true) { - l = 0; - t = 0 + (stop ? ptop.sizeCalculated + this.padding : 0); - w = pleft.sizeCalculated; - h = height - (stop ? ptop.sizeCalculated + this.padding : 0) - - (sbottom ? pbottom.sizeCalculated + this.padding : 0); - e = $('#layout_'+ this.name +'_panel_left'); - if (window.navigator.userAgent.indexOf('MSIE') != -1 && e.length > 0 && e[0].clientHeight < e[0].scrollHeight) w += 17; // IE hack - e.css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px' - }).show(); - pleft.width = w; - pleft.height = h; - // resizer - if (pleft.resizable) { - l = pleft.sizeCalculated - (this.padding === 0 ? this.resizer : 0); - w = (this.resizer > this.padding ? this.resizer : this.padding); - $('#layout_'+ this.name +'_resizer_left').show().css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px', - 'cursor': 'ew-resize' - }).off('mousedown').on('mousedown', function (event) { - // event before - var edata = obj.trigger({ phase: 'before', type: 'resizerClick', target: 'left', originalEvent: event }); - if (edata.isCancelled === true) return; - // default action - w2ui[obj.name].tmp.events.resizeStart('left', event); - // event after - obj.trigger($.extend(edata, { phase: 'after' })); - return false; - }); - } - } else { - $('#layout_'+ this.name +'_panel_left').hide(); - $('#layout_'+ this.name +'_resizer_left').hide(); - } - // right if any - if (pright != null && pright.hidden !== true) { - l = width - pright.sizeCalculated; - t = 0 + (stop ? ptop.sizeCalculated + this.padding : 0); - w = pright.sizeCalculated; - h = height - (stop ? ptop.sizeCalculated + this.padding : 0) - - (sbottom ? pbottom.sizeCalculated + this.padding : 0); - $('#layout_'+ this.name +'_panel_right').css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px' - }).show(); - pright.width = w; - pright.height = h; - // resizer - if (pright.resizable) { - l = l - this.padding; - w = (this.resizer > this.padding ? this.resizer : this.padding); - $('#layout_'+ this.name +'_resizer_right').show().css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px', - 'cursor': 'ew-resize' - }).off('mousedown').on('mousedown', function (event) { - // event before - var edata = obj.trigger({ phase: 'before', type: 'resizerClick', target: 'right', originalEvent: event }); - if (edata.isCancelled === true) return; - // default action - w2ui[obj.name].tmp.events.resizeStart('right', event); - // event after - obj.trigger($.extend(edata, { phase: 'after' })); - return false; - }); - } - } else { - $('#layout_'+ this.name +'_panel_right').hide(); - $('#layout_'+ this.name +'_resizer_right').hide(); - } - // bottom if any - if (pbottom != null && pbottom.hidden !== true) { - l = 0; - t = height - pbottom.sizeCalculated; - w = width; - h = pbottom.sizeCalculated; - $('#layout_'+ this.name +'_panel_bottom').css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px' - }).show(); - pbottom.width = w; - pbottom.height = h; - // resizer - if (pbottom.resizable) { - t = t - (this.padding === 0 ? 0 : this.padding); - h = (this.resizer > this.padding ? this.resizer : this.padding); - $('#layout_'+ this.name +'_resizer_bottom').show().css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px', - 'cursor': 'ns-resize' - }).off('mousedown').on('mousedown', function (event) { - // event before - var edata = obj.trigger({ phase: 'before', type: 'resizerClick', target: 'bottom', originalEvent: event }); - if (edata.isCancelled === true) return; - // default action - w2ui[obj.name].tmp.events.resizeStart('bottom', event); - // event after - obj.trigger($.extend(edata, { phase: 'after' })); - return false; - }); - } - } else { - $('#layout_'+ this.name +'_panel_bottom').hide(); - $('#layout_'+ this.name +'_resizer_bottom').hide(); - } - // main - always there - l = 0 + (sleft ? pleft.sizeCalculated + this.padding : 0); - t = 0 + (stop ? ptop.sizeCalculated + this.padding : 0); - w = width - (sleft ? pleft.sizeCalculated + this.padding : 0) - - (sright ? pright.sizeCalculated + this.padding: 0); - h = height - (stop ? ptop.sizeCalculated + this.padding : 0) - - (sbottom ? pbottom.sizeCalculated + this.padding : 0) - - (sprev ? pprev.sizeCalculated + this.padding : 0); - e = $('#layout_'+ this.name +'_panel_main'); - if (window.navigator.userAgent.indexOf('MSIE') != -1 && e.length > 0 && e[0].clientHeight < e[0].scrollHeight) w += 17; // IE hack - e.css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px' - }); - pmain.width = w; - pmain.height = h; - - // preview if any - if (pprev != null && pprev.hidden !== true) { - l = 0 + (sleft ? pleft.sizeCalculated + this.padding : 0); - t = height - (sbottom ? pbottom.sizeCalculated + this.padding : 0) - pprev.sizeCalculated; - w = width - (sleft ? pleft.sizeCalculated + this.padding : 0) - - (sright ? pright.sizeCalculated + this.padding : 0); - h = pprev.sizeCalculated; - e = $('#layout_'+ this.name +'_panel_preview'); - if (window.navigator.userAgent.indexOf('MSIE') != -1 && e.length > 0 && e[0].clientHeight < e[0].scrollHeight) w += 17; // IE hack - e.css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px' - }).show(); - pprev.width = w; - pprev.height = h; - // resizer - if (pprev.resizable) { - t = t - (this.padding === 0 ? 0 : this.padding); - h = (this.resizer > this.padding ? this.resizer : this.padding); - $('#layout_'+ this.name +'_resizer_preview').show().css({ - 'display': 'block', - 'left': l + 'px', - 'top': t + 'px', - 'width': w + 'px', - 'height': h + 'px', - 'cursor': 'ns-resize' - }).off('mousedown').on('mousedown', function (event) { - // event before - var edata = obj.trigger({ phase: 'before', type: 'resizerClick', target: 'preview', originalEvent: event }); - if (edata.isCancelled === true) return; - // default action - w2ui[obj.name].tmp.events.resizeStart('preview', event); - // event after - obj.trigger($.extend(edata, { phase: 'after' })); - return false; - }); - } - } else { - $('#layout_'+ this.name +'_panel_preview').hide(); - $('#layout_'+ this.name +'_resizer_preview').hide(); - } - - // display tabs and toolbar if needed - for (var p1 = 0; p1 < w2panels.length; p1++) { - var pan = this.get(w2panels[p1]); - var tmp2 = '#layout_'+ this.name +'_panel_'+ w2panels[p1] +' > .w2ui-panel-'; - var tabHeight = 0; - if (pan) { - if (pan.title) { - tabHeight += w2utils.getSize($(tmp2 + 'title').css({ top: tabHeight + 'px', display: 'block' }), 'height'); - } - if (pan.show.tabs) { - if (pan.tabs != null && w2ui[this.name +'_'+ w2panels[p1] +'_tabs']) w2ui[this.name +'_'+ w2panels[p1] +'_tabs'].resize(); - tabHeight += w2utils.getSize($(tmp2 + 'tabs').css({ top: tabHeight + 'px', display: 'block' }), 'height'); - } - if (pan.show.toolbar) { - if (pan.toolbar != null && w2ui[this.name +'_'+ w2panels[p1] +'_toolbar']) w2ui[this.name +'_'+ w2panels[p1] +'_toolbar'].resize(); - tabHeight += w2utils.getSize($(tmp2 + 'toolbar').css({ top: tabHeight + 'px', display: 'block' }), 'height'); - } - } - $(tmp2 + 'content').css({ display: 'block' }).css({ top: tabHeight + 'px' }); - } - // send resize to all objects - clearTimeout(this._resize_timer); - this._resize_timer = setTimeout(function () { - for (var e in w2ui) { - if (typeof w2ui[e].resize == 'function') { - // sent to all none-layouts - if (w2ui[e].panels == null) w2ui[e].resize(); - // only send to nested layouts - var parent = $(w2ui[e].box).parents('.w2ui-layout'); - if (parent.length > 0 && parent.attr('name') == obj.name) w2ui[e].resize(); - } - } - }, 100); - this.trigger($.extend(edata, { phase: 'after' })); - return (new Date()).getTime() - time; - }, - - destroy: function () { - // event before - var edata = this.trigger({ phase: 'before', type: 'destroy', target: this.name }); - if (edata.isCancelled === true) return; - if (w2ui[this.name] == null) return false; - // clean up - if ($(this.box).find('#layout_'+ this.name +'_panel_main').length > 0) { - $(this.box) - .removeAttr('name') - .removeClass('w2ui-layout') - .html(''); - } - delete w2ui[this.name]; - // event after - this.trigger($.extend(edata, { phase: 'after' })); - if (this.tmp.events && this.tmp.events.resize) $(window).off('resize', this.tmp.events.resize); - return true; - }, - - lock: function (panel, msg, showSpinner) { - if (w2panels.indexOf(panel) == -1) { - console.log('ERROR: First parameter needs to be the a valid panel name.'); - return; - } - var args = Array.prototype.slice.call(arguments, 0); - args[0] = '#layout_'+ this.name + '_panel_' + panel; - w2utils.lock.apply(window, args); - }, - - unlock: function (panel, speed) { - if (w2panels.indexOf(panel) == -1) { - console.log('ERROR: First parameter needs to be the a valid panel name.'); - return; - } - var nm = '#layout_'+ this.name + '_panel_' + panel; - w2utils.unlock(nm, speed); - } - }; - - $.extend(w2layout.prototype, w2utils.event); - w2obj.layout = w2layout; -})(jQuery); - -/************************************************************************ -* Library: Web 2.0 UI for jQuery (using prototypical inheritance) -* - Following objects defined -* - w2popup - popup widget -* - $().w2popup - jQuery wrapper -* - Dependencies: jQuery, w2utils -* -* == NICE TO HAVE == -* - hide overlay on esc -* - make popup width/height in % -* -* == 1.5 changes -* - w2prompt -************************************************************************/ - -var w2popup = {}; - -(function ($) { - - // ==================================================== - // -- Registers as a jQuery plugin - - $.fn.w2popup = function(method, options) { - if (method == null) { - options = {}; - method = 'open'; - } - if ($.isPlainObject(method)) { - options = method; - method = 'open'; - } - method = method.toLowerCase(); - if (method === 'load' && typeof options === 'string') { - options = $.extend({ url: options }, arguments.length > 2 ? arguments[2] : {}); - } - if (method === 'open' && options.url != null) method = 'load'; - options = options || {}; - // load options from markup - var dlgOptions = {}; - if ($(this).length > 0 && method == 'open') { - if ($(this).find('div[rel=title], div[rel=body], div[rel=buttons]').length > 0) { - // remember previous tempalte - if ($('#w2ui-popup').length > 0) { - var tmp = $('#w2ui-popup').data('options'); - w2popup._prev = { - template : w2popup._template, - title : tmp.title, - body : tmp.body, - buttons : tmp.buttons - }; - } - w2popup._template = this; - - if ($(this).find('div[rel=title]').length > 0) { - dlgOptions['title'] = $(this).find('div[rel=title]'); - } - if ($(this).find('div[rel=body]').length > 0) { - dlgOptions['body'] = $(this).find('div[rel=body]'); - dlgOptions['style'] = $(this).find('div[rel=body]')[0].style.cssText; - } - if ($(this).find('div[rel=buttons]').length > 0) { - dlgOptions['buttons'] = $(this).find('div[rel=buttons]'); - } - } else { - dlgOptions['title'] = ' '; - dlgOptions['body'] = $(this).html(); - } - if (parseInt($(this).css('width')) != 0) dlgOptions['width'] = parseInt($(this).css('width')); - if (parseInt($(this).css('height')) != 0) dlgOptions['height'] = parseInt($(this).css('height')); - } - // show popup - return w2popup[method]($.extend({}, dlgOptions, options)); - }; - - // ==================================================== - // -- Implementation of core functionality (SINGLETON) - - w2popup = { - defaults: { - title : '', - body : '', - buttons : '', - style : '', - color : '#000', - opacity : 0.4, - speed : 0.3, - modal : false, - maximized : false, - keyboard : true, // will close popup on esc if not modal - width : 500, - height : 300, - showClose : true, - showMax : false, - transition: null - }, - status : 'closed', // string that describes current status - handlers : [], - onOpen : null, - onClose : null, - onMax : null, - onMin : null, - onToggle : null, - onKeydown : null, - - open: function (options) { - var obj = this; - if (w2popup.status == 'closing') { - setTimeout(function () { obj.open.call(obj, options); }, 100); - return; - } - // get old options and merge them - var old_options = $('#w2ui-popup').data('options'); - var options = $.extend({}, this.defaults, old_options, { title: '', body : '', buttons: '' }, options, { maximized: false }); - // need timer because popup might not be open - setTimeout(function () { $('#w2ui-popup').data('options', options); }, 100); - // if new - reset event handlers - if ($('#w2ui-popup').length == 0) { - // w2popup.handlers = []; // if commented, allows to add w2popup.on() for all - w2popup.onMax = null; - w2popup.onMin = null; - w2popup.onToggle = null; - w2popup.onOpen = null; - w2popup.onClose = null; - w2popup.onKeydown = null; - } - if (options.onOpen) w2popup.onOpen = options.onOpen; - if (options.onClose) w2popup.onClose = options.onClose; - if (options.onMax) w2popup.onMax = options.onMax; - if (options.onMin) w2popup.onMin = options.onMin; - if (options.onToggle) w2popup.onToggle = options.onToggle; - if (options.onKeydown) w2popup.onKeydown = options.onKeydown; - options.width = parseInt(options.width); - options.height = parseInt(options.height); - - var maxW, maxH; - if (window.innerHeight == undefined) { - maxW = parseInt(document.documentElement.offsetWidth); - maxH = parseInt(document.documentElement.offsetHeight); - if (w2utils.engine === 'IE7') { maxW += 21; maxH += 4; } - } else { - maxW = parseInt(window.innerWidth); - maxH = parseInt(window.innerHeight); - } - if (maxW - 10 < options.width) options.width = maxW - 10; - if (maxH - 10 < options.height) options.height = maxH - 10; - var top = (maxH - options.height) / 2 * 0.6; - var left = (maxW - options.width) / 2; - - // check if message is already displayed - if ($('#w2ui-popup').length == 0) { - // trigger event - var edata = this.trigger({ phase: 'before', type: 'open', target: 'popup', options: options, present: false }); - if (edata.isCancelled === true) return; - w2popup.status = 'opening'; - // output message - w2popup.lockScreen(options); - var btn = ''; - if (options.showClose) { - btn += '
Close
'; - } - if (options.showMax) { - btn += '
Max
'; - } - // first insert just body - var msg = '
'; - $('body').append(msg); - // parse rel=* - var parts = $('#w2ui-popup'); - if (parts.find('div[rel=title], div[rel=body], div[rel=buttons]').length > 0) { - // title - var tmp = parts.find('div[rel=title]'); - if (tmp.length > 0) { options.title = tmp.html(); tmp.remove(); } - // buttons - var tmp = parts.find('div[rel=buttons]'); - if (tmp.length > 0) { options.buttons = tmp.html(); tmp.remove(); } - // body - var tmp = parts.find('div[rel=body]'); - if (tmp.length > 0) options.body = tmp.html(); else options.body = parts.html(); - } - // then content - var msg = '
' + btn + '
'+ - '
'+ - '
' + - '
'+ - '
'+ - '
'+ - ''; // this is needed to keep focus in popup - $('#w2ui-popup').html(msg); - - if (options.title) $('#w2ui-popup .w2ui-popup-title').append(options.title); - if (options.buttons) $('#w2ui-popup .w2ui-popup-buttons').append(options.buttons); - if (options.body) $('#w2ui-popup .w2ui-popup-body').append(options.body); - - // allow element to render - setTimeout(function () { - $('#w2ui-popup') - .css('opacity', '1') - .css(w2utils.cssPrefix({ - 'transition': options.speed + 's opacity, ' + options.speed + 's -webkit-transform', - 'transform' : 'scale(1)' - })); - obj.focus(); - }, 1); - // clean transform - setTimeout(function () { - $('#w2ui-popup').css(w2utils.cssPrefix('transform', '')); - // event after - w2popup.status = 'open'; - setTimeout(function () { - obj.trigger($.extend(edata, { phase: 'after' })); - }, 100); - }, options.speed * 1000); - - } else { - // if was from template and now not - if (w2popup._prev == null && w2popup._template != null) obj.restoreTemplate(); - - // trigger event - var edata = this.trigger({ phase: 'before', type: 'open', target: 'popup', options: options, present: true }); - if (edata.isCancelled === true) return; - // check if size changed - w2popup.status = 'opening'; - if (old_options != null) { - if (!old_options.maximized && (old_options['width'] != options['width'] || old_options['height'] != options['height'])) { - w2popup.resize(options.width, options.height); - } - options.prevSize = options.width + 'px:' + options.height + 'px'; - options.maximized = old_options.maximized; - } - // show new items - var cloned = $('#w2ui-popup .w2ui-box').clone(); - cloned.removeClass('w2ui-box').addClass('w2ui-box-temp').find('.w2ui-popup-body').empty().append(options.body); - // parse rel=* - if (typeof options.body == 'string' && cloned.find('div[rel=title], div[rel=body], div[rel=buttons]').length > 0) { - // title - var tmp = cloned.find('div[rel=title]'); - if (tmp.length > 0) { options['title'] = tmp.html(); tmp.remove(); } - // buttons - var tmp = cloned.find('div[rel=buttons]'); - if (tmp.length > 0) { options['buttons'] = tmp.html(); tmp.remove(); } - // body - var tmp = cloned.find('div[rel=body]'); - if (tmp.length > 0) options['body'] = tmp.html(); else options['body'] = cloned.html(); - // set proper body - cloned.html(options.body); - } - $('#w2ui-popup .w2ui-box').after(cloned); - - if (options.buttons) { - $('#w2ui-popup .w2ui-popup-buttons').show().html('').append(options.buttons); - $('#w2ui-popup .w2ui-popup-body').removeClass('w2ui-popup-no-buttons'); - $('#w2ui-popup .w2ui-box, #w2ui-popup .w2ui-box-temp').css('bottom', ''); - } else { - $('#w2ui-popup .w2ui-popup-buttons').hide().html(''); - $('#w2ui-popup .w2ui-popup-body').addClass('w2ui-popup-no-buttons'); - $('#w2ui-popup .w2ui-box, #w2ui-popup .w2ui-box-temp').css('bottom', '0px'); - } - if (options.title) { - $('#w2ui-popup .w2ui-popup-title') - .show() - .html((options.showClose ? '
Close
' : '') + - (options.showMax ? '
Max
' : '')) - .append(options.title); - $('#w2ui-popup .w2ui-popup-body').removeClass('w2ui-popup-no-title'); - $('#w2ui-popup .w2ui-box, #w2ui-popup .w2ui-box-temp').css('top', ''); - } else { - $('#w2ui-popup .w2ui-popup-title').hide().html(''); - $('#w2ui-popup .w2ui-popup-body').addClass('w2ui-popup-no-title'); - $('#w2ui-popup .w2ui-box, #w2ui-popup .w2ui-box-temp').css('top', '0px'); - } - // transition - var div_old = $('#w2ui-popup .w2ui-box')[0]; - var div_new = $('#w2ui-popup .w2ui-box-temp')[0]; - w2utils.transition(div_old, div_new, options.transition, function () { - // clean up - obj.restoreTemplate(); - $(div_old).remove(); - $(div_new).removeClass('w2ui-box-temp').addClass('w2ui-box'); - var $body = $(div_new).find('.w2ui-popup-body'); - if ($body.length == 1) $body[0].style.cssText = options.style; - // remove max state - $('#w2ui-popup').data('prev-size', null); - // focus on first button - obj.focus(); - // call event onChange - w2popup.status = 'open'; - obj.trigger($.extend(edata, { phase: 'after' })); - }); - } - - // save new options - options._last_focus = $(':focus'); - // keyboard events - if (options.keyboard) $(document).on('keydown', this.keydown); - - // initialize move - var tmp = { - resizing : false, - mvMove : mvMove, - mvStop : mvStop - }; - $('#w2ui-popup .w2ui-popup-title').on('mousedown', function (event) { - if (!w2popup.get().maximized) mvStart(event); - }); - - // handlers - function mvStart(evnt) { - if (!evnt) evnt = window.event; - w2popup.status = 'moving'; - tmp.resizing = true; - tmp.isLocked = $('#w2ui-popup > .w2ui-lock').length == 1 ? true : false; - tmp.x = evnt.screenX; - tmp.y = evnt.screenY; - tmp.pos_x = $('#w2ui-popup').position().left; - tmp.pos_y = $('#w2ui-popup').position().top; - if (!tmp.isLocked) w2popup.lock({ opacity: 0 }); - $(document).on('mousemove', tmp.mvMove); - $(document).on('mouseup', tmp.mvStop); - if (evnt.stopPropagation) evnt.stopPropagation(); else evnt.cancelBubble = true; - if (evnt.preventDefault) evnt.preventDefault(); else return false; - } - - function mvMove(evnt) { - if (tmp.resizing != true) return; - if (!evnt) evnt = window.event; - tmp.div_x = evnt.screenX - tmp.x; - tmp.div_y = evnt.screenY - tmp.y; - $('#w2ui-popup').css(w2utils.cssPrefix({ - 'transition': 'none', - 'transform' : 'translate3d('+ tmp.div_x +'px, '+ tmp.div_y +'px, 0px)' - })); - } - - function mvStop(evnt) { - if (tmp.resizing != true) return; - if (!evnt) evnt = window.event; - w2popup.status = 'open'; - tmp.div_x = (evnt.screenX - tmp.x); - tmp.div_y = (evnt.screenY - tmp.y); - $('#w2ui-popup').css({ - 'left': (tmp.pos_x + tmp.div_x) + 'px', - 'top' : (tmp.pos_y + tmp.div_y) + 'px' - }).css(w2utils.cssPrefix({ - 'transition': 'none', - 'transform' : 'translate3d(0px, 0px, 0px)' - })); - tmp.resizing = false; - $(document).off('mousemove', tmp.mvMove); - $(document).off('mouseup', tmp.mvStop); - if (!tmp.isLocked) w2popup.unlock(); - } - return this; - }, - - keydown: function (event) { - var options = $('#w2ui-popup').data('options'); - if (options && !options.keyboard) return; - // trigger event - var edata = w2popup.trigger({ phase: 'before', type: 'keydown', target: 'popup', options: options, originalEvent: event }); - if (edata.isCancelled === true) return; - // default behavior - switch (event.keyCode) { - case 27: - event.preventDefault(); - if ($('#w2ui-popup .w2ui-message').length > 0) w2popup.message(); else w2popup.close(); - break; - } - // event after - w2popup.trigger($.extend(edata, { phase: 'after'})); - }, - - close: function (options) { - var obj = this; - var options = $.extend({}, $('#w2ui-popup').data('options'), options); - if ($('#w2ui-popup').length == 0 || this.status == 'closed') return; - if (this.status == 'opening') { - setTimeout(function () { w2popup.close(); }, 100); - return; - } - // trigger event - var edata = this.trigger({ phase: 'before', type: 'close', target: 'popup', options: options }); - if (edata.isCancelled === true) return; - // default behavior - w2popup.status = 'closing'; - $('#w2ui-popup') - .css('opacity', '0') - .css(w2utils.cssPrefix({ - 'transition': options.speed + 's opacity, ' + options.speed + 's -webkit-transform', - 'transform' : 'scale(0.9)' - })); - w2popup.unlockScreen(options); - setTimeout(function () { - // return template - obj.restoreTemplate(); - $('#w2ui-popup').remove(); - w2popup.status = 'closed'; - // restore active - if (options._last_focus.length > 0) options._last_focus.focus(); - // event after - obj.trigger($.extend(edata, { phase: 'after'})); - }, options.speed * 1000); - // remove keyboard events - if (options.keyboard) $(document).off('keydown', this.keydown); - }, - - toggle: function () { - var obj = this; - var options = $('#w2ui-popup').data('options'); - // trigger event - var edata = this.trigger({ phase: 'before', type: 'toggle', target: 'popup', options: options }); - if (edata.isCancelled === true) return; - // defatul action - if (options.maximized === true) w2popup.min(); else w2popup.max(); - // event after - setTimeout(function () { - obj.trigger($.extend(edata, { phase: 'after'})); - }, (options.speed * 1000) + 50); - }, - - max: function () { - var obj = this; - var options = $('#w2ui-popup').data('options'); - if (options.maximized === true) return; - // trigger event - var edata = this.trigger({ phase: 'before', type: 'max', target: 'popup', options: options }); - if (edata.isCancelled === true) return; - // default behavior - w2popup.status = 'resizing'; - options.prevSize = $('#w2ui-popup').css('width') + ':' + $('#w2ui-popup').css('height'); - // do resize - w2popup.resize(10000, 10000, function () { - w2popup.status = 'open'; - options.maximized = true; - obj.trigger($.extend(edata, { phase: 'after'})); - // resize gird, form, layout inside popup - $('#w2ui-popup .w2ui-grid, #w2ui-popup .w2ui-form, #w2ui-popup .w2ui-layout').each(function () { - var name = $(this).attr('name'); - if (w2ui[name] && w2ui[name].resize) w2ui[name].resize(); - }) - }); - }, - - min: function () { - var obj = this; - var options = $('#w2ui-popup').data('options'); - if (options.maximized !== true) return; - var size = options.prevSize.split(':'); - // trigger event - var edata = this.trigger({ phase: 'before', type: 'min', target: 'popup', options: options }); - if (edata.isCancelled === true) return; - // default behavior - w2popup.status = 'resizing'; - // do resize - w2popup.resize(parseInt(size[0]), parseInt(size[1]), function () { - w2popup.status = 'open'; - options.maximized = false; - options.prevSize = null; - obj.trigger($.extend(edata, { phase: 'after'})); - // resize gird, form, layout inside popup - $('#w2ui-popup .w2ui-grid, #w2ui-popup .w2ui-form, #w2ui-popup .w2ui-layout').each(function () { - var name = $(this).attr('name'); - if (w2ui[name] && w2ui[name].resize) w2ui[name].resize(); - }) - }); - }, - - get: function () { - return $('#w2ui-popup').data('options'); - }, - - set: function (options) { - w2popup.open(options); - }, - - clear: function() { - $('#w2ui-popup .w2ui-popup-title').html(''); - $('#w2ui-popup .w2ui-popup-body').html(''); - $('#w2ui-popup .w2ui-popup-buttons').html(''); - }, - - reset: function () { - w2popup.open(w2popup.defaults); - }, - - load: function (options) { - w2popup.status = 'loading'; - if (options.url == null) { - console.log('ERROR: The url parameter is empty.'); - return; - } - var tmp = String(options.url).split('#'); - var url = tmp[0]; - var selector = tmp[1]; - if (options == null) options = {}; - // load url - var html = $('#w2ui-popup').data(url); - if (html != null) { - popup(html, selector); - } else { - $.get(url, function (data, status, obj) { // should always be $.get as it is template - popup(obj.responseText, selector); - $('#w2ui-popup').data(url, obj.responseText); // remember for possible future purposes - }); - } - function popup(html, selector) { - delete options.url; - $('body').append(''); - if (selector != null && $('#w2ui-tmp #'+selector).length > 0) { - $('#w2ui-tmp #' + selector).w2popup(options); - } else { - $('#w2ui-tmp > div').w2popup(options); - } - // link styles - if ($('#w2ui-tmp > style').length > 0) { - var style = $('
').append($('#w2ui-tmp > style').clone()).html(); - if ($('#w2ui-popup #div-style').length == 0) { - $('#w2ui-popup').append('
'); - } - $('#w2ui-popup #div-style').html(style); - } - $('#w2ui-tmp').remove(); - } - }, - - message: function (options) { - var obj = this; - $().w2tag(); // hide all tags - if (!options) options = { width: 200, height: 100 }; - var pWidth = parseInt($('#w2ui-popup').width()); - var pHeight = parseInt($('#w2ui-popup').height()); - options.originalWidth = options.width; - options.originalHeight = options.height; - if (parseInt(options.width) < 10) options.width = 10; - if (parseInt(options.height) < 10) options.height = 10; - if (options.hideOnClick == null) options.hideOnClick = false; - var poptions = $('#w2ui-popup').data('options') || {}; - var titleHeight = parseInt($('#w2ui-popup > .w2ui-popup-title').css('height')); - if (options.width == null || options.width > poptions.width - 10) { - options.width = poptions.width - 10; - } - if (options.height == null || options.height > poptions.height - titleHeight - 5) { - options.height = poptions.height - titleHeight - 5; // need margin from bottom only - } - // negative value means margin - if (options.originalHeight < 0) options.height = pHeight + options.originalHeight - titleHeight; - if (options.originalWidth < 0) options.width = pWidth + options.originalWidth * 2; // x 2 because there is left and right margin - - var head = $('#w2ui-popup .w2ui-popup-title'); - var msgCount = $('#w2ui-popup .w2ui-message').length; - // remove message - if ($.trim(options.html) == '' && $.trim(options.body) == '' && $.trim(options.buttons) == '') { - var $msg = $('#w2ui-popup #w2ui-message'+ (msgCount-1)); - var options = $msg.data('options') || {}; - $msg.css(w2utils.cssPrefix({ - 'transition': '0.15s', - 'transform': 'translateY(-' + options.height + 'px)' - })); - if (msgCount == 1) { - w2popup.unlock(150); - } else { - $('#w2ui-popup #w2ui-message'+ (msgCount-2)).css('z-index', 1500); - } - setTimeout(function () { - var $focus = $msg.data('prev_focus'); - $msg.remove(); - if ($focus && $focus.length > 0) { - $focus.focus(); - } else { - obj.focus(); - } - if (typeof options.onClose == 'function') options.onClose(); - }, 150); - } else { - if ($.trim(options.body) != '' || $.trim(options.buttons) != '') { - options.html = '
'+ options.body +'
'+ - '
'+ options.buttons +'
'; - } - // hide previous messages - $('#w2ui-popup .w2ui-message').css('z-index', 1390); - head.css('z-index', 1501); - // add message - $('#w2ui-popup .w2ui-box') - .before(''); - $('#w2ui-popup #w2ui-message'+ msgCount).data('options', options).data('prev_focus', $(':focus')); - var display = $('#w2ui-popup #w2ui-message'+ msgCount).css('display'); - $('#w2ui-popup #w2ui-message'+ msgCount).css(w2utils.cssPrefix({ - 'transform': (display == 'none' ? 'translateY(-' + options.height + 'px)' : 'translateY(0px)') - })); - if (display == 'none') { - $('#w2ui-popup #w2ui-message'+ msgCount).show().html(options.html); - // timer needs to animation - setTimeout(function () { - $('#w2ui-popup #w2ui-message'+ msgCount).css(w2utils.cssPrefix({ - 'transform': (display == 'none' ? 'translateY(0px)' : 'translateY(-' + options.height + 'px)') - })); - }, 1); - // timer for lock - if (msgCount == 0) w2popup.lock(); - setTimeout(function() { - obj.focus(); - // has to be on top of lock - $('#w2ui-popup #w2ui-message'+ msgCount).css(w2utils.cssPrefix({ 'transition': '0s' })); - if (typeof options.onOpen == 'function') options.onOpen(); - }, 350); - } - } - }, - - focus: function () { - var tmp = null; - var pop = $('#w2ui-popup'); - var sel = 'input:visible, button:visible, select:visible, textarea:visible'; - // clear previous blur - $(pop).find(sel).off('.keep-focus'); - // in message or popup - var cnt = $('#w2ui-popup .w2ui-message').length - 1; - var msg = $('#w2ui-popup #w2ui-message' + cnt); - if (msg.length > 0) { - var btn =$(msg[msg.length - 1]).find('button'); - if (btn.length > 0) btn[0].focus(); - tmp = msg; - } else if (pop.length > 0) { - var btn = pop.find('.w2ui-popup-buttons button'); - if (btn.length > 0) btn[0].focus(); - tmp = pop; - } - // keep focus/blur inside popup - $(tmp).find(sel) - .on('blur.keep-focus', function (event) { - setTimeout(function () { - var focus = $(':focus'); - if ((focus.length > 0 && !$(tmp).find(sel).is(focus)) || focus.hasClass('w2ui-popup-hidden')) { - var el = $(tmp).find(sel); - if (el.length > 0) el[0].focus(); - } - }, 1); - }); - }, - - lock: function (msg, showSpinner) { - var args = Array.prototype.slice.call(arguments, 0); - args.unshift($('#w2ui-popup')); - w2utils.lock.apply(window, args); - }, - - unlock: function (speed) { - w2utils.unlock($('#w2ui-popup'), speed); - }, - - // --- INTERNAL FUNCTIONS - - lockScreen: function (options) { - if ($('#w2ui-lock').length > 0) return false; - if (options == null) options = $('#w2ui-popup').data('options'); - if (options == null) options = {}; - options = $.extend({}, w2popup.defaults, options); - // show element - $('body').append('
'); - // lock screen - setTimeout(function () { - $('#w2ui-lock') - .css('opacity', options.opacity) - .css(w2utils.cssPrefix('transition', options.speed + 's opacity')); - }, 1); - // add events - if (options.modal == true) { - $('#w2ui-lock').on('mousedown', function () { - $('#w2ui-lock') - .css('opacity', '0.6') - .css(w2utils.cssPrefix('transition', '.1s')); - }); - $('#w2ui-lock').on('mouseup', function () { - setTimeout(function () { - $('#w2ui-lock') - .css('opacity', options.opacity) - .css(w2utils.cssPrefix('transition', '.1s')); - }, 100); - }); - } else { - $('#w2ui-lock').on('mousedown', function () { w2popup.close(); }); - } - return true; - }, - - unlockScreen: function (options) { - if ($('#w2ui-lock').length == 0) return false; - if (options == null) options = $('#w2ui-popup').data('options'); - if (options == null) options = {}; - options = $.extend({}, w2popup.defaults, options); - $('#w2ui-lock') - .css('opacity', '0') - .css(w2utils.cssPrefix('transition', options.speed + 's opacity')); - setTimeout(function () { - $('#w2ui-lock').remove(); - }, options.speed * 1000); - return true; - }, - - resizeMessages: function () { - var obj = this; - var options = $('#w2ui-popup').data('options'); - // see if there are messages and resize them - $('#w2ui-popup .w2ui-message').each(function () { - var moptions = $(this).data('options'); - var $popup = $('#w2ui-popup'); - if (parseInt(moptions.width) < 10) moptions.width = 10; - if (parseInt(moptions.height) < 10) moptions.height = 10; - var titleHeight = parseInt($popup.find('> .w2ui-popup-title').css('height')); - var pWidth = parseInt($popup.width()); - var pHeight = parseInt($popup.height()); - // recalc width - moptions.width = moptions.originalWidth; - if (moptions.width > pWidth - 10) { - moptions.width = pWidth - 10; - } - // recalc height - moptions.height = moptions.originalHeight; - if (moptions.height > pHeight - titleHeight - 5) { - moptions.height = pHeight - titleHeight - 5; - } - if (moptions.originalHeight < 0) moptions.height = pHeight + moptions.originalHeight - titleHeight; - if (moptions.originalWidth < 0) moptions.width = pWidth + moptions.originalWidth * 2; // x 2 because there is left and right margin - $(this).css({ - left : ((pWidth - moptions.width) / 2) + 'px', - width : moptions.width + 'px', - height : moptions.height + 'px' - }); - }); - }, - - resize: function (width, height, callBack) { - var obj = this; - var options = $('#w2ui-popup').data('options'); - width = parseInt(width); - height = parseInt(height); - // calculate new position - var maxW, maxH; - if (window.innerHeight == undefined) { - maxW = parseInt(document.documentElement.offsetWidth); - maxH = parseInt(document.documentElement.offsetHeight); - if (w2utils.engine === 'IE7') { maxW += 21; maxH += 4; } - } else { - maxW = parseInt(window.innerWidth); - maxH = parseInt(window.innerHeight); - } - if (maxW - 10 < width) width = maxW - 10; - if (maxH - 10 < height) height = maxH - 10; - var top = (maxH - height) / 2 * 0.6; - var left = (maxW - width) / 2; - // resize there - $('#w2ui-popup') - .css(w2utils.cssPrefix({ - 'transition': options.speed + 's width, ' + options.speed + 's height, ' + options.speed + 's left, ' + options.speed + 's top' - })) - .css({ - 'top' : top, - 'left' : left, - 'width' : width, - 'height': height - }); - var tmp_int = setInterval(function () { obj.resizeMessages(); }, 10); // then messages resize nicely - setTimeout(function () { - clearInterval(tmp_int); - options.width = width; - options.height = height; - obj.resizeMessages(); - if (typeof callBack == 'function') callBack(); - }, (options.speed * 1000) + 50); // give extra 50 ms - }, - - /*********************** - * Internal - **/ - - // restores template - restoreTemplate: function () { - var options = $('#w2ui-popup').data('options'); - if (options == null) return; - var template = w2popup._template; - var title = options.title; - var body = options.body; - var buttons = options.buttons; - if (w2popup._prev) { - template = w2popup._prev.template; - title = w2popup._prev.title; - body = w2popup._prev.body; - buttons = w2popup._prev.buttons; - delete w2popup._prev; - } else { - delete w2popup._template; - } - if (template != null) { - var $tmp = $(template); - if ($tmp.length == 0) return; - if ($(body).attr('rel') == 'body') { - if (title) $tmp.append(title); - if (body) $tmp.append(body); - if (buttons) $tmp.append(buttons); - } else { - $tmp.append(body); - } - } - } - }; - - // merge in event handling - $.extend(w2popup, w2utils.event); - -})(jQuery); - -// ============================================ -// --- Common dialogs - -var w2alert = function (msg, title, callBack) { - var $ = jQuery; - if (title == null) title = w2utils.lang('Notification'); - if ($('#w2ui-popup').length > 0 && w2popup.status != 'closing') { - w2popup.message({ - width : 400, - height : 170, - body : '
' + msg + '
', - buttons : '', - onOpen: function () { - $('#w2ui-popup .w2ui-message .w2ui-popup-btn').focus(); - }, - onClose: function () { - if (typeof callBack == 'function') callBack(); - } - }); - } else { - w2popup.open({ - width : 450, - height : 220, - showMax : false, - showClose : false, - title : title, - body : '
' + msg + '
', - buttons : '', - onOpen: function (event) { - // do not use onComplete as it is slower - setTimeout(function () { $('#w2ui-popup .w2ui-popup-btn').focus(); }, 1); - }, - onKeydown: function (event) { - $('#w2ui-popup .w2ui-popup-btn').focus().addClass('clicked'); - }, - onClose: function () { - if (typeof callBack == 'function') callBack(); - } - }); - } -}; - -var w2confirm = function (msg, title, callBack) { - var $ = jQuery; - var options = {}; - var defaults = { - msg : '', - title : w2utils.lang('Confirmation'), - width : ($('#w2ui-popup').length > 0 ? 400 : 450), - height : ($('#w2ui-popup').length > 0 ? 170 : 220), - yes_text : 'Yes', - yes_class : '', - yes_style : '', - yes_callBack: null, - no_text : 'No', - no_class : '', - no_style : '', - no_callBack : null, - callBack : null - }; - if (arguments.length == 1 && typeof msg == 'object') { - $.extend(options, defaults, msg); - } else { - if (typeof title == 'function') { - $.extend(options, defaults, { - msg : msg, - callBack: title - }) - } else { - $.extend(options, defaults, { - msg : msg, - title : title, - callBack: callBack - }) - } - } - // if there is a yes/no button object - if (typeof options.btn_yes == 'object') { - options.yes_text = options.btn_yes.text || options.yes_text; - options.yes_class = options.btn_yes["class"] || options.yes_class; - options.yes_style = options.btn_yes.style || options.yes_style; - options.yes_callBack = options.btn_yes.callBack || options.yes_callBack; - } - if (typeof options.btn_no == 'object') { - options.no_text = options.btn_no.text || options.no_text; - options.no_class = options.btn_no["class"] || options.no_class; - options.no_style = options.btn_no.style || options.no_style; - options.no_callBack = options.btn_no.callBack || options.no_callBack; - } - if ($('#w2ui-popup').length > 0 && w2popup.status != 'closing' && w2popup.get()) { - if (options.width > w2popup.get().width) options.width = w2popup.get().width; - if (options.height > (w2popup.get().height - 50)) options.height = w2popup.get().height - 50; - w2popup.message({ - width : options.width, - height : options.height, - body : '
' + options.msg + '
', - buttons : '' + - '', - onOpen: function () { - $('#w2ui-popup .w2ui-message .w2ui-btn').on('click.w2confirm', function (event) { - w2popup._confirm_btn = event.target.id; - w2popup.message(); - }); - }, - onClose: function () { - // needed this because there might be other messages - $('#w2ui-popup .w2ui-message .w2ui-btn').off('click.w2confirm'); - // need to wait for message to slide up - setTimeout(function () { - if (typeof options.callBack == 'function') options.callBack(w2popup._confirm_btn); - if (w2popup._confirm_btn == 'Yes' && typeof options.yes_callBack == 'function') options.yes_callBack(); - if (w2popup._confirm_btn == 'No' && typeof options.no_callBack == 'function') options.no_callBack(); - }, 300); - } - // onKeydown will not work here - }); - - } else { - - if (!w2utils.isInt(options.height)) options.height = options.height + 50; - w2popup.open({ - width : options.width, - height : options.height, - title : options.title, - modal : true, - showClose : false, - body : '
' + options.msg + '
', - buttons : ''+ - '', - onOpen: function (event) { - // do not use onComplete as it is slower - setTimeout(function () { - $('#w2ui-popup .w2ui-popup-btn').on('click', function (event) { - w2popup.close(); - if (typeof options.callBack == 'function') options.callBack(event.target.id); - if (event.target.id == 'Yes' && typeof options.yes_callBack == 'function') options.yes_callBack(); - if (event.target.id == 'No' && typeof options.no_callBack == 'function') options.no_callBack(); - }); - $('#w2ui-popup .w2ui-popup-btn#Yes').focus(); - }, 1); - }, - onKeydown: function (event) { - // if there are no messages - if ($('#w2ui-popup .w2ui-message').length == 0) { - switch (event.originalEvent.keyCode) { - case 13: // enter - $('#w2ui-popup .w2ui-popup-btn#Yes').focus().addClass('clicked'); // no need fo click as enter will do click - w2popup.close(); - break; - case 27: // esc - $('#w2ui-popup .w2ui-popup-btn#No').focus().click(); - w2popup.close(); - break; - } - } - } - }); - } - - return { - yes: function (fun) { - options.yes_callBack = fun; - return this; - }, - no: function (fun) { - options.no_callBack = fun; - return this; - } - }; -}; - -var w2prompt = function (label, title, callBack) { - var $ = jQuery; - - var options = {}; - var defaults = { - label : '', - value : '', - title : w2utils.lang('Notification'), - ok_text : w2utils.lang('Ok'), - cancel_text : w2utils.lang('Cancel'), - width : ($('#w2ui-popup').lengtvalueh > 0 ? 400 : 450), - height : ($('#w2ui-popup').length > 0 ? 170 : 220), - callBack : null - } - - if (arguments.length == 1 && typeof label == 'object') { - $.extend(options, defaults, label); - } else { - if (typeof title == 'function') { - $.extend(options, defaults, { - label : label, - callBack: title - }) - } else { - $.extend(options, defaults, { - label : label, - title : title, - callBack: callBack - }) - } - } - - if ($('#w2ui-popup').length > 0 && w2popup.status != 'closing' && w2popup.get()) { - if (options.width > w2popup.get().width) options.width = w2popup.get().width; - if (options.height > (w2popup.get().height - 50)) options.height = w2popup.get().height - 50; - w2popup.message({ - width : options.width, - height : options.height, - body : '
', - buttons : '', - onOpen: function () { - $('#w2prompt').val(options.value); - $('#w2ui-popup .w2ui-message .w2ui-btn#Ok').on('click.w2prompt', function (event) { - w2popup._prompt_value = $('#w2prompt').val(); - w2popup.message(); - }); - $('#w2ui-popup .w2ui-message .w2ui-btn#Cancel').on('click.w2prompt', function (event) { - w2popup._prompt_value = null; - w2popup.message(); - }); - // set focus - setTimeout(function () { $('#w2prompt').focus(); }, 100); - }, - onClose: function () { - // needed this because there might be other messages - $('#w2ui-popup .w2ui-message .w2ui-btn').off('click.w2prompt'); - // need to wait for message to slide up - setTimeout(function () { - if (typeof options.callBack == 'function') options.callBack(w2popup._prompt_value); - }, 300); - } - // onKeydown will not work here - }); - - } else { - - if (!w2utils.isInt(options.height)) options.height = options.height + 50; - w2popup.open({ - width : options.width, - height : options.height, - title : options.title, - modal : true, - showClose : false, - body : '
', - buttons : '', - onOpen: function (event) { - // do not use onComplete as it is slower - setTimeout(function () { - $('#w2prompt').val(options.value); - $('#w2prompt').w2field('text'); - $('#w2ui-popup .w2ui-popup-btn#Ok').on('click', function (event) { - w2popup._prompt_value = $('#w2prompt').val(); - w2popup.close(); - if (typeof options.callBack == 'function') options.callBack(w2popup._prompt_value); - }); - $('#w2ui-popup .w2ui-popup-btn#Cancel').on('click', function (event) { - w2popup._prompt_value = null; - w2popup.close(); - if (typeof options.callBack == 'function') options.callBack(w2popup._prompt_value); - }); - $('#w2ui-popup .w2ui-popup-btn#Ok'); - // set focus - setTimeout(function () { $('#w2prompt').focus(); }, 100); - }, 1); - }, - onKeydown: function (event) { - // if there are no messages - if ($('#w2ui-popup .w2ui-message').length == 0) { - switch (event.originalEvent.keyCode) { - case 13: // enter - $('#w2ui-popup .w2ui-popup-btn#Ok').focus().addClass('clicked'); // no need fo click as enter will do click - w2popup.close(); - break; - case 27: // esc - w2popup.close(); - break; - } - } - } - }); - } -}; - -/************************************************************************ -* Library: Web 2.0 UI for jQuery (using prototypical inheritance) -* - Following objects defined -* - w2tabs - tabs widget -* - $().w2tabs - jQuery wrapper -* - Dependencies: jQuery, w2utils -* -* == NICE TO HAVE == -* - align = left, right, center ?? -* -************************************************************************/ - -(function ($) { - var w2tabs = function (options) { - this.box = null; // DOM Element that holds the element - this.name = null; // unique name for w2ui - this.active = null; - this.flow = 'down'; // can be down or up - this.tooltip = 'top'; // can be top, bottom, left, right - this.tabs = []; - this.routeData = {}; // data for dynamic routes - this.right = ''; - this.style = ''; - - $.extend(this, { handlers: [] }); - $.extend(true, this, w2obj.tabs, options); - }; - - // ==================================================== - // -- Registers as a jQuery plugin - - $.fn.w2tabs = function(method) { - if ($.isPlainObject(method)) { - // check name parameter - if (!w2utils.checkName(method, 'w2tabs')) return; - // extend tabs - var tabs = method.tabs || []; - var object = new w2tabs(method); - for (var i = 0; i < tabs.length; i++) { - object.tabs[i] = $.extend({}, w2tabs.prototype.tab, tabs[i]); - } - if ($(this).length !== 0) { - object.render($(this)[0]); - } - // register new object - w2ui[object.name] = object; - return object; - } else { - var obj = w2ui[$(this).attr('name')]; - if (!obj) return null; - if (arguments.length > 0) { - if (obj[method]) obj[method].apply(obj, Array.prototype.slice.call(arguments, 1)); - return this; - } else { - return obj; - } - } - }; - - // ==================================================== - // -- Implementation of core functionality - - w2tabs.prototype = { - onClick : null, - onClose : null, - onRender : null, - onRefresh : null, - onResize : null, - onDestroy : null, - - tab : { - id : null, // command to be sent to all event handlers - text : null, - route : null, - hidden : false, - disabled : false, - closable : false, - tooltip : null, - style : '', - onClick : null, - onRefresh : null, - onClose : null - }, - - add: function (tab) { - return this.insert(null, tab); - }, - - insert: function (id, tab) { - if (!$.isArray(tab)) tab = [tab]; - // assume it is array - for (var i = 0; i < tab.length; i++) { - // checks - if (tab[i].id == null) { - console.log('ERROR: The parameter "id" is required but not supplied. (obj: '+ this.name +')'); - return; - } - if (!w2utils.checkUniqueId(tab[i].id, this.tabs, 'tabs', this.name)) return; - // add tab - var newTab = $.extend({}, w2tabs.prototype.tab, tab[i]); - if (id == null) { - this.tabs.push(newTab); - } else { - var middle = this.get(id, true); - this.tabs = this.tabs.slice(0, middle).concat([newTab], this.tabs.slice(middle)); - } - this.refresh(tab[i].id); - this.resize(); - } - }, - - remove: function () { - var removed = 0; - for (var a = 0; a < arguments.length; a++) { - var tab = this.get(arguments[a]); - if (!tab) return false; - removed++; - // remove from array - this.tabs.splice(this.get(tab.id, true), 1); - // remove from screen - $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(tab.id)).remove(); - } - this.resize(); - return removed; - }, - - select: function (id) { - if (this.active == id || this.get(id) == null) return false; - this.active = id; - this.refresh(); - return true; - }, - - set: function (id, tab) { - var index = this.get(id, true); - if (index == null) return false; - $.extend(this.tabs[index], tab); - this.refresh(id); - return true; - }, - - get: function (id, returnIndex) { - if (arguments.length === 0) { - var all = []; - for (var i1 = 0; i1 < this.tabs.length; i1++) { - if (this.tabs[i1].id != null) { - all.push(this.tabs[i1].id); - } - } - return all; - } else { - for (var i2 = 0; i2 < this.tabs.length; i2++) { - if (this.tabs[i2].id == id) { // need to be == since id can be numeric - return (returnIndex === true ? i2 : this.tabs[i2]); - } - } - } - return null; - }, - - show: function () { - var obj = this; - var shown = 0; - var tmp = []; - for (var a = 0; a < arguments.length; a++) { - var tab = this.get(arguments[a]); - if (!tab || tab.hidden === false) continue; - shown++; - tab.hidden = false; - tmp.push(tab.id); - } - setTimeout(function () { for (var t=0; t
'; - } - var tabHTML = closable + - '
' + text + '
'; - if (jq_el.length === 0) { - // does not exist - create it - var addStyle = ''; - if (tab.hidden) { addStyle += 'display: none;'; } - if (tab.disabled) { addStyle += 'opacity: 0.2;'; } - var html = ''+ tabHTML + ''; - if (this.get(id, true) !== this.tabs.length-1 && $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.tabs[parseInt(this.get(id, true))+1].id)).length > 0) { - $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.tabs[parseInt(this.get(id, true))+1].id)).before(html); - } else { - $(this.box).find('#tabs_'+ this.name +'_right').before(html); - } - } else { - // refresh - jq_el.html(tabHTML); - if (tab.hidden) { jq_el.css('display', 'none'); } - else { jq_el.css('display', ''); } - if (tab.disabled) { jq_el.css({ 'opacity': '0.2' }); } - else { jq_el.css({ 'opacity': '1' }); } - } - } - // right html - $('#tabs_'+ this.name +'_right').html(this.right); - // event after - this.trigger($.extend(edata, { phase: 'after' })); - return (new Date()).getTime() - time; - }, - - render: function (box) { - var time = (new Date()).getTime(); - // event before - var edata = this.trigger({ phase: 'before', type: 'render', target: this.name, box: box }); - if (edata.isCancelled === true) return; - // default action - // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection - if (box != null) { - if ($(this.box).find('> table #tabs_'+ this.name + '_right').length > 0) { - $(this.box) - .removeAttr('name') - .removeClass('w2ui-reset w2ui-tabs') - .html(''); - } - this.box = box; - } - if (!this.box) return false; - // render all buttons - var html = '
'+ - ''+ - ' '+ - '
'+ this.right +'
'+ - '
'+ - '
'+ - '
'; - $(this.box) - .attr('name', this.name) - .addClass('w2ui-reset w2ui-tabs') - .html(html); - if ($(this.box).length > 0) $(this.box)[0].style.cssText += this.style; - // event after - this.trigger($.extend(edata, { phase: 'after' })); - this.refresh(); - this.resize(); - return (new Date()).getTime() - time; - }, - - scroll: function (direction) { - var box = $(this.box); - var obj = this; - var scrollBox = box.find('.w2ui-scroll-wrapper'); - var scrollLeft = scrollBox.scrollLeft(); - var width1, width2, scroll; - - switch (direction) { - case 'left': - width1 = scrollBox.outerWidth(); - width2 = scrollBox.find(':first').outerWidth(); - scroll = scrollLeft - width1 + 50; // 35 is width of both button - if (scroll <= 0) scroll = 0; - scrollBox.animate({ scrollLeft: scroll }, 300); - break; - - case 'right': - width1 = scrollBox.outerWidth(); - width2 = scrollBox.find(':first').outerWidth(); - scroll = scrollLeft + width1 - 50; // 35 is width of both button - if (scroll >= width2 - width1) scroll = width2 - width1; - scrollBox.animate({ scrollLeft: scroll }, 300); - break; - } - setTimeout(function () { obj.resize(); }, 350); - }, - - - resize: function () { - var time = (new Date()).getTime(); - // event before - var edata = this.trigger({ phase: 'before', type: 'resize', target: this.name }); - if (edata.isCancelled === true) return; - - // show hide overflow buttons - var box = $(this.box); - box.find('.w2ui-scroll-left, .w2ui-scroll-right').hide(); - var scrollBox = box.find('.w2ui-scroll-wrapper'); - if (scrollBox.find(':first').outerWidth() > scrollBox.outerWidth()) { - // we have overflowed content - if (scrollBox.scrollLeft() > 0) { - box.find('.w2ui-scroll-left').show(); - } - if (scrollBox.scrollLeft() < scrollBox.find(':first').outerWidth() - scrollBox.outerWidth()) { - box.find('.w2ui-scroll-right').show(); - } - } - - // event after - this.trigger($.extend(edata, { phase: 'after' })); - return (new Date()).getTime() - time; - }, - - destroy: function () { - // event before - var edata = this.trigger({ phase: 'before', type: 'destroy', target: this.name }); - if (edata.isCancelled === true) return; - // clean up - if ($(this.box).find('> table #tabs_'+ this.name + '_right').length > 0) { - $(this.box) - .removeAttr('name') - .removeClass('w2ui-reset w2ui-tabs') - .html(''); - } - delete w2ui[this.name]; - // event after - this.trigger($.extend(edata, { phase: 'after' })); - }, - - // =================================================== - // -- Internal Event Handlers - - click: function (id, event) { - var tab = this.get(id); - if (tab == null || tab.disabled) return false; - // event before - var edata = this.trigger({ phase: 'before', type: 'click', target: id, tab: tab, object: tab, originalEvent: event }); - if (edata.isCancelled === true) return; - // default action - $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.active) +' .w2ui-tab').removeClass('active'); - this.active = tab.id; - // route processing - if (typeof tab.route == 'string') { - var route = tab.route !== '' ? String('/'+ tab.route).replace(/\/{2,}/g, '/') : ''; - var info = w2utils.parseRoute(route); - if (info.keys.length > 0) { - for (var k = 0; k < info.keys.length; k++) { - if (this.routeData[info.keys[k].name] == null) continue; - route = route.replace((new RegExp(':'+ info.keys[k].name, 'g')), this.routeData[info.keys[k].name]); - } - } - setTimeout(function () { window.location.hash = route; }, 1); - } - // event after - this.trigger($.extend(edata, { phase: 'after' })); - this.refresh(id); - }, - - animateClose: function(id, event) { - var tab = this.get(id); - if (tab == null || tab.disabled) return false; - // event before - var edata = this.trigger({ phase: 'before', type: 'close', target: id, object: this.get(id), originalEvent: event }); - if (edata.isCancelled === true) return; - // default action - var obj = this; - $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(tab.id)).css(w2utils.cssPrefix('transition', '.2s')).css('opacity', '0'); - setTimeout(function () { - var width = $(obj.box).find('#tabs_'+ obj.name +'_tab_'+ w2utils.escapeId(tab.id)).width(); - $(obj.box).find('#tabs_'+ obj.name +'_tab_'+ w2utils.escapeId(tab.id)) - .html('
'); - setTimeout(function () { - $(obj.box).find('#tabs_'+ obj.name +'_tab_'+ w2utils.escapeId(tab.id)).find(':first-child').css({ 'width': '0px' }); - }, 50); - }, 200); - setTimeout(function () { - obj.remove(id); - }, 450); - // event before - this.trigger($.extend(edata, { phase: 'after' })); - this.refresh(); - }, - - animateInsert: function(id, tab) { - if (this.get(id) == null) return; - if (!$.isPlainObject(tab)) return; - // check for unique - if (!w2utils.checkUniqueId(tab.id, this.tabs, 'tabs', this.name)) return; - // insert simple div - var jq_el = $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(tab.id)); - if (jq_el.length !== 0) return; // already exists - // measure width - if (tab.text == null && tab.caption != null) tab.text = tab.caption; - var tmp = '
'+ - ''+ - '
'+ - (tab.closable ? '
' : '') + - '
'+ tab.text +'
'+ - '
'+ - '
'; - $('body').append(tmp); - // create dummy element - var tabHTML = '
 
'; - var addStyle = ''; - if (tab.hidden) { addStyle += 'display: none;'; } - if (tab.disabled) { addStyle += 'opacity: 0.2;'; } - var html = ''+ tabHTML +''; - if (this.get(id, true) !== this.tabs.length && $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.tabs[parseInt(this.get(id, true))].id)).length > 0) { - $(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.tabs[parseInt(this.get(id, true))].id)).before(html); - } else { - $(this.box).find('#tabs_'+ this.name +'_right').before(html); - } - // -- move - var obj = this; - setTimeout(function () { - var width = $('#_tmp_simple_tab').width(); - $('#_tmp_tabs').remove(); - $('#tabs_'+ obj.name +'_tab_'+ w2utils.escapeId(tab.id) +' > div').css('width', width+'px'); - }, 1); - setTimeout(function () { - // insert for real - obj.insert(id, tab); - }, 200); - } - }; - - $.extend(w2tabs.prototype, w2utils.event); - w2obj.tabs = w2tabs; -})(jQuery); - -/************************************************************************ -* Library: Web 2.0 UI for jQuery (using prototypical inheritance) -* - Following objects defined -* - w2toolbar - toolbar widget -* - $().w2toolbar - jQuery wrapper -* - Dependencies: jQuery, w2utils, w2field -* -* == NICE TO HAVE == -* - vertical toolbar -* -************************************************************************/ - -(function ($) { - var w2toolbar = function (options) { - this.box = null; // DOM Element that holds the element - this.name = null; // unique name for w2ui - this.routeData = {}; // data for dynamic routes - this.items = []; - this.right = ''; // HTML text on the right of toolbar - this.tooltip = 'top'; // can be top, bottom, left, right - - $.extend(true, this, w2obj.toolbar, options); - }; - - // ==================================================== - // -- Registers as a jQuery plugin - - $.fn.w2toolbar = function(method) { - if ($.isPlainObject(method)) { - // check name parameter - if (!w2utils.checkName(method, 'w2toolbar')) return; - // extend items - var items = method.items || []; - var object = new w2toolbar(method); - $.extend(object, { items: [], handlers: [] }); - for (var i = 0; i < items.length; i++) { - object.items[i] = $.extend({}, w2toolbar.prototype.item, items[i]); - // menus - if (object.items[i].type == 'menu-check') { - var item = object.items[i]; - if (!Array.isArray(item.selected)) item.selected = []; - if (Array.isArray(item.items)) { - for (var j = 0; j < item.items.length; j++) { - var it = item.items[j]; - if (it.checked && item.selected.indexOf(it.id) == -1) item.selected.push(it.id); - if (!it.checked && item.selected.indexOf(it.id) != -1) it.checked = true; - if (it.checked == null) it.checked = false; - } - } - } - if (object.items[i].type == 'menu-radio') { - var item = object.items[i]; - if (Array.isArray(item.items)) { - for (var j = 0; j < item.items.length; j++) { - var it = item.items[j]; - if (it.checked && item.selected == null) item.selected = it.id; else it.checked = false; - if (!it.checked && item.selected == it.id) it.checked = true; - if (it.checked == null) it.checked = false; - } - } - } - } - if ($(this).length !== 0) { - object.render($(this)[0]); - } - // register new object - w2ui[object.name] = object; - return object; - - } else { - var obj = w2ui[$(this).attr('name')]; - if (!obj) return null; - if (arguments.length > 0) { - if (obj[method]) obj[method].apply(obj, Array.prototype.slice.call(arguments, 1)); - return this; - } else { - return obj; - } - } - }; - - // ==================================================== - // -- Implementation of core functionality - - w2toolbar.prototype = { - onClick : null, - onRender : null, - onRefresh : null, - onResize : null, - onDestroy : null, - - item: { - id : null, // command to be sent to all event handlers - type : 'button', // button, check, radio, drop, menu, menu-radio, menu-check, break, html, spacer - text : null, - html : '', - tooltip : null, // w2toolbar.tooltip should be - count : null, - hidden : false, - disabled : false, - checked : false, // used for radio buttons - img : null, - icon : null, - route : null, // if not null, it is route to go - arrow : true, // arrow down for drop/menu types - style : null, // extre css style for caption - color : null, // color value - used in color pickers - transparent : null, // transparent t/f - used in color pickers - group : null, // used for radio buttons - items : null, // for type menu* it is an array of items in the menu - selected : null, // used for menu-check, menu-radio - overlay : {}, - onClick : null, - onRefresh : null - }, - - add: function (items) { - this.insert(null, items); - }, - - insert: function (id, items) { - if (!$.isArray(items)) items = [items]; - for (var o = 0; o < items.length; o++) { - // checks - if (items[o].type == null) { - console.log('ERROR: The parameter "type" is required but not supplied in w2toolbar.add() method.'); - return; - } - if ($.inArray(String(items[o].type), ['button', 'check', 'radio', 'drop', 'menu', 'menu-radio', 'menu-check', 'color', 'text-color', 'break', 'html', 'spacer']) == -1) { - console.log('ERROR: The parameter "type" should be one of the following [button, check, radio, drop, menu, break, html, spacer] '+ - 'in w2toolbar.add() method.'); - return; - } - if (items[o].id == null && items[o].type != 'break' && items[o].type != 'spacer') { - console.log('ERROR: The parameter "id" is required but not supplied in w2toolbar.add() method.'); - return; - } - if (!w2utils.checkUniqueId(items[o].id, this.items, 'toolbar items', this.name)) return; - // add item - var it = $.extend({}, w2toolbar.prototype.item, items[o]); - if (id == null) { - this.items.push(it); - } else { - var middle = this.get(id, true); - this.items = this.items.slice(0, middle).concat([it], this.items.slice(middle)); - } - this.refresh(it.id); - this.resize(); - } - }, - - remove: function () { - var removed = 0; - for (var a = 0; a < arguments.length; a++) { - var it = this.get(arguments[a]); - if (!it || String(arguments[a]).indexOf(':') != -1) continue; - removed++; - // remove from screen - $(this.box).find('#tb_'+ this.name +'_item_'+ w2utils.escapeId(it.id)).remove(); - // remove from array - var ind = this.get(it.id, true); - if (ind != null) this.items.splice(ind, 1); - } - this.resize(); - return removed; - }, - - set: function (id, newOptions) { - var item = this.get(id); - if (item == null) return false; - $.extend(item, newOptions); - this.refresh(String(id).split(':')[0]); - return true; - }, - - get: function (id, returnIndex) { - if (arguments.length == 0) { - var all = []; - for (var i1 = 0; i1 < this.items.length; i1++) if (this.items[i1].id != null) all.push(this.items[i1].id); - return all; - } - var tmp = String(id).split(':'); - for (var i2 = 0; i2 < this.items.length; i2++) { - var it = this.items[i2]; - // find a menu item - if (['menu', 'menu-radio', 'menu-check'].indexOf(it.type) != -1 && tmp.length == 2 && it.id == tmp[0]) { - for (var i = 0; i < it.items.length; i++) { - var item = it.items[i]; - if (item.id == tmp[1] || (item.id == null && item.text == tmp[1])) { - if (returnIndex == true) return i; else return item; - } - } - } else if (it.id == tmp[0]) { - if (returnIndex == true) return i2; else return it; - } - } - return null; - }, - - show: function () { - var obj = this; - var items = 0; - var tmp = []; - for (var a = 0; a < arguments.length; a++) { - var it = this.get(arguments[a]); - if (!it) continue; - items++; - it.hidden = false; - tmp.push(String(arguments[a]).split(':')[0]); - } - setTimeout(function () { for (var t=0; t 1) { - var subItem = this.get(id); - if (subItem && !subItem.disabled) { - obj.menuClick({ name: obj.name, item: it, subItem: subItem, originalEvent: event }); - } - return; - } - if (it && !it.disabled) { - // event before - var edata = this.trigger({ phase: 'before', type: 'click', target: (id != null ? id : this.name), - item: it, object: it, originalEvent: event }); - if (edata.isCancelled === true) return; - - var btn = '#tb_'+ this.name +'_item_'+ w2utils.escapeId(it.id) +' table.w2ui-button'; - $(btn).removeClass('down'); // need to requery at the moment -- as well as elsewhere in this function - - if (it.type == 'radio') { - for (var i = 0; i < this.items.length; i++) { - var itt = this.items[i]; - if (itt == null || itt.id == it.id || itt.type !== 'radio') continue; - if (itt.group == it.group && itt.checked) { - itt.checked = false; - this.refresh(itt.id); - } - } - it.checked = true; - $(btn).addClass('checked'); - } - - if (['menu', 'menu-radio', 'menu-check', 'drop', 'color', 'text-color'].indexOf(it.type) != -1) { - obj.tooltipHide(id); - if (it.checked) { - // if it was already checked, second click will hide it - setTimeout(function () { - // hide overlay - var el = $('#tb_'+ obj.name +'_item_'+ w2utils.escapeId(it.id)); - el.w2overlay({ name: obj.name }); - // uncheck - it.checked = false; - obj.refresh(it.id); - }, 1); - - } else { - - // show overlay - setTimeout(function () { - var el = $('#tb_'+ obj.name +'_item_'+ w2utils.escapeId(it.id)); - if (!$.isPlainObject(it.overlay)) it.overlay = {}; - var left = (el.width() - 50) / 2; - if (left > 19) left = 19; - if (it.type == 'drop') { - el.w2overlay(it.html, $.extend({ name: obj.name, left: left, top: 3 }, it.overlay, { - onHide: function (event) { - hideDrop(); - } - })); - } - if (['menu', 'menu-radio', 'menu-check'].indexOf(it.type) != -1) { - var menuType = 'normal'; - if (it.type == 'menu-radio') { - menuType = 'radio'; - it.items.forEach(function (item) { - if (it.selected == item.id) item.checked = true; else item.checked = false; - }); - } - if (it.type == 'menu-check') { - menuType = 'check'; - it.items.forEach(function (item) { - if ($.isArray(it.selected) && it.selected.indexOf(item.id) != -1) item.checked = true; else item.checked = false; - }); - } - el.w2menu($.extend({ name: obj.name, items: it.items, left: left, top: 3 }, it.overlay, { - type: menuType, - select: function (event) { - obj.menuClick({ name: obj.name, item: it, subItem: event.item, originalEvent: event.originalEvent, keepOpen: event.keepOpen }); - }, - onHide: function (event) { - hideDrop(); - } - })); - } - if (['color', 'text-color'].indexOf(it.type) != -1) { - if (it.transparent == null) it.transparent = true; - $(el).w2color({ color: it.color, transparent: it.transparent }, function (color, index) { - if (color != null) { - obj.colorClick({ name: obj.name, item: it, color: color, originalEvent: event.originalEvent }); - } - hideDrop(); - }); - } - function hideDrop(event) { - it.checked = false; - $(btn).removeClass('checked'); - } - }, 1); - } - } - - if (['check', 'menu', 'menu-radio', 'menu-check', 'drop', 'color', 'text-color'].indexOf(it.type) != -1) { - it.checked = !it.checked; - if (it.checked) { - $(btn).addClass('checked'); - } else { - $(btn).removeClass('checked'); - } - } - // route processing - if (it.route) { - var route = String('/'+ it.route).replace(/\/{2,}/g, '/'); - var info = w2utils.parseRoute(route); - if (info.keys.length > 0) { - for (var k = 0; k < info.keys.length; k++) { - route = route.replace((new RegExp(':'+ info.keys[k].name, 'g')), this.routeData[info.keys[k].name]); - } - } - setTimeout(function () { window.location.hash = route; }, 1); - } - if (event && ['button', 'check', 'radio'].indexOf(it.type) != -1) { - // need to refresh toolbar as it might be dynamic - this.tooltipShow(id, event, true); - } - // event after - this.trigger($.extend(edata, { phase: 'after' })); - } - }, - - scroll: function (direction) { - var box = $(this.box); - var obj = this; - var scrollBox = box.find('.w2ui-scroll-wrapper'); - var scrollLeft = scrollBox.scrollLeft(); - var width1, width2, scroll; - - switch (direction) { - case 'left': - width1 = scrollBox.outerWidth(); - width2 = scrollBox.find(':first').outerWidth(); - scroll = scrollLeft - width1 + 50; // 35 is width of both button - if (scroll <= 0) scroll = 0; - scrollBox.animate({ scrollLeft: scroll }, 300); - break; - - case 'right': - width1 = scrollBox.outerWidth(); - width2 = scrollBox.find(':first').outerWidth(); - scroll = scrollLeft + width1 - 50; // 35 is width of both button - if (scroll >= width2 - width1) scroll = width2 - width1; - scrollBox.animate({ scrollLeft: scroll }, 300); - break; - } - setTimeout(function () { obj.resize(); }, 350); - }, - - render: function (box) { - var time = (new Date()).getTime(); - // event before - var edata = this.trigger({ phase: 'before', type: 'render', target: this.name, box: box }); - if (edata.isCancelled === true) return; - - if (box != null) { - if ($(this.box).find('> table #tb_'+ this.name + '_right').length > 0) { - $(this.box) - .removeAttr('name') - .removeClass('w2ui-reset w2ui-toolbar') - .html(''); - } - this.box = box; - } - if (!this.box) return; - // render all buttons - var html = '
'+ - ''+ - ''; - for (var i = 0; i < this.items.length; i++) { - var it = this.items[i]; - if (it == null) continue; - if (it.id == null) it.id = "item_" + i; - if (it.type == 'spacer') { - html += ''; - } else { - html += ''; - } - } - html += ''; - html += ''+ - '
'+ - ''+ this.right +'
'+ - '
'+ - '
'; - $(this.box) - .attr('name', this.name) - .addClass('w2ui-reset w2ui-toolbar') - .html(html); - if ($(this.box).length > 0) $(this.box)[0].style.cssText += this.style; - // refresh all - this.refresh(); - this.resize(); - // event after - this.trigger($.extend(edata, { phase: 'after' })); - return (new Date()).getTime() - time; - }, - - refresh: function (id) { - var time = (new Date()).getTime(); - // event before - var edata = this.trigger({ phase: 'before', type: 'refresh', target: (id != null ? id : this.name), item: this.get(id) }); - if (edata.isCancelled === true) return; - // refresh all - if (id == null) { - for (var i = 0; i < this.items.length; i++) { - var it1 = this.items[i]; - if (it1.id == null) it1.id = "item_" + i; - this.refresh(it1.id); - } - return; - } - // create or refresh only one item - var it = this.get(id); - if (it == null) return false; - if (typeof it.onRefresh == 'function') { - var edata2 = this.trigger({ phase: 'before', type: 'refresh', target: id, item: it, object: it }); - if (edata2.isCancelled === true) return; - } - var el = $(this.box).find('#tb_'+ this.name +'_item_'+ w2utils.escapeId(it.id)); - var html = this.getItemHTML(it); - if (el.length == 0) { - // does not exist - create it - if (it.type == 'spacer') { - html = ''; - } else { - html = ''+ html + - ''; - } - if (this.get(id, true) == this.items.length-1) { - $(this.box).find('#tb_'+ this.name +'_right').before(html); - } else { - $(this.box).find('#tb_'+ this.name +'_item_'+ w2utils.escapeId(this.items[parseInt(this.get(id, true))+1].id)).before(html); - } - } else { - if (['menu', 'menu-radio', 'menu-check', 'drop', 'color', 'text-color'].indexOf(it.type) != -1 && it.checked == false) { - if ($('#w2ui-overlay-'+ this.name).length > 0) $('#w2ui-overlay-'+ this.name)[0].hide(); - } - // refresh - el.html(html); - if (it.hidden) { el.css('display', 'none'); } else { el.css('display', ''); } - if (it.disabled) { el.addClass('disabled'); } else { el.removeClass('disabled'); } - } - // event after - if (typeof it.onRefresh == 'function') { - this.trigger($.extend(edata2, { phase: 'after' })); - } - this.trigger($.extend(edata, { phase: 'after' })); - return (new Date()).getTime() - time; - }, - - resize: function () { - var time = (new Date()).getTime(); - // event before - var edata = this.trigger({ phase: 'before', type: 'resize', target: this.name }); - if (edata.isCancelled === true) return; - - // show hide overflow buttons - var box = $(this.box); - box.find('.w2ui-scroll-left, .w2ui-scroll-right').hide(); - var scrollBox = box.find('.w2ui-scroll-wrapper'); - if (scrollBox.find(':first').outerWidth() > scrollBox.outerWidth()) { - // we have overflowed content - if (scrollBox.scrollLeft() > 0) { - box.find('.w2ui-scroll-left').show(); - } - if (scrollBox.scrollLeft() < scrollBox.find(':first').outerWidth() - scrollBox.outerWidth()) { - box.find('.w2ui-scroll-right').show(); - } - } - - // event after - this.trigger($.extend(edata, { phase: 'after' })); - return (new Date()).getTime() - time; - }, - - destroy: function () { - // event before - var edata = this.trigger({ phase: 'before', type: 'destroy', target: this.name }); - if (edata.isCancelled === true) return; - // clean up - if ($(this.box).find('> table #tb_'+ this.name + '_right').length > 0) { - $(this.box) - .removeAttr('name') - .removeClass('w2ui-reset w2ui-toolbar') - .html(''); - } - $(this.box).html(''); - delete w2ui[this.name]; - // event after - this.trigger($.extend(edata, { phase: 'after' })); - }, - - // ======================================== - // --- Internal Functions - - getItemHTML: function (item) { - var html = ''; - if (item.caption != null && item.text == null) item.text = item.caption; // for backward compatibility - if (item.text == null) item.text = ''; - if (item.tooltip == null && item.hint != null) item.tooltip = item.hint; // for backward compatibility - if (item.tooltip == null) item.tooltip = ''; - var img = ' '; - var text = item.text; - if (typeof text == 'function') text = text.call(this, item); - if (item.img) img = '
'; - if (item.icon) img = '
'; - - if (html == '') switch (item.type) { - case 'color': - case 'text-color': - if (typeof item.color == 'string' && item.color.substr(0,1) == '#') item.color = item.color.substr(1); - if (item.type == 'color') { - text = '
'+ - (item.text ? '
' + w2utils.lang(item.text) + '
' : ''); - } - if (item.type == 'text-color') { - text = '
'+ - (item.text ? w2utils.lang(item.text) : 'Aa') + - '
'; - } - case 'menu': - case 'menu-check': - case 'menu-radio': - case 'button': - case 'check': - case 'radio': - case 'drop': - html += ''+ - '
'+ - ' '+ - ' ' + - img + - (text !== '' - ? '' - : '' - ) + - (item.count != null - ? '' - : '' - ) + - (((['menu', 'menu-radio', 'menu-check', 'drop', 'color', 'text-color'].indexOf(item.type) != -1) && item.arrow !== false) ? - '' : '') + - '
'+ w2utils.lang(text) +''+ item.count +'
'+ - '
'; - break; - - case 'break': - html += ''+ - ' '+ - '
 
'; - break; - - case 'html': - html += ''+ - ' '+ - '
' + (typeof item.html == 'function' ? item.html.call(this, item) : item.html) + '
'; - break; - } - return '
' + html + '
'; - }, - - tooltipShow: function (id, event, forceRefresh) { - if (this.tooltip == null) return; - var $el = $(this.box).find('#tb_'+ this.name + '_item_'+ w2utils.escapeId(id)); - var item = this.get(id); - var pos = this.tooltip; - var txt = item.tooltip; - if (typeof txt == 'function') txt = txt.call(this, item); - $el.prop('_mouse_over', true); - setTimeout(function () { - if ($el.prop('_mouse_over') === true && $el.prop('_mouse_tooltip') !== true) { - $el.prop('_mouse_tooltip', true); - // show tooltip - if (['menu', 'menu-radio', 'menu-check', 'drop', 'color', 'text-color'].indexOf(item.type) != -1 && item.checked == true) return; // not for opened drop downs - $el.w2tag(w2utils.lang(txt), { position: pos }); - } - if (forceRefresh == true) { - $el.w2tag(w2utils.lang(txt), { position: pos }); - } - }, 1); - }, - - tooltipHide: function (id, event) { - if (this.tooltip == null) return; - var $el = $(this.box).find('#tb_'+ this.name + '_item_'+ w2utils.escapeId(id)); - var item = this.get(id); - $el.removeProp('_mouse_over'); - setTimeout(function () { - if ($el.prop('_mouse_over') !== true && $el.prop('_mouse_tooltip') === true) { - $el.removeProp('_mouse_tooltip'); - // hide tooltip - $el.w2tag(); - } - }, 1); - }, - - menuClick: function (event) { - var obj = this; - if (event.item && !event.item.disabled) { - // event before - var edata = this.trigger({ phase: 'before', type: 'click', target: event.item.id + ':' + event.subItem.id, item: event.item, - subItem: event.subItem, originalEvent: event.originalEvent }); - if (edata.isCancelled === true) return; - - // route processing - var it = event.subItem; - var item = this.get(event.item.id); - if (item.type == 'menu-radio') { - item.selected = it.id; - event.item.items.forEach(function (item) { item.checked = false }); - it.checked = true; - } - if (item.type == 'menu-check') { - if (!$.isArray(item.selected)) item.selected = []; - var ind = item.selected.indexOf(it.id); - if (ind == -1) { - item.selected.push(it.id); - it.checked = true; - } else { - item.selected.splice(ind, 1); - it.checked = false; - } - } - if (typeof it.route == 'string') { - var route = it.route !== '' ? String('/'+ it.route).replace(/\/{2,}/g, '/') : ''; - var info = w2utils.parseRoute(route); - if (info.keys.length > 0) { - for (var k = 0; k < info.keys.length; k++) { - if (obj.routeData[info.keys[k].name] == null) continue; - route = route.replace((new RegExp(':'+ info.keys[k].name, 'g')), this.routeData[info.keys[k].name]); - } - } - setTimeout(function () { window.location.hash = route; }, 1); - } - this.refresh(event.item.id); - // event after - this.trigger($.extend(edata, { phase: 'after' })); - } - }, - - colorClick: function (event) { - var obj = this; - if (event.item && !event.item.disabled) { - // event before - var edata = this.trigger({ phase: 'before', type: 'click', target: event.item.id, item: event.item, - color: event.color, originalEvent: event.originalEvent }); - if (edata.isCancelled === true) return; - - // default behavior - event.item.color = event.color; - obj.refresh(event.item.id); - - // event after - this.trigger($.extend(edata, { phase: 'after' })); - } - } - }; - - $.extend(w2toolbar.prototype, w2utils.event); - w2obj.toolbar = w2toolbar; -})(jQuery); -/************************************************************************ -* Library: Web 2.0 UI for jQuery (using prototypical inheritance) -* - Following objects defined -* - w2sidebar - sidebar widget -* - $().w2sidebar - jQuery wrapper -* - Dependencies: jQuery, w2utils -* -* == NICE TO HAVE == -* - add find() method to find nodes by a specific criteria (I want all nodes for exampe) -* - dbl click should be like it is in grid (with timer not HTML dbl click event) -* - reorder with dgrag and drop -* - node.style is misleading - should be there to apply color for example -* - add multiselect -* -************************************************************************/ - -(function ($) { - var w2sidebar = function (options) { - this.name = null; - this.box = null; - this.sidebar = null; - this.parent = null; - this.nodes = []; // Sidebar child nodes - this.menu = []; - this.routeData = {}; // data for dynamic routes - this.selected = null; // current selected node (readonly) - this.img = null; - this.icon = null; - this.style = ''; - this.topHTML = ''; - this.bottomHTML = ''; - this.flatButton = false; - this.keyboard = true; - this.flat = false; - this.hasFocus = false; - - $.extend(true, this, w2obj.sidebar, options); - }; - - // ==================================================== - // -- Registers as a jQuery plugin - - $.fn.w2sidebar = function(method) { - if ($.isPlainObject(method)) { - // check name parameter - if (!w2utils.checkName(method, 'w2sidebar')) return; - // extend items - var nodes = method.nodes; - var object = new w2sidebar(method); - $.extend(object, { handlers: [], nodes: [] }); - if (nodes != null) { - object.add(object, nodes); - } - if ($(this).length !== 0) { - object.render($(this)[0]); - } - object.sidebar = object; - // register new object - w2ui[object.name] = object; - return object; - - } else { - var obj = w2ui[$(this).attr('name')]; - if (!obj) return null; - if (arguments.length > 0) { - if (obj[method]) obj[method].apply(obj, Array.prototype.slice.call(arguments, 1)); - return this; - } else { - return obj; - } - } - }; - - // ==================================================== - // -- Implementation of core functionality - - w2sidebar.prototype = { - - onClick : null, // Fire when user click on Node Text - onDblClick : null, // Fire when user dbl clicks - onContextMenu : null, - onMenuClick : null, // when context menu item selected - onExpand : null, // Fire when node Expands - onCollapse : null, // Fire when node Colapses - onKeydown : null, - onRender : null, - onRefresh : null, - onResize : null, - onDestroy : null, - onFocus : null, - onBlur : null, - onFlat : null, - - node: { - id : null, - text : '', - count : null, - img : null, - icon : null, - nodes : [], - style : '', // additional style for subitems - route : null, - selected : false, - expanded : false, - hidden : false, - disabled : false, - group : false, // if true, it will build as a group - groupShowHide : true, - collapsible : true, - plus : false, // if true, plus will be shown even if there is no sub nodes - // events - onClick : null, - onDblClick : null, - onContextMenu : null, - onExpand : null, - onCollapse : null, - // internal - parent : null, // node object - sidebar : null - }, - - add: function (parent, nodes) { - if (arguments.length == 1) { - // need to be in reverse order - nodes = arguments[0]; - parent = this; - } - if (typeof parent == 'string') parent = this.get(parent); - return this.insert(parent, null, nodes); - }, - - insert: function (parent, before, nodes) { - var txt, ind, tmp, node, nd; - if (arguments.length == 2) { - // need to be in reverse order - nodes = arguments[1]; - before = arguments[0]; - if (before != null) { - ind = this.get(before); - if (ind == null) { - if (!$.isArray(nodes)) nodes = [nodes]; - txt = (nodes[0].caption != null ? nodes[0].caption : nodes[0].text); - console.log('ERROR: Cannot insert node "'+ txt +'" because cannot find node "'+ before +'" to insert before.'); - return null; - } - parent = this.get(before).parent; - } else { - parent = this; - } - } - if (typeof parent == 'string') parent = this.get(parent); - if (!$.isArray(nodes)) nodes = [nodes]; - for (var o = 0; o < nodes.length; o++) { - node = nodes[o]; - if (typeof node.id == null) { - txt = (node.caption != null ? node.caption : node.text); - console.log('ERROR: Cannot insert node "'+ txt +'" because it has no id.'); - continue; - } - if (this.get(this, node.id) != null) { - txt = (node.caption != null ? node.caption : node.text); - console.log('ERROR: Cannot insert node with id='+ node.id +' (text: '+ txt + ') because another node with the same id already exists.'); - continue; - } - tmp = $.extend({}, w2sidebar.prototype.node, node); - tmp.sidebar = this; - tmp.parent = parent; - nd = tmp.nodes || []; - tmp.nodes = []; // very important to re-init empty nodes array - if (before == null) { // append to the end - parent.nodes.push(tmp); - } else { - ind = this.get(parent, before, true); - if (ind == null) { - txt = (node.caption != null ? node.caption : node.text); - console.log('ERROR: Cannot insert node "'+ txt +'" because cannot find node "'+ before +'" to insert before.'); - return null; - } - parent.nodes.splice(ind, 0, tmp); - } - if (nd.length > 0) { - this.insert(tmp, null, nd); - } - } - this.refresh(parent.id); - return tmp; - }, - - remove: function () { // multiple arguments - var deleted = 0; - var tmp; - for (var a = 0; a < arguments.length; a++) { - tmp = this.get(arguments[a]); - if (tmp == null) continue; - if (this.selected != null && this.selected === tmp.id) { - this.selected = null; - } - var ind = this.get(tmp.parent, arguments[a], true); - if (ind == null) continue; - if (tmp.parent.nodes[ind].selected) tmp.sidebar.unselect(tmp.id); - tmp.parent.nodes.splice(ind, 1); - deleted++; - } - if (deleted > 0 && arguments.length == 1) this.refresh(tmp.parent.id); else this.refresh(); - return deleted; - }, - - set: function (parent, id, node) { - if (arguments.length == 2) { - // need to be in reverse order - node = id; - id = parent; - parent = this; - } - // searches all nested nodes - if (typeof parent == 'string') parent = this.get(parent); - if (parent.nodes == null) return null; - for (var i = 0; i < parent.nodes.length; i++) { - if (parent.nodes[i].id === id) { - // make sure nodes inserted correctly - var nodes = node.nodes; - $.extend(parent.nodes[i], node, { nodes: [] }); - if (nodes != null) { - this.add(parent.nodes[i], nodes); - } - this.refresh(id); - return true; - } else { - var rv = this.set(parent.nodes[i], id, node); - if (rv) return true; - } - } - return false; - }, - - get: function (parent, id, returnIndex) { // can be just called get(id) or get(id, true) - if (arguments.length === 0) { - var all = []; - var tmp = this.find({}); - for (var t = 0; t < tmp.length; t++) { - if (tmp[t].id != null) all.push(tmp[t].id); - } - return all; - } else { - if (arguments.length == 1 || (arguments.length == 2 && id === true) ) { - // need to be in reverse order - returnIndex = id; - id = parent; - parent = this; - } - // searches all nested nodes - if (typeof parent == 'string') parent = this.get(parent); - if (parent.nodes == null) return null; - for (var i = 0; i < parent.nodes.length; i++) { - if (parent.nodes[i].id == id) { - if (returnIndex === true) return i; else return parent.nodes[i]; - } else { - var rv = this.get(parent.nodes[i], id, returnIndex); - if (rv || rv === 0) return rv; - } - } - return null; - } - }, - - find: function (parent, params, results) { // can be just called find({ selected: true }) - if (arguments.length == 1) { - // need to be in reverse order - params = parent; - parent = this; - } - if (!results) results = []; - // searches all nested nodes - if (typeof parent == 'string') parent = this.get(parent); - if (parent.nodes == null) return results; - for (var i = 0; i < parent.nodes.length; i++) { - var match = true; - for (var prop in params) { // params is an object - if (parent.nodes[i][prop] != params[prop]) match = false; - } - if (match) results.push(parent.nodes[i]); - if (parent.nodes[i].nodes.length > 0) results = this.find(parent.nodes[i], params, results); - } - return results; - }, - - hide: function () { // multiple arguments - var hidden = 0; - for (var a = 0; a < arguments.length; a++) { - var tmp = this.get(arguments[a]); - if (tmp == null) continue; - tmp.hidden = true; - hidden++; - } - if (arguments.length == 1) this.refresh(arguments[0]); else this.refresh(); - return hidden; - }, - - show: function () { // multiple arguments - var shown = 0; - for (var a = 0; a < arguments.length; a++) { - var tmp = this.get(arguments[a]); - if (tmp == null) continue; - tmp.hidden = false; - shown++; - } - if (arguments.length == 1) this.refresh(arguments[0]); else this.refresh(); - return shown; - }, - - disable: function () { // multiple arguments - var disabled = 0; - for (var a = 0; a < arguments.length; a++) { - var tmp = this.get(arguments[a]); - if (tmp == null) continue; - tmp.disabled = true; - if (tmp.selected) this.unselect(tmp.id); - disabled++; - } - if (arguments.length == 1) this.refresh(arguments[0]); else this.refresh(); - return disabled; - }, - - enable: function () { // multiple arguments - var enabled = 0; - for (var a = 0; a < arguments.length; a++) { - var tmp = this.get(arguments[a]); - if (tmp == null) continue; - tmp.disabled = false; - enabled++; - } - if (arguments.length == 1) this.refresh(arguments[0]); else this.refresh(); - return enabled; - }, - - select: function (id) { - var new_node = this.get(id); - if (!new_node) return false; - if (this.selected == id && new_node.selected) return false; - this.unselect(this.selected); - $(this.box).find('#node_'+ w2utils.escapeId(id)) - .addClass('w2ui-selected') - .find('.w2ui-icon').addClass('w2ui-icon-selected'); - new_node.selected = true; - this.selected = id; - return true; - }, - - unselect: function (id) { - // if no arguments provided, unselect selected node - if (arguments.length == 0) { - id = this.selected; - } - var current = this.get(id); - if (!current) return false; - current.selected = false; - $(this.box).find('#node_'+ w2utils.escapeId(id)) - .removeClass('w2ui-selected') - .find('.w2ui-icon').removeClass('w2ui-icon-selected'); - if (this.selected == id) this.selected = null; - return true; - }, - - toggle: function(id) { - var nd = this.get(id); - if (nd == null) return false; - if (nd.plus) { - this.set(id, { plus: false }); - this.expand(id); - this.refresh(id); - return; - } - if (nd.nodes.length === 0) return false; - if (!nd.collapsible) return false; - if (this.get(id).expanded) return this.collapse(id); else return this.expand(id); - }, - - collapse: function (id) { - var obj = this; - var nd = this.get(id); - // event before - var edata = this.trigger({ phase: 'before', type: 'collapse', target: id, object: nd }); - if (edata.isCancelled === true) return; - // default action - $(this.box).find('#node_'+ w2utils.escapeId(id) +'_sub').slideUp(200); - $(this.box).find('#node_'+ w2utils.escapeId(id) +' .w2ui-node-dots:first-child').html('
+
'); - nd.expanded = false; - // event after - this.trigger($.extend(edata, { phase: 'after' })); - setTimeout(function () { obj.refresh(id); }, 200); - return true; - }, - - collapseAll: function (parent) { - if (parent == null) parent = this; - if (typeof parent == 'string') parent = this.get(parent); - if (parent.nodes == null) return false; - for (var i = 0; i < parent.nodes.length; i++) { - if (parent.nodes[i].expanded === true) parent.nodes[i].expanded = false; - if (parent.nodes[i].nodes && parent.nodes[i].nodes.length > 0) this.collapseAll(parent.nodes[i]); - } - this.refresh(parent.id); - return true; - }, - - expand: function (id) { - var obj = this; - var nd = this.get(id); - // event before - var edata = this.trigger({ phase: 'before', type: 'expand', target: id, object: nd }); - if (edata.isCancelled === true) return; - // default action - $(this.box).find('#node_'+ w2utils.escapeId(id) +'_sub').slideDown(200); - $(this.box).find('#node_'+ w2utils.escapeId(id) +' .w2ui-node-dots:first-child').html('
-
'); - nd.expanded = true; - // event after - this.trigger($.extend(edata, { phase: 'after' })); - setTimeout(function () { obj.refresh(id); }, 200); - return true; - }, - - expandAll: function (parent) { - if (parent == null) parent = this; - if (typeof parent == 'string') parent = this.get(parent); - if (parent.nodes == null) return false; - for (var i = 0; i < parent.nodes.length; i++) { - if (parent.nodes[i].expanded === false) parent.nodes[i].expanded = true; - if (parent.nodes[i].nodes && parent.nodes[i].nodes.length > 0) this.expandAll(parent.nodes[i]); - } - this.refresh(parent.id); - }, - - expandParents: function (id) { - var node = this.get(id); - if (node == null) return false; - if (node.parent) { - if (!node.parent.expanded) { - node.parent.expanded = true; - this.refresh(node.parent.id); - } - this.expandParents(node.parent.id); - } - return true; - }, - - click: function (id, event) { - var obj = this; - var nd = this.get(id); - if (nd == null) return; - if (nd.disabled || nd.group) return; // should click event if already selected - // TODO INTO-CPS APP CTHA: Manually commented select part. - // See: https://github.com/vitmalina/w2ui/issues/1267 - // // unselect all previsously - // $(obj.box).find('.w2ui-node.w2ui-selected').each(function (index, el) { - // var oldID = $(el).attr('id').replace('node_', ''); - // var oldNode = obj.get(oldID); - // if (oldNode != null) oldNode.selected = false; - // $(el).removeClass('w2ui-selected').find('.w2ui-icon').removeClass('w2ui-icon-selected'); - // }); - // // select new one - // var newNode = $(obj.box).find('#node_'+ w2utils.escapeId(id)); - // var oldNode = $(obj.box).find('#node_'+ w2utils.escapeId(obj.selected)); - // newNode.addClass('w2ui-selected').find('.w2ui-icon').addClass('w2ui-icon-selected'); - // need timeout to allow rendering - setTimeout(function () { - // event before - var edata = obj.trigger({ phase: 'before', type: 'click', target: id, originalEvent: event, node: nd, object: nd }); - if (edata.isCancelled === true) { - // TODO INTO-CPS APP CTHA: Manually commented select part. - // restore selection - // newNode.removeClass('w2ui-selected').find('.w2ui-icon').removeClass('w2ui-icon-selected'); - // oldNode.addClass('w2ui-selected').find('.w2ui-icon').addClass('w2ui-icon-selected'); - return; - } - // default action - if (typeof oldNode !== 'undefined' && oldNode != null) - oldNode.selected = false; - obj.get(id).selected = true; - obj.selected = id; - // route processing - if (typeof nd.route == 'string') { - var route = nd.route !== '' ? String('/'+ nd.route).replace(/\/{2,}/g, '/') : ''; - var info = w2utils.parseRoute(route); - if (info.keys.length > 0) { - for (var k = 0; k < info.keys.length; k++) { - if (obj.routeData[info.keys[k].name] == null) continue; - route = route.replace((new RegExp(':'+ info.keys[k].name, 'g')), obj.routeData[info.keys[k].name]); - } - } - setTimeout(function () { window.location.hash = route; }, 1); - } - // event after - obj.trigger($.extend(edata, { phase: 'after' })); - }, 1); - }, - - focus: function (event) { - var obj = this; - // event before - var edata = this.trigger({ phase: 'before', type: 'focus', target: this.name, originalEvent: event }); - if (edata.isCancelled === true) return false; - // default behaviour - this.hasFocus = true; - $(this.box).find('.w2ui-selected').removeClass('w2ui-inactive'); - setTimeout(function () { - var $input = $(obj.box).find('#sidebar_'+ obj.name + '_focus'); - if (!$input.is(':focus')) $input.focus(); - }, 10); - // event after - this.trigger($.extend(edata, { phase: 'after' })); - }, - - blur: function (event) { - // event before - var edata = this.trigger({ phase: 'before', type: 'blur', target: this.name, originalEvent: event }); - if (edata.isCancelled === true) return false; - // default behaviour - this.hasFocus = false; - $(this.box).find('.w2ui-selected').addClass('w2ui-inactive'); - // event after - this.trigger($.extend(edata, { phase: 'after' })); - }, - - keydown: function (event) { - var obj = this; - var nd = obj.get(obj.selected); - if (obj.keyboard !== true) return; - if (!nd) nd = obj.nodes[0]; - // trigger event - var edata = obj.trigger({ phase: 'before', type: 'keydown', target: obj.name, originalEvent: event }); - if (edata.isCancelled === true) return; - // default behaviour - if (event.keyCode == 13 || event.keyCode == 32) { // enter or space - if (nd.nodes.length > 0) obj.toggle(obj.selected); - } - if (event.keyCode == 37) { // left - if (nd.nodes.length > 0 && nd.expanded) { - obj.collapse(obj.selected); - } else { - selectNode(nd.parent); - if (!nd.parent.group) obj.collapse(nd.parent.id); - } - } - if (event.keyCode == 39) { // right - if ((nd.nodes.length > 0 || nd.plus) && !nd.expanded) obj.expand(obj.selected); - } - if (event.keyCode == 38) { // up - selectNode(neighbor(nd, prev)); - } - if (event.keyCode == 40) { // down - selectNode(neighbor(nd, next)); - } - // cancel event if needed - if ($.inArray(event.keyCode, [13, 32, 37, 38, 39, 40]) != -1) { - if (event.preventDefault) event.preventDefault(); - if (event.stopPropagation) event.stopPropagation(); - } - // event after - obj.trigger($.extend(edata, { phase: 'after' })); - - function selectNode (node, event) { - if (node != null && !node.hidden && !node.disabled && !node.group) { - obj.click(node.id, event); - setTimeout(function () { obj.scrollIntoView(); }, 50); - } - } - - function neighbor (node, neighborFunc) { - node = neighborFunc(node); - while (node != null && (node.hidden || node.disabled)) { - if (node.group) break; else node = neighborFunc(node); - } - return node; - } - - function next (node, noSubs) { - if (node == null) return null; - var parent = node.parent; - var ind = obj.get(node.id, true); - var nextNode = null; - // jump inside - if (node.expanded && node.nodes.length > 0 && noSubs !== true) { - var t = node.nodes[0]; - if (t.hidden || t.disabled || t.group) nextNode = next(t); else nextNode = t; - } else { - if (parent && ind + 1 < parent.nodes.length) { - nextNode = parent.nodes[ind + 1]; - } else { - nextNode = next(parent, true); // jump to the parent - } - } - if (nextNode != null && (nextNode.hidden || nextNode.disabled || nextNode.group)) nextNode = next(nextNode); - return nextNode; - } - - function prev (node) { - if (node == null) return null; - var parent = node.parent; - var ind = obj.get(node.id, true); - var prevNode = (ind > 0) ? lastChild(parent.nodes[ind - 1]) : parent; - if (prevNode != null && (prevNode.hidden || prevNode.disabled || prevNode.group)) prevNode = prev(prevNode); - return prevNode; - } - - function lastChild (node) { - if (node.expanded && node.nodes.length > 0) { - var t = node.nodes[node.nodes.length - 1]; - if (t.hidden || t.disabled || t.group) return prev(t); else return lastChild(t); - } - return node; - } - }, - - scrollIntoView: function (id) { - if (id == null) id = this.selected; - var nd = this.get(id); - if (nd == null) return; - var body = $(this.box).find('.w2ui-sidebar-div'); - var item = $(this.box).find('#node_'+ w2utils.escapeId(id)); - var offset = item.offset().top - body.offset().top; - if (offset + item.height() > body.height() || offset <= 0) { - body.animate({ 'scrollTop': body.scrollTop() + offset - body.height() / 2 + item.height() }, 250, 'linear'); - } - }, - - dblClick: function (id, event) { - var nd = this.get(id); - // event before - var edata = this.trigger({ phase: 'before', type: 'dblClick', target: id, originalEvent: event, object: nd }); - if (edata.isCancelled === true) return; - // default action - this.toggle(id); - // event after - this.trigger($.extend(edata, { phase: 'after' })); - }, - - contextMenu: function (id, event) { - var obj = this; - var nd = obj.get(id); - if (id != obj.selected) obj.click(id); - // event before - var edata = obj.trigger({ phase: 'before', type: 'contextMenu', target: id, originalEvent: event, object: nd }); - if (edata.isCancelled === true) return; - // default action - // TODO INTO-CPS APP CTHA: Used to be: if (nd.group || nd.disabled) return; - // See https://github.com/vitmalina/w2ui/issues/1232 - if (nd.disabled) return; - if (obj.menu.length > 0) { - $(obj.box).find('#node_'+ w2utils.escapeId(id)) - .w2menu({ - items: obj.menu, - contextMenu: true, - originalEvent: event, - onSelect: function (event) { - obj.menuClick(id, parseInt(event.index), event.originalEvent); - } - } - ); - } - // cancel event - if (event.preventDefault) event.preventDefault(); - // event after - obj.trigger($.extend(edata, { phase: 'after' })); - }, - - menuClick: function (itemId, index, event) { - var obj = this; - // event before - var edata = obj.trigger({ phase: 'before', type: 'menuClick', target: itemId, originalEvent: event, menuIndex: index, menuItem: obj.menu[index] }); - if (edata.isCancelled === true) return; - // default action - // -- empty - // event after - obj.trigger($.extend(edata, { phase: 'after' })); - }, - - goFlat: function () { - // event before - var edata = this.trigger({ phase: 'before', type: 'flat', goFlat: !this.flat }); - if (edata.isCancelled === true) return; - // default action - this.flat = !this.flat; - this.refresh(); - // event after - this.trigger($.extend(edata, { phase: 'after' })); - }, - - render: function (box) { - var time = (new Date()).getTime(); - var obj = this; - // event before - var edata = this.trigger({ phase: 'before', type: 'render', target: this.name, box: box }); - if (edata.isCancelled === true) return; - // default action - if (box != null) { - if ($(this.box).find('> div > div.w2ui-sidebar-div').length > 0) { - $(this.box) - .removeAttr('name') - .removeClass('w2ui-reset w2ui-sidebar') - .html(''); - } - this.box = box; - } - if (!this.box) return; - $(this.box) - .attr('name', this.name) - .addClass('w2ui-reset w2ui-sidebar') - .html('
'+ - ''+ - '
' + - '
'+ - '
'+ - '
' - ); - $(this.box).find('> div').css({ - width : $(this.box).width() + 'px', - height : $(this.box).height() + 'px' - }); - if ($(this.box).length > 0) $(this.box)[0].style.cssText += this.style; - // adjust top and bottom - var flatHTML = ''; - if (this.flatButton == true) { - flatHTML = '
'; - } - if (this.topHTML !== '' || flatHTML != '') { - $(this.box).find('.w2ui-sidebar-top').html(this.topHTML + flatHTML); - $(this.box).find('.w2ui-sidebar-div') - .css('top', $(this.box).find('.w2ui-sidebar-top').height() + 'px'); - } - if (this.bottomHTML !== '') { - $(this.box).find('.w2ui-sidebar-bottom').html(this.bottomHTML); - $(this.box).find('.w2ui-sidebar-div') - .css('bottom', $(this.box).find('.w2ui-sidebar-bottom').height() + 'px'); - } - // focus - var kbd_timer; - $(this.box).find('#sidebar_'+ this.name + '_focus') - .on('focus', function (event) { - clearTimeout(kbd_timer); - if (!obj.hasFocus) obj.focus(event); - }) - .on('blur', function (event) { - kbd_timer = setTimeout(function () { - if (obj.hasFocus) { obj.blur(event); } - }, 100); - }) - .on('keydown', function (event) { - if (event.keyCode != 9) { // not tab - w2ui[obj.name].keydown.call(w2ui[obj.name], event); - } - }); - $(this.box).off('mousedown').on('mousedown', function (event) { - // set focus to grid - setTimeout(function () { - // if input then do not focus - if (['INPUT', 'TEXTAREA', 'SELECT'].indexOf(event.target.tagName.toUpperCase()) == -1) { - var $input = $(obj.box).find('#sidebar_'+ obj.name + '_focus'); - if (!$input.is(':focus')) $input.focus(); - } - }, 1); - }); - // event after - this.trigger($.extend(edata, { phase: 'after' })); - // --- - this.refresh(); - return (new Date()).getTime() - time; - }, - - refresh: function (id) { - var time = (new Date()).getTime(); - // event before - var edata = this.trigger({ phase: 'before', type: 'refresh', target: (id != null ? id : this.name), - fullRefresh: (id != null ? false : true) }); - if (edata.isCancelled === true) return; - // adjust top and bottom - var flatHTML = ''; - if (this.flatButton == true) { - flatHTML = '
'; - } - if (this.topHTML !== '' || flatHTML !== '') { - $(this.box).find('.w2ui-sidebar-top').html(this.topHTML + flatHTML); - $(this.box).find('.w2ui-sidebar-div') - .css('top', $(this.box).find('.w2ui-sidebar-top').height() + 'px'); - } - if (this.bottomHTML !== '') { - $(this.box).find('.w2ui-sidebar-bottom').html(this.bottomHTML); - $(this.box).find('.w2ui-sidebar-div') - .css('bottom', $(this.box).find('.w2ui-sidebar-bottom').height() + 'px'); - } - // default action - $(this.box).find('> div').css({ - width : $(this.box).width() + 'px', - height: $(this.box).height() + 'px' - }); - var obj = this; - var node, nd; - var nm; - if (id == null) { - node = this; - nm = '.w2ui-sidebar-div'; - } else { - node = this.get(id); - if (node == null) return; - nm = '#node_'+ w2utils.escapeId(node.id) + '_sub'; - } - var nodeHTML; - if (node !== this) { - var tmp = '#node_'+ w2utils.escapeId(node.id); - nodeHTML = getNodeHTML(node); - $(this.box).find(tmp).before(''); - $(this.box).find(tmp).remove(); - $(this.box).find(nm).remove(); - $('#sidebar_'+ this.name + '_tmp').before(nodeHTML); - $('#sidebar_'+ this.name + '_tmp').remove(); - } - // refresh sub nodes - $(this.box).find(nm).html(''); - for (var i = 0; i < node.nodes.length; i++) { - nd = node.nodes[i]; - nodeHTML = getNodeHTML(nd); - $(this.box).find(nm).append(nodeHTML); - if (nd.nodes.length !== 0) { - this.refresh(nd.id); - } else { - // trigger event - var edata2 = this.trigger({ phase: 'before', type: 'refresh', target: nd.id }); - if (edata2.isCancelled === true) return; - // event after - this.trigger($.extend(edata2, { phase: 'after' })); - } - } - // event after - this.trigger($.extend(edata, { phase: 'after' })); - return (new Date()).getTime() - time; - - function getNodeHTML(nd) { - var html = ''; - var img = nd.img; - if (img == null) img = this.img; - var icon = nd.icon; - if (icon == null) icon = this.icon; - // -- find out level - var tmp = nd.parent; - var level = 0; - while (tmp && tmp.parent != null) { - if (tmp.group) level--; - tmp = tmp.parent; - level++; - } - if (nd.caption != null) nd.text = nd.caption; - if (nd.group) { - html = - '
'+ - ((nd.groupShowHide && nd.collapsible) ? ''+ (!nd.hidden && nd.expanded ? w2utils.lang('Hide') : w2utils.lang('Show')) +'' : '') + - (typeof nd.text == 'function' ? nd.text.call(obj, nd) : ''+ nd.text +'') + - '
'+ - '
'; - if (obj.flat) { - html = '
 
'+ - '
'; - } - } else { - if (nd.selected && !nd.disabled) obj.selected = nd.id; - tmp = ''; - if (img) tmp = '
'; - if (icon) tmp = '
'; - var text = nd.text; - if (typeof nd.text == 'function') text = nd.text.call(obj, nd); - html = '
'+ - ''+ - ''+ - ''+ - '
'+ - '
' + (nd.nodes.length > 0 ? (nd.expanded ? '-' : '+') : (nd.plus ? '+' : '')) + '
' + - '
'+ - tmp + - (nd.count || nd.count === 0 ? '
'+ nd.count +'
' : '') + - '
'+ text +'
'+ - '
'+ - '
'+ - '
'; - if (obj.flat) { - html = '
'+ nd.count +'' : '')) + '\'), '+ - ' { id: \'' + nd.id + '\', left: -5 })"'+ - ' onmouseout="jQuery(this).find(\'.w2ui-node-data\').w2tag(null, { id: \'' + nd.id + '\' })"'+ - ' ondblclick="w2ui[\''+ obj.name +'\'].dblClick(\''+ nd.id +'\', event);"'+ - ' oncontextmenu="w2ui[\''+ obj.name +'\'].contextMenu(\''+ nd.id +'\', event);"'+ - ' onClick="w2ui[\''+ obj.name +'\'].click(\''+ nd.id +'\', event); ">'+ - '
'+ tmp +'
'+ - '
'+ - '
'; - } - } - return html; - } - }, - - resize: function () { - var time = (new Date()).getTime(); - // event before - var edata = this.trigger({ phase: 'before', type: 'resize', target: this.name }); - if (edata.isCancelled === true) return; - // default action - $(this.box).css('overflow', 'hidden'); // container should have no overflow - $(this.box).find('> div').css({ - width : $(this.box).width() + 'px', - height : $(this.box).height() + 'px' - }); - // event after - this.trigger($.extend(edata, { phase: 'after' })); - return (new Date()).getTime() - time; - }, - - destroy: function () { - // event before - var edata = this.trigger({ phase: 'before', type: 'destroy', target: this.name }); - if (edata.isCancelled === true) return; - // clean up - if ($(this.box).find('> div > div.w2ui-sidebar-div').length > 0) { - $(this.box) - .removeAttr('name') - .removeClass('w2ui-reset w2ui-sidebar') - .html(''); - } - delete w2ui[this.name]; - // event after - this.trigger($.extend(edata, { phase: 'after' })); - }, - - lock: function (msg, showSpinner) { - var args = Array.prototype.slice.call(arguments, 0); - args.unshift(this.box); - w2utils.lock.apply(window, args); - }, - - unlock: function (speed) { - w2utils.unlock(this.box, speed); - } - }; - - $.extend(w2sidebar.prototype, w2utils.event); - w2obj.sidebar = w2sidebar; -})(jQuery); -/************************************************************************ -* Library: Web 2.0 UI for jQuery (using prototypical inheritance) -* - Following objects defined -* - w2field - various field controls -* - $().w2field - jQuery wrapper -* - Dependencies: jQuery, w2utils -* -* == NICE TO HAVE == -* - upload (regular files) -* - BUG with prefix/postfix and arrows (test in different contexts) -* - prefix and suffix are slow (100ms or so) -* - multiple date selection -* - month selection, year selections -* - arrows no longer work (for int) -* - form to support custom types -* - rewrite suffix and prefix positioning with translateY() -* - MultiSelect - Allow Copy/Paste for single and multi values -* - add routeData to list/enum -* - for type: list -> read value from attr('value') -* - ENUM, LIST: should be able to define which is ID field and which is TEXT -* - ENUM, LIST: same data structure as grid -* - ENUM, LIST: should have same as grid (limit, offset, search, sort) -* - ENUM, LIST: should support wild cars -* - add selection of predefined times (used for appointments) -* -* == 1.5 changes -* - added support decimalSymbol (added options.decimalSymbol) -* - $('#id').w2field() - will return w2field object (same as $('#id').data('w2field')) -* - added resize() function and automatic watching for size -* - bug: if input is hidden and then enum is applied, then when it becomes visible, it will be 110px -* - deprecate placeholder, read it from input -* - added get(), set(), setIndex() for fields -* - added options.compare function for list, combo, enum -* - added options.filter for list, combo, enum -* - added selection for the current date in the calendar -* - added for enum options.onScroll -* - modified clearCache() -* - changed onSearch - happens when search input changes -* - added options.method - for combo/list/enum if url is defined -* - options.items can be a function now -* - options.maxDropWidth -* - options.noMinutes - for time field -* - options.transarent = t/f for color -* - remote data is not compatible with grid -* - options.recId, options.recText - to define custom id and text for remove data, can be string or function -* - options.readContent - for file type -* -************************************************************************/ - -(function ($) { - - var w2field = function (options) { - // public properties - this.el = null; - this.helpers = {}; // object or helper elements - this.type = options.type || 'text'; - this.options = $.extend(true, {}, options); - this.onSearch = options.onSearch || null; - this.onRequest = options.onRequest || null; - this.onLoad = options.onLoad || null; - this.onError = options.onError || null; - this.onClick = options.onClick || null; - this.onAdd = options.onAdd || null; - this.onNew = options.onNew || null; - this.onRemove = options.onRemove || null; - this.onMouseOver = options.onMouseOver || null; - this.onMouseOut = options.onMouseOut || null; - this.onIconClick = options.onIconClick || null; - this.onScroll = options.onScroll || null; - this.tmp = {}; // temp object - // clean up some options - delete this.options.type; - delete this.options.onSearch; - delete this.options.onRequest; - delete this.options.onLoad; - delete this.options.onError; - delete this.options.onClick; - delete this.options.onMouseOver; - delete this.options.onMouseOut; - delete this.options.onIconClick; - delete this.options.onScroll; - // extend with defaults - $.extend(true, this, w2obj.field); - }; - - // ==================================================== - // -- Registers as a jQuery plugin - - $.fn.w2field = function (method, options) { - // call direct - if (this.length == 0) { - var pr = w2field.prototype; - if (pr[method]) { - return pr[method].apply(pr, Array.prototype.slice.call(arguments, 1)); - } - } else { - // if without arguments - return the object - if (arguments.length == 0) { - var obj = $(this).data('w2field'); - return obj; - } - if (typeof method == 'string' && typeof options == 'object') { - method = $.extend(true, {}, options, { type: method }); - } - if (typeof method == 'string' && options == null) { - method = { type: method }; - } - method.type = String(method.type).toLowerCase(); - return this.each(function (index, el) { - var obj = $(el).data('w2field'); - // if object is not defined, define it - if (obj == null) { - var obj = new w2field(method); - $.extend(obj, { handlers: [] }); - if (el) obj.el = $(el)[0]; - obj.init(); - $(el).data('w2field', obj); - return obj; - } else { // fully re-init - obj.clear(); - if (method.type == 'clear') return; - var obj = new w2field(method); - $.extend(obj, { handlers: [] }); - if (el) obj.el = $(el)[0]; - obj.init(); - $(el).data('w2field', obj); - return obj; - } - return null; - }); - } - }; - - // ==================================================== - // -- Implementation of core functionality - - /* To add custom types - $().w2field('addType', 'myType', function (options) { - $(this.el).on('keypress', function (event) { - if (event.metaKey || event.ctrlKey || event.altKey - || (event.charCode != event.keyCode && event.keyCode > 0)) return; - var ch = String.fromCharCode(event.charCode); - if (ch != 'a' && ch != 'b' && ch != 'c') { - if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; - return false; - } - }); - $(this.el).on('blur', function (event) { // keyCode & charCode differ in FireFox - var ch = this.value; - if (ch != 'a' && ch != 'b' && ch != 'c') { - $(this).w2tag(w2utils.lang("Not a single character from the set of 'abc'")); - } - }); - }); - */ - - w2field.prototype = { - - custom: {}, // map of custom types - - addType: function (type, handler) { - type = String(type).toLowerCase(); - this.custom[type] = handler; - return true; - }, - - removeType: function (type) { - type = String(type).toLowerCase(); - if (!this.custom[type]) return false; - delete this.custom[type]; - return true; - }, - - init: function () { - var obj = this; - var options = this.options; - var defaults; - - // Custom Types - if (typeof this.custom[this.type] == 'function') { - this.custom[this.type].call(this, options); - return; - } - // only for INPUT or TEXTAREA - if (['INPUT', 'TEXTAREA'].indexOf(this.el.tagName.toUpperCase()) == -1) { - console.log('ERROR: w2field could only be applied to INPUT or TEXTAREA.', this.el); - return; - } - - switch (this.type) { - case 'text': - case 'int': - case 'float': - case 'money': - case 'currency': - case 'percent': - case 'alphanumeric': - case 'bin': - case 'hex': - defaults = { - min : null, - max : null, - step : 1, - autoFormat : true, - currencyPrefix : w2utils.settings.currencyPrefix, - currencySuffix : w2utils.settings.currencySuffix, - currencyPrecision : w2utils.settings.currencyPrecision, - decimalSymbol : w2utils.settings.decimalSymbol, - groupSymbol : w2utils.settings.groupSymbol, - arrows : false, - keyboard : true, - precision : null, - silent : true, - prefix : '', - suffix : '' - }; - this.options = $.extend(true, {}, defaults, options); - options = this.options; // since object is re-created, need to re-assign - options.numberRE = new RegExp('['+ options.groupSymbol + ']', 'g'); - options.moneyRE = new RegExp('['+ options.currencyPrefix + options.currencySuffix + options.groupSymbol +']', 'g'); - options.percentRE = new RegExp('['+ options.groupSymbol + '%]', 'g'); - // no keyboard support needed - if (['text', 'alphanumeric', 'hex', 'bin'].indexOf(this.type) != -1) { - options.arrows = false; - options.keyboard = false; - } - this.addPrefix(); // only will add if needed - this.addSuffix(); - break; - - case 'color': - defaults = { - prefix : '#', - suffix : '
 
', - arrows : false, - keyboard : false, - transparent : true - }; - $.extend(options, defaults); - this.addPrefix(); // only will add if needed - this.addSuffix(); // only will add if needed - // additional checks - $(this.el).attr('maxlength', 6); - if ($(this.el).val() != '') setTimeout(function () { obj.change(); }, 1); - break; - - case 'date': - defaults = { - format : w2utils.settings.dateFormat, // date format - keyboard : true, - silent : true, - start : '', // string or jquery object - end : '', // string or jquery object - blocked : {}, // { '4/11/2011': 'yes' } - colored : {}, // { '4/11/2011': 'red:white' } - blockWeekDays : null // array of numbers of weekday to block - }; - this.options = $.extend(true, {}, defaults, options); - options = this.options; // since object is re-created, need to re-assign - if ($(this.el).attr('placeholder') == null) $(this.el).attr('placeholder', options.format); - break; - - case 'time': - defaults = { - format : w2utils.settings.timeFormat, - keyboard : true, - silent : true, - start : '', - end : '', - noMinutes : false - }; - this.options = $.extend(true, {}, defaults, options); - options = this.options; // since object is re-created, need to re-assign - if ($(this.el).attr('placeholder') == null) $(this.el).attr('placeholder', options.format); - break; - - case 'datetime': - defaults = { - format : w2utils.settings.dateFormat + ' | ' + w2utils.settings.timeFormat, - keyboard : true, - silent : true, - start : '', // string or jquery object or Date object - end : '', // string or jquery object or Date object - blocked : [], // [ '4/11/2011', '4/12/2011' ] or [ new Date(2011, 4, 11), new Date(2011, 4, 12) ] - colored : {}, // { '12/17/2014': 'blue:green', '12/18/2014': 'gray:white' }; // key has be be formatted with w2utils.settings.dateFormat - placeholder : null, // optional. will fall back to this.format if not specified. Only used if this.el has no placeholder attribute. - btn_now : true, // show/hide the use-current-date-and-time button - noMinutes : false - }; - this.options = $.extend(true, {}, defaults, options); - options = this.options; // since object is re-created, need to re-assign - if ($(this.el).attr('placeholder') == null) $(this.el).attr('placeholder', options.placeholder || options.format); - break; - - case 'list': - case 'combo': - defaults = { - items : [], - selected : {}, - url : null, // url to pull data from - recId : null, // map retrieved data from url to id, can be string or function - recText : null, // map retrieved data from url to text, can be string or function - method : null, // default comes from w2utils.settings.dataType - interval : 350, // number of ms to wait before sending server call on search - postData : {}, - minLength : 1, // min number of chars when trigger search - cacheMax : 250, - maxDropHeight : 350, // max height for drop down menu - maxDropWidth : null, // if null then auto set - match : 'begins', // ['contains', 'is', 'begins', 'ends'] - silent : true, - icon : null, - iconStyle : '', - onSearch : null, // when search needs to be performed - onRequest : null, // when request is submitted - onLoad : null, // when data is received - onError : null, // when data fails to load due to server error or other failure modes - onIconClick : null, - renderDrop : null, // render function for drop down item - compare : null, // compare function for filtering - filter : true, // weather to filter at all - prefix : '', - suffix : '', - openOnFocus : false, // if to show overlay onclick or when typing - markSearch : false - }; - options.items = this.normMenu(options.items); // need to be first - if (this.type == 'list') { - // defaults.search = (options.items && options.items.length >= 10 ? true : false); - defaults.openOnFocus = true; - $(this.el).addClass('w2ui-select'); - // if simple value - look it up - if (!$.isPlainObject(options.selected) && options.items) { - for (var i = 0; i< options.items.length; i++) { - var item = options.items[i]; - if (item && item.id == options.selected) { - options.selected = $.extend(true, {}, item); - break; - } - } - } - this.watchSize(); - } - options = $.extend({}, defaults, options, { - align : 'both', // same width as control - altRows : true // alternate row color - }); - this.options = options; - if (!$.isPlainObject(options.selected)) options.selected = {}; - $(this.el).data('selected', options.selected); - if (options.url) { - options.items = []; - this.request(0); - } - if (this.type == 'list') this.addFocus(); - this.addPrefix(); - this.addSuffix(); - setTimeout(function () { obj.refresh(); }, 10); // need this for icon refresh - $(this.el).attr('autocomplete', 'off'); - if (options.selected.text != null) $(this.el).val(options.selected.text); - break; - - case 'enum': - defaults = { - items : [], - selected : [], - max : 0, // max number of selected items, 0 - unlim - url : null, // not implemented - recId : null, // map retrieved data from url to id, can be string or function - recText : null, // map retrieved data from url to text, can be string or function - interval : 350, // number of ms to wait before sending server call on search - method : null, // default comes from w2utils.settings.dataType - postData : {}, - minLength : 1, // min number of chars when trigger search - cacheMax : 250, - maxWidth : 250, // max width for a single item - maxHeight : 350, // max height for input control to grow - maxDropHeight : 350, // max height for drop down menu - maxDropWidth : null, // if null then auto set - match : 'contains', // ['contains', 'is', 'begins', 'ends'] - silent : true, - openOnFocus : false, // if to show overlay onclick or when typing - markSearch : true, - renderDrop : null, // render function for drop down item - renderItem : null, // render selected item - compare : null, // compare function for filtering - filter : true, // alias for compare - style : '', // style for container div - onSearch : null, // when search needs to be performed - onRequest : null, // when request is submitted - onLoad : null, // when data is received - onError : null, // when data fails to load due to server error or other failure modes - onClick : null, // when an item is clicked - onAdd : null, // when an item is added - onNew : null, // when new item should be added - onRemove : null, // when an item is removed - onMouseOver : null, // when an item is mouse over - onMouseOut : null, // when an item is mouse out - onScroll : null // when div with selected items is scrolled - }; - options = $.extend({}, defaults, options, { - align : 'both', // same width as control - suffix : '', - altRows : true // alternate row color - }); - options.items = this.normMenu(options.items); - options.selected = this.normMenu(options.selected); - this.options = options; - if (!$.isArray(options.selected)) options.selected = []; - $(this.el).data('selected', options.selected); - if (options.url) { - options.items = []; - this.request(0); - } - this.addSuffix(); - this.addMulti(); - this.watchSize(); - break; - - case 'file': - defaults = { - selected : [], - max : 0, - maxSize : 0, // max size of all files, 0 - unlim - maxFileSize : 0, // max size of a single file, 0 -unlim - maxWidth : 250, // max width for a single item - maxHeight : 350, // max height for input control to grow - maxDropHeight : 350, // max height for drop down menu - maxDropWidth : null, // if null then auto set - readContent : true, // if true, it will readAsDataURL content of the file - silent : true, - renderItem : null, // render selected item - style : '', // style for container div - onClick : null, // when an item is clicked - onAdd : null, // when an item is added - onRemove : null, // when an item is removed - onMouseOver : null, // when an item is mouse over - onMouseOut : null // when an item is mouse out - }; - options = $.extend({}, defaults, options, { - align : 'both', // same width as control - altRows : true // alternate row color - }); - this.options = options; - if (!$.isArray(options.selected)) options.selected = []; - $(this.el).data('selected', options.selected); - if ($(this.el).attr('placeholder') == null) { - $(this.el).attr('placeholder', w2utils.lang('Attach files by dragging and dropping or Click to Select')); - } - this.addMulti(); - this.watchSize(); - break; - } - // attach events - this.tmp = { - onChange : function (event) { obj.change.call(obj, event); }, - onClick : function (event) { obj.click.call(obj, event); }, - onFocus : function (event) { obj.focus.call(obj, event); }, - onBlur : function (event) { obj.blur.call(obj, event); }, - onKeydown : function (event) { obj.keyDown.call(obj, event); }, - onKeyup : function (event) { obj.keyUp.call(obj, event); }, - onKeypress : function (event) { obj.keyPress.call(obj, event); } - }; - $(this.el) - .addClass('w2field w2ui-input') - .data('w2field', this) - .on('change.w2field', this.tmp.onChange) - .on('click.w2field', this.tmp.onClick) // ignore click because it messes overlays - .on('focus.w2field', this.tmp.onFocus) - .on('blur.w2field', this.tmp.onBlur) - .on('keydown.w2field', this.tmp.onKeydown) - .on('keyup.w2field', this.tmp.onKeyup) - .on('keypress.w2field', this.tmp.onKeypress) - .css(w2utils.cssPrefix('box-sizing', 'border-box')); - // format initial value - this.change($.Event('change')); - }, - - watchSize: function () { - var obj = this; - var tmp = $(obj.el).data('tmp') || {}; - tmp.sizeTimer = setInterval(function () { - if ($(obj.el).parents('body').length > 0) { - obj.resize(); - } else { - clearInterval(tmp.sizeTimer); - } - }, 200); - $(obj.el).data('tmp', tmp); - }, - - get: function () { - var ret; - if (['list', 'enum', 'file'].indexOf(this.type) != -1) { - ret = $(this.el).data('selected'); - } else { - ret = $(this.el).val(); - } - return ret; - }, - - set: function (val) { - if (['list', 'enum', 'file'].indexOf(this.type) != -1) { - $(this.el).data('selected', val).change(); - this.refresh(); - } else { - $(this.el).val(val); - } - }, - - setIndex: function (ind) { - var items = this.options.items; - if (items && items[ind]) { - $(this.el).data('selected', items[ind]).change(); - this.refresh(); - return true; - } - return false; - }, - - clear: function () { - var obj = this; - var options = this.options; - // if money then clear value - if (['money', 'currency'].indexOf(this.type) != -1) { - $(this.el).val($(this.el).val().replace(options.moneyRE, '')); - } - if (this.type == 'percent') { - $(this.el).val($(this.el).val().replace(/%/g, '')); - } - if (this.type == 'color') { - $(this.el).removeAttr('maxlength'); - } - if (this.type == 'list') { - $(this.el).removeClass('w2ui-select'); - } - this.type = 'clear'; - var tmp = $(this.el).data('tmp'); - if (!this.tmp) return; - // restore paddings - if (tmp != null) { - $(this.el).height('auto'); - if (tmp && tmp['old-padding-left']) $(this.el).css('padding-left', tmp['old-padding-left']); - if (tmp && tmp['old-padding-right']) $(this.el).css('padding-right', tmp['old-padding-right']); - if (tmp && tmp['old-background-color']) $(this.el).css('background-color', tmp['old-background-color']); - if (tmp && tmp['old-border-color']) $(this.el).css('border-color', tmp['old-border-color']); - // remove resize watcher - clearInterval(tmp.sizeTimer); - } - // remove events and (data) - $(this.el) - .val(this.clean($(this.el).val())) - .removeClass('w2field') - .removeData() // removes all attached data - .off('.w2field'); // remove only events added by w2field - // remove helpers - for (var h in this.helpers) $(this.helpers[h]).remove(); - this.helpers = {}; - }, - - refresh: function () { - var obj = this; - var options = this.options; - var selected = $(this.el).data('selected'); - var time = (new Date()).getTime(); - // enum - if (['list'].indexOf(this.type) != -1) { - $(obj.el).parent().css('white-space', 'nowrap'); // needs this for arrow always to appear on the right side - // hide focus and show text - if (obj.helpers.prefix) obj.helpers.prefix.hide(); - setTimeout(function () { - if (!obj.helpers.focus) return; - // if empty show no icon - if (!$.isEmptyObject(selected) && options.icon) { - options.prefix = ''+ - ''; - obj.addPrefix(); - } else { - options.prefix = ''; - obj.addPrefix(); - } - // focus helper - var focus = obj.helpers.focus.find('input'); - if ($(focus).val() == '') { - $(focus).css('text-indent', '-9999em').prev().css('opacity', 0); - $(obj.el).val(selected && selected.text != null ? selected.text : ''); - } else { - $(focus).css('text-indent', 0).prev().css('opacity', 1); - $(obj.el).val(''); - setTimeout(function () { - if (obj.helpers.prefix) obj.helpers.prefix.hide(); - var tmp = 'position: absolute; opacity: 0; margin: 4px 0px 0px 2px; background-position: left !important;'; - if (options.icon) { - $(focus).css('margin-left', '17px'); - $(obj.helpers.focus).find('.icon-search').attr('style', tmp + 'width: 11px !important; opacity: 1; display: block'); - } else { - $(focus).css('margin-left', '0px'); - $(obj.helpers.focus).find('.icon-search').attr('style', tmp + 'width: 0px !important; opacity: 0; display: none'); - } - }, 1); - } - // if readonly or disabled - if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) { - setTimeout(function () { - $(obj.helpers.prefix).css('opacity', '0.6'); - $(obj.helpers.suffix).css('opacity', '0.6'); - }, 1); - } else { - setTimeout(function () { - $(obj.helpers.prefix).css('opacity', '1'); - $(obj.helpers.suffix).css('opacity', '1'); - }, 1); - } - }, 1); - } - if (['enum', 'file'].indexOf(this.type) != -1) { - var html = ''; - if (selected) { - for (var s = 0; s < selected.length; s++) { - var it = selected[s]; - var ren = ''; - if (typeof options.renderItem == 'function') { - ren = options.renderItem(it, s, '
  
'); - } else { - ren = '
  
'+ - (obj.type == 'enum' ? it.text : it.name + ' - '+ w2utils.formatSize(it.size) +''); - } - html += '
  • '+ - ren +'
  • '; - } - } - var div = obj.helpers.multi; - var ul = div.find('ul'); - div.attr('style', div.attr('style') + ';' + options.style); - $(obj.el).css('z-index', '-1'); - if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) { - setTimeout(function () { - div[0].scrollTop = 0; // scroll to the top - div.addClass('w2ui-readonly') - .find('li').css('opacity', '0.9') - .parent().find('li.nomouse').hide() - .find('input').prop('readonly', true) - .parents('ul') - .find('.w2ui-list-remove').hide(); - }, 1); - } else { - setTimeout(function () { - div.removeClass('w2ui-readonly') - .find('li').css('opacity', '1') - .parent().find('li.nomouse').show() - .find('input').prop('readonly', false) - .parents('ul') - .find('.w2ui-list-remove').show(); - }, 1); - } - - // clean - div.find('.w2ui-enum-placeholder').remove(); - ul.find('li').not('li.nomouse').remove(); - // add new list - if (html != '') { - ul.prepend(html); - } else if ($(obj.el).attr('placeholder') != null && div.find('input').val() == '') { - var style = - 'padding-top: ' + $(this.el).css('padding-top') + ';'+ - 'padding-left: ' + $(this.el).css('padding-left') + '; ' + - 'box-sizing: ' + $(this.el).css('box-sizing') + '; ' + - 'line-height: ' + $(this.el).css('line-height') + '; ' + - 'font-size: ' + $(this.el).css('font-size') + '; ' + - 'font-family: ' + $(this.el).css('font-family') + '; '; - div.prepend('
    '+ $(obj.el).attr('placeholder') +'
    '); - } - // ITEMS events - div.off('scroll.w2field').on('scroll.w2field', function (event) { - var edata = obj.trigger({ phase: 'before', type: 'scroll', target: obj.el, originalEvent: event }); - if (edata.isCancelled === true) return; - // event after - obj.trigger($.extend(edata, { phase: 'after' })); - }) - .find('li') - .data('mouse', 'out') - .on('click', function (event) { - var target = (event.target.tagName.toUpperCase() == 'LI' ? event.target : $(event.target).parents('LI')); - var item = selected[$(target).attr('index')]; - if ($(target).hasClass('nomouse')) return; - event.stopPropagation(); - // default behavior - if ($(event.target).hasClass('w2ui-list-remove')) { - if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; - // trigger event - var edata = obj.trigger({ phase: 'before', type: 'remove', target: obj.el, originalEvent: event.originalEvent, item: item }); - if (edata.isCancelled === true) return; - // default behavior - $().w2overlay(); - selected.splice($(event.target).attr('index'), 1); - $(obj.el).trigger('change'); - $(event.target).parent().fadeOut('fast'); - setTimeout(function () { - obj.refresh(); - // event after - obj.trigger($.extend(edata, { phase: 'after' })); - }, 300); - } else { - // trigger event - var edata = obj.trigger({ phase: 'before', type: 'click', target: obj.el, originalEvent: event.originalEvent, item: item }); - if (edata.isCancelled === true) return; - // if file - show image preview - if (obj.type == 'file') { - var preview = ''; - if ((/image/i).test(item.type)) { // image - preview = '
    '+ - ' '+ - '
    '; - } - var td1 = 'style="padding: 3px; text-align: right; color: #777;"'; - var td2 = 'style="padding: 3px"'; - preview += '
    '+ - ' '+ - ' '+ - ' '+ - ' '+ - ' '+ - '
    '+ w2utils.lang('Name') +':'+ item.name +'
    '+ w2utils.lang('Size') +':'+ w2utils.formatSize(item.size) +'
    '+ w2utils.lang('Type') +':' + - ' '+ item.type +''+ - '
    '+ w2utils.lang('Modified') +':'+ w2utils.date(item.modified) +'
    '+ - '
    '; - $('#w2ui-overlay').remove(); - $(target).w2overlay(preview); - } // event after - obj.trigger($.extend(edata, { phase: 'after' })); - } - }) - .on('mouseover', function (event) { - var target = (event.target.tagName.toUpperCase() == 'LI' ? event.target : $(event.target).parents('LI')); - if ($(target).hasClass('nomouse')) return; - if ($(target).data('mouse') == 'out') { - var item = selected[$(event.target).attr('index')]; - // trigger event - var edata = obj.trigger({ phase: 'before', type: 'mouseOver', target: obj.el, originalEvent: event.originalEvent, item: item }); - if (edata.isCancelled === true) return; - // event after - obj.trigger($.extend(edata, { phase: 'after' })); - } - $(target).data('mouse', 'over'); - }) - .on('mouseout', function (event) { - var target = (event.target.tagName.toUpperCase() == 'LI' ? event.target : $(event.target).parents('LI')); - if ($(target).hasClass('nomouse')) return; - $(target).data('mouse', 'leaving'); - setTimeout(function () { - if ($(target).data('mouse') == 'leaving') { - $(target).data('mouse', 'out'); - var item = selected[$(event.target).attr('index')]; - // trigger event - var edata = obj.trigger({ phase: 'before', type: 'mouseOut', target: obj.el, originalEvent: event.originalEvent, item: item }); - if (edata.isCancelled === true) return; - // event after - obj.trigger($.extend(edata, { phase: 'after' })); - } - }, 0); - }); - // adjust height - $(this.el).height('auto'); - var cntHeight = $(div).find('> div.w2ui-multi-items').height() + w2utils.getSize(div, '+height') * 2; - if (cntHeight < 26) cntHeight = 26; - if (cntHeight > options.maxHeight) cntHeight = options.maxHeight; - if (div.length > 0) div[0].scrollTop = 1000; - var inpHeight = w2utils.getSize($(this.el), 'height') - 2; - if (inpHeight > cntHeight) cntHeight = inpHeight; - $(div).css({ 'height': cntHeight + 'px', overflow: (cntHeight == options.maxHeight ? 'auto' : 'hidden') }); - if (cntHeight < options.maxHeight) $(div).prop('scrollTop', 0); - $(this.el).css({ 'height' : (cntHeight + 2) + 'px' }); - // update size - if (obj.type == 'enum') { - var tmp = obj.helpers.multi.find('input'); - tmp.width(((tmp.val().length + 2) * 8) + 'px'); - } - } - return (new Date()).getTime() - time; - }, - - reset: function () { - var obj = this; - var type = this.type; - this.clear(); - this.type = type; - this.init(); - }, - - // resizing width of list, enum, file controls - resize: function () { - var obj = this; - var new_width = $(obj.el).width(); - var new_height = $(obj.el).height(); - if (obj.tmp.current_width == new_width && new_height > 0) return; - - var focus = this.helpers.focus; - var multi = this.helpers.multi; - var suffix = this.helpers.suffix; - var prefix = this.helpers.prefix; - - // resize helpers - if (focus) { - focus.width($(obj.el).width()); - } - if (multi) { - var width = (w2utils.getSize(obj.el, 'width') - - parseInt($(obj.el).css('margin-left'), 10) - - parseInt($(obj.el).css('margin-right'), 10)); - $(multi).width(width); - } - if (suffix) { - obj.options.suffix = '
    '; - obj.addSuffix(); - } - if (prefix) { - obj.addPrefix(); - } - // remember width - obj.tmp.current_width = new_width; - }, - - clean: function (val) { - //issue #499 - if(typeof val == 'number'){ - return val; - } - var options = this.options; - val = String(val).trim(); - // clean - if (['int', 'float', 'money', 'currency', 'percent'].indexOf(this.type) != -1) { - if (typeof val == 'string') { - if (options.autoFormat && ['money', 'currency'].indexOf(this.type) != -1) val = String(val).replace(options.moneyRE, ''); - if (options.autoFormat && this.type == 'percent') val = String(val).replace(options.percentRE, ''); - if (options.autoFormat && ['int', 'float'].indexOf(this.type) != -1) val = String(val).replace(options.numberRE, ''); - val = val.replace(/\s+/g, '').replace(w2utils.settings.groupSymbol, '').replace(w2utils.settings.decimalSymbol, '.'); - } - if (parseFloat(val) == val) { - if (options.min != null && val < options.min) { val = options.min; $(this.el).val(options.min); } - if (options.max != null && val > options.max) { val = options.max; $(this.el).val(options.max); } - } - if (val !== '' && w2utils.isFloat(val)) val = Number(val); else val = ''; - } - return val; - }, - - format: function (val) { - var options = this.options; - // autoformat numbers or money - if (options.autoFormat && val != '') { - switch (this.type) { - case 'money': - case 'currency': - val = w2utils.formatNumber(val, options.currencyPrecision, options.groupSymbol); - if (val != '') val = options.currencyPrefix + val + options.currencySuffix; - break; - case 'percent': - val = w2utils.formatNumber(val, options.precision, options.groupSymbol); - if (val != '') val += '%'; - break; - case 'float': - val = w2utils.formatNumber(val, options.precision, options.groupSymbol); - break; - case 'int': - val = w2utils.formatNumber(val, 0, options.groupSymbol); - break; - } - } - return val; - }, - - change: function (event) { - var obj = this; - var options = obj.options; - // numeric - if (['int', 'float', 'money', 'currency', 'percent'].indexOf(this.type) != -1) { - // check max/min - var val = $(this.el).val(); - var new_val = this.format(this.clean($(this.el).val())); - // if was modified - if (val != '' && val != new_val) { - $(this.el).val(new_val).change(); - // cancel event - event.stopPropagation(); - event.preventDefault(); - return false; - } - } - // color - if (this.type == 'color') { - var color = '#' + $(this.el).val(); - if ($(this.el).val().length != 6 && $(this.el).val().length != 3) color = ''; - $(this.el).next().find('div').css('background-color', color); - if ($(obj.el).is(':focus')) this.updateOverlay(); - } - // list, enum - if (['list', 'enum', 'file'].indexOf(this.type) != -1) { - obj.refresh(); - // need time out to show icon indent properly - setTimeout(function () { obj.refresh(); }, 5); - } - // date, time - if (['date', 'time', 'datetime'].indexOf(this.type) != -1) { - // convert linux timestamps - var tmp = parseInt(obj.el.value); - if (w2utils.isInt(obj.el.value) && tmp > 3000) { - if (this.type == 'time') $(obj.el).val(w2utils.formatTime(new Date(tmp), options.format)).change(); - if (this.type == 'date') $(obj.el).val(w2utils.formatDate(new Date(tmp), options.format)).change(); - if (this.type == 'datetime') $(obj.el).val(w2utils.formatDateTime(new Date(tmp), options.format)).change(); - } - } - }, - - click: function (event) { - event.stopPropagation(); - // lists - if (['list', 'combo', 'enum'].indexOf(this.type) != -1) { - if (!$(this.el).is(':focus')) this.focus(event); - } - // other fields with drops - if (['date', 'time', 'color', 'datetime'].indexOf(this.type) != -1) { - this.updateOverlay(); - } - }, - - focus: function (event) { - var obj = this; - var options = this.options; - // color, date, time - if (['color', 'date', 'time', 'datetime'].indexOf(obj.type) !== -1) { - if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; - if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); - setTimeout(function () { obj.updateOverlay(); }, 150); - } - // menu - if (['list', 'combo', 'enum'].indexOf(obj.type) != -1) { - if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; - if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); - obj.resize(); - setTimeout(function () { - if (obj.type == 'list' && $(obj.el).is(':focus')) { - $(obj.helpers.focus).find('input').focus(); - return; - } - obj.search(); - setTimeout(function () { obj.updateOverlay(); }, 1); - }, 1); - } - // file - if (obj.type == 'file') { - $(obj.helpers.multi).css({ 'outline': 'auto 5px #7DB4F3', 'outline-offset': '-2px' }); - } - }, - - blur: function (event) { - var obj = this; - var options = obj.options; - var val = $(obj.el).val().trim(); - // hide overlay - if (['color', 'date', 'time', 'list', 'combo', 'enum', 'datetime'].indexOf(obj.type) != -1) { - if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); - } - if (['int', 'float', 'money', 'currency', 'percent'].indexOf(obj.type) != -1) { - if (val !== '' && !obj.checkType(val)) { - $(obj.el).val('').change(); - if (options.silent === false) { - $(obj.el).w2tag('Not a valid number'); - setTimeout(function () { $(obj.el).w2tag(''); }, 3000); - } - } - } - // date or time - if (['date', 'time', 'datetime'].indexOf(obj.type) != -1) { - // check if in range - if (val !== '' && !obj.inRange(obj.el.value)) { - $(obj.el).val('').removeData('selected').change(); - if (options.silent === false) { - $(obj.el).w2tag('Not in range'); - setTimeout(function () { $(obj.el).w2tag(''); }, 3000); - } - } else { - if (obj.type == 'date' && val !== '' && !w2utils.isDate(obj.el.value, options.format)) { - $(obj.el).val('').removeData('selected').change(); - if (options.silent === false) { - $(obj.el).w2tag('Not a valid date'); - setTimeout(function () { $(obj.el).w2tag(''); }, 3000); - } - } - else if (obj.type == 'time' && val !== '' && !w2utils.isTime(obj.el.value)) { - $(obj.el).val('').removeData('selected').change(); - if (options.silent === false) { - $(obj.el).w2tag('Not a valid time'); - setTimeout(function () { $(obj.el).w2tag(''); }, 3000); - } - } - else if (obj.type == 'datetime' && val !== '' && !w2utils.isDateTime(obj.el.value, options.format)) { - $(obj.el).val('').removeData('selected').change(); - if (options.silent === false) { - $(obj.el).w2tag('Not a valid date'); - setTimeout(function () { $(obj.el).w2tag(''); }, 3000); - } - } - } - } - // clear search input - if (obj.type == 'enum') { - $(obj.helpers.multi).find('input').val('').width(20); - } - // file - if (obj.type == 'file') { - $(obj.helpers.multi).css({ 'outline': 'none' }); - } - }, - - keyPress: function (event) { - var obj = this; - var options = obj.options; - // ignore wrong pressed key - if (['int', 'float', 'money', 'currency', 'percent', 'hex', 'bin', 'color', 'alphanumeric'].indexOf(obj.type) != -1) { - // keyCode & charCode differ in FireFox - if (event.metaKey || event.ctrlKey || event.altKey || (event.charCode != event.keyCode && event.keyCode > 0)) return; - var ch = String.fromCharCode(event.charCode); - if (!obj.checkType(ch, true) && event.keyCode != 13) { - event.preventDefault(); - if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; - return false; - } - } - // update date popup - if (['date', 'time', 'datetime'].indexOf(obj.type) != -1) { - if (event.keyCode !== 9) setTimeout(function () { obj.updateOverlay(); }, 1); - } - }, - - keyDown: function (event, extra) { - var obj = this; - var options = obj.options; - var key = event.keyCode || (extra && extra.keyCode); - // numeric - if (['int', 'float', 'money', 'currency', 'percent'].indexOf(obj.type) != -1) { - if (!options.keyboard || $(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; - var cancel = false; - var val = parseFloat($(obj.el).val().replace(options.moneyRE, '')) || 0; - var inc = options.step; - if (event.ctrlKey || event.metaKey) inc = 10; - switch (key) { - case 38: // up - if (event.shiftKey) break; // no action if shift key is pressed - $(obj.el).val((val + inc <= options.max || options.max == null ? Number((val + inc).toFixed(12)) : options.max)).change(); - cancel = true; - break; - case 40: // down - if (event.shiftKey) break; // no action if shift key is pressed - $(obj.el).val((val - inc >= options.min || options.min == null ? Number((val - inc).toFixed(12)) : options.min)).change(); - cancel = true; - break; - } - if (cancel) { - event.preventDefault(); - setTimeout(function () { - // set cursor to the end - obj.el.setSelectionRange(obj.el.value.length, obj.el.value.length); - }, 0); - } - } - // date - if (obj.type == 'date') { - if (!options.keyboard || $(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; - var cancel = false; - var daymil = 24*60*60*1000; - var inc = 1; - if (event.ctrlKey || event.metaKey) inc = 10; - var dt = w2utils.isDate($(obj.el).val(), options.format, true); - if (!dt) { dt = new Date(); daymil = 0; } - switch (key) { - case 38: // up - if (event.shiftKey) break; // no action if shift key is pressed - var newDT = w2utils.formatDate(dt.getTime() + daymil, options.format); - if (inc == 10) newDT = w2utils.formatDate(new Date(dt.getFullYear(), dt.getMonth()+1, dt.getDate()), options.format); - $(obj.el).val(newDT).change(); - cancel = true; - break; - case 40: // down - if (event.shiftKey) break; // no action if shift key is pressed - var newDT = w2utils.formatDate(dt.getTime() - daymil, options.format); - if (inc == 10) newDT = w2utils.formatDate(new Date(dt.getFullYear(), dt.getMonth()-1, dt.getDate()), options.format); - $(obj.el).val(newDT).change(); - cancel = true; - break; - } - if (cancel) { - event.preventDefault(); - setTimeout(function () { - // set cursor to the end - obj.el.setSelectionRange(obj.el.value.length, obj.el.value.length); - obj.updateOverlay(); - }, 0); - } - } - // time - if (obj.type == 'time') { - if (!options.keyboard || $(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; - var cancel = false; - var inc = (event.ctrlKey || event.metaKey ? 60 : 1); - var val = $(obj.el).val(); - var time = obj.toMin(val) || obj.toMin((new Date()).getHours() + ':' + ((new Date()).getMinutes() - 1)); - switch (key) { - case 38: // up - if (event.shiftKey) break; // no action if shift key is pressed - time += inc; - cancel = true; - break; - case 40: // down - if (event.shiftKey) break; // no action if shift key is pressed - time -= inc; - cancel = true; - break; - } - if (cancel) { - $(obj.el).val(obj.fromMin(time)).change(); - event.preventDefault(); - setTimeout(function () { - // set cursor to the end - obj.el.setSelectionRange(obj.el.value.length, obj.el.value.length); - }, 0); - } - } - // datetime - if (obj.type == 'datetime') { - if (!options.keyboard || $(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; - var cancel = false; - var daymil = 24*60*60*1000; - var inc = 1; - if (event.ctrlKey || event.metaKey) inc = 10; - var str = $(obj.el).val(); - var dt = w2utils.isDateTime(str, this.options.format, true); - if (!dt) { dt = new Date(); daymil = 0; } - switch (key) { - case 38: // up - if (event.shiftKey) break; // no action if shift key is pressed - var newDT = w2utils.formatDateTime(dt.getTime() + daymil, options.format); - if (inc == 10) newDT = w2utils.formatDateTime(new Date(dt.getFullYear(), dt.getMonth()+1, dt.getDate()), options.format); - $(obj.el).val(newDT).change(); - cancel = true; - break; - case 40: // down - if (event.shiftKey) break; // no action if shift key is pressed - var newDT = w2utils.formatDateTime(dt.getTime() - daymil, options.format); - if (inc == 10) newDT = w2utils.formatDateTime(new Date(dt.getFullYear(), dt.getMonth()-1, dt.getDate()), options.format); - $(obj.el).val(newDT).change(); - cancel = true; - break; - } - if (cancel) { - event.preventDefault(); - setTimeout(function () { - // set cursor to the end - obj.el.setSelectionRange(obj.el.value.length, obj.el.value.length); - obj.updateOverlay(); - }, 0); - } - } - // color - if (obj.type == 'color') { - if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; - // paste - if (event.keyCode == 86 && (event.ctrlKey || event.metaKey)) { - $(obj.el).prop('maxlength', 7); - setTimeout(function () { - var val = $(obj).val(); - if (val.substr(0, 1) == '#') val = val.substr(1); - if (!w2utils.isHex(val)) val = ''; - $(obj).val(val).prop('maxlength', 6).change(); - }, 20); - } - if ((event.ctrlKey || event.metaKey) && !event.shiftKey) { - var dir = null; - var newColor = null; - switch (key) { - case 38: // up - dir = 'up'; - break; - case 40: // down - dir = 'down'; - break; - case 39: // right - dir = 'right'; - break; - case 37: // left - dir = 'left'; - break; - } - if (obj.el.nav && dir != null) { - newColor = obj.el.nav(dir); - $(obj.el).val(newColor).change(); - event.preventDefault(); - } - } - } - // list/select/combo - if (['list', 'combo', 'enum'].indexOf(obj.type) != -1) { - if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; - var selected = $(obj.el).data('selected'); - var focus = $(obj.el); - var indexOnly = false; - if (['list', 'enum'].indexOf(obj.type) != -1) { - if (obj.type == 'list') { - focus = $(obj.helpers.focus).find('input'); - } - if (obj.type == 'enum') { - focus = $(obj.helpers.multi).find('input'); - } - // not arrows - refresh - if ([37, 38, 39, 40].indexOf(key) == -1) { - setTimeout(function () { obj.refresh(); }, 1); - } - // paste - if (event.keyCode == 86 && (event.ctrlKey || event.metaKey)) { - setTimeout(function () { - obj.refresh(); - obj.search(); - obj.request(); - }, 50); - } - } - // apply arrows - switch (key) { - case 27: // escape - if (obj.type == 'list') { - if (focus.val() != '') focus.val(''); - event.stopPropagation(); // escape in field should not close popup - } - break; - case 37: // left - case 39: // right - // indexOnly = true; - break; - case 13: // enter - if ($('#w2ui-overlay').length == 0) break; // no action if overlay not open - var item = options.items[options.index]; - if (obj.type == 'enum') { - if (item != null) { - // trigger event - var edata = obj.trigger({ phase: 'before', type: 'add', target: obj.el, originalEvent: event.originalEvent, item: item }); - if (edata.isCancelled === true) return; - item = edata.item; // need to reassign because it could be recreated by user - // default behavior - if (selected.length >= options.max && options.max > 0) selected.pop(); - delete item.hidden; - delete obj.tmp.force_open; - selected.push(item); - $(obj.el).change(); - focus.val('').width(20); - obj.refresh(); - // event after - obj.trigger($.extend(edata, { phase: 'after' })); - } else { - // trigger event - item = { id: focus.val(), text: focus.val() }; - var edata = obj.trigger({ phase: 'before', type: 'new', target: obj.el, originalEvent: event.originalEvent, item: item }); - if (edata.isCancelled === true) return; - item = edata.item; // need to reassign because it could be recreated by user - // default behavior - if (typeof obj.onNew == 'function') { - if (selected.length >= options.max && options.max > 0) selected.pop(); - delete obj.tmp.force_open; - selected.push(item); - $(obj.el).change(); - focus.val('').width(20); - obj.refresh(); - } - // event after - obj.trigger($.extend(edata, { phase: 'after' })); - } - } else { - if (item) $(obj.el).data('selected', item).val(item.text).change(); - if ($(obj.el).val() == '' && $(obj.el).data('selected')) $(obj.el).removeData('selected').val('').change(); - if (obj.type == 'list') { - focus.val(''); - obj.refresh(); - } - // hide overlay - obj.tmp.force_hide = true; - } - break; - case 8: // backspace - case 46: // delete - if (obj.type == 'enum' && key == 8) { - if (focus.val() == '' && selected.length > 0) { - var item = selected[selected.length - 1]; - // trigger event - var edata = obj.trigger({ phase: 'before', type: 'remove', target: obj.el, originalEvent: event.originalEvent, item: item }); - if (edata.isCancelled === true) return; - // default behavior - selected.pop(); - $(obj.el).trigger('change'); - obj.refresh(); - // event after - obj.trigger($.extend(edata, { phase: 'after' })); - } - } - if (obj.type == 'list' && focus.val() == '') { - $(obj.el).data('selected', {}).change(); - obj.refresh(); - } - break; - case 38: // up - options.index = w2utils.isInt(options.index) ? parseInt(options.index) : 0; - options.index--; - while (options.index > 0 && options.items[options.index].hidden) options.index--; - if (options.index == 0 && options.items[options.index].hidden) { - while (options.items[options.index] && options.items[options.index].hidden) options.index++; - } - indexOnly = true; - break; - case 40: // down - options.index = w2utils.isInt(options.index) ? parseInt(options.index) : -1; - options.index++; - while (options.index < options.items.length-1 && options.items[options.index].hidden) options.index++; - if (options.index == options.items.length-1 && options.items[options.index].hidden) { - while (options.items[options.index] && options.items[options.index].hidden) options.index--; - } - // show overlay if not shown - if (focus.val() == '' && $('#w2ui-overlay').length == 0) { - obj.tmp.force_open = true; - } else { - indexOnly = true; - } - break; - } - if (indexOnly) { - if (options.index < 0) options.index = 0; - if (options.index >= options.items.length) options.index = options.items.length -1; - obj.updateOverlay(indexOnly); - // cancel event - event.preventDefault(); - setTimeout(function () { - // set cursor to the end - if (obj.type == 'enum') { - var tmp = focus.get(0); - tmp.setSelectionRange(tmp.value.length, tmp.value.length); - } else if (obj.type == 'list') { - var tmp = focus.get(0); - tmp.setSelectionRange(tmp.value.length, tmp.value.length); - } else { - obj.el.setSelectionRange(obj.el.value.length, obj.el.value.length); - } - }, 0); - return; - } - // expand input - if (obj.type == 'enum') { - focus.width(((focus.val().length + 2) * 8) + 'px'); - } - } - }, - - keyUp: function (event) { - var obj = this; - if (this.type == 'color') { - if (event.keyCode == 86 && (event.ctrlKey || event.metaKey)) { - $(this).prop('maxlength', 6); - } - } - if (['list', 'combo', 'enum'].indexOf(this.type) != -1) { - if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; - // need to be here for ipad compa - if ([16, 17, 18, 20, 37, 39, 91].indexOf(event.keyCode) == -1) { // no refreah on crtl, shift, left/right arrows, etc - var input = $(this.helpers.focus).find('input'); - if (input.length == 0) input = $(this.el); // for combo list - // trigger event - var edata = this.trigger({ phase: 'before', type: 'search', originalEvent: event, target: input, search: input.val() }); - if (edata.isCancelled === true) return; - // regular - if (!this.tmp.force_hide) this.request(); - if (input.val().length == 1) this.refresh() - if ($('#w2ui-overlay').length == 0 || [38, 40].indexOf(event.keyCode) == -1) { // no search on arrows - this.search(); - } - // event after - this.trigger($.extend(edata, { phase: 'after' })); - } - } - }, - - clearCache: function () { - var options = this.options; - options.items = []; - this.tmp.xhr_loading = false; - this.tmp.xhr_search = ''; - this.tmp.xhr_total = -1; - }, - - request: function (interval) { - var obj = this; - var options = this.options; - var search = $(obj.el).val() || ''; - // if no url - do nothing - if (!options.url) return; - // -- - if (obj.type == 'enum') { - var tmp = $(obj.helpers.multi).find('input'); - if (tmp.length == 0) search = ''; else search = tmp.val(); - } - if (obj.type == 'list') { - var tmp = $(obj.helpers.focus).find('input'); - if (tmp.length == 0) search = ''; else search = tmp.val(); - } - if (options.minLength != 0 && search.length < options.minLength) { - options.items = []; // need to empty the list - this.updateOverlay(); - return; - } - if (interval == null) interval = options.interval; - if (obj.tmp.xhr_search == null) obj.tmp.xhr_search = ''; - if (obj.tmp.xhr_total == null) obj.tmp.xhr_total = -1; - // check if need to search - if (options.url && $(obj.el).prop('readonly') != true && $(obj.el).prop('disabled') != true && ( - (options.items.length === 0 && obj.tmp.xhr_total !== 0) || - (obj.tmp.xhr_total == options.cacheMax && search.length > obj.tmp.xhr_search.length) || - (search.length >= obj.tmp.xhr_search.length && search.substr(0, obj.tmp.xhr_search.length) != obj.tmp.xhr_search) || - (search.length < obj.tmp.xhr_search.length) - )) { - // empty list - if (obj.tmp.xhr) obj.tmp.xhr.abort(); - obj.tmp.xhr_loading = true; - obj.search(); - // timeout - clearTimeout(obj.tmp.timeout); - obj.tmp.timeout = setTimeout(function () { - // trigger event - var url = options.url; - var postData = { - search : search, - max : options.cacheMax - }; - $.extend(postData, options.postData); - var edata = obj.trigger({ phase: 'before', type: 'request', target: obj.el, url: url, postData: postData }); - if (edata.isCancelled === true) return; - url = edata.url; - postData = edata.postData; - var ajaxOptions = { - type : 'GET', - url : url, - data : postData, - dataType : 'JSON' // expected from server - }; - if (options.method) ajaxOptions.type = options.method; - if (w2utils.settings.dataType == 'JSON') { - ajaxOptions.type = 'POST'; - ajaxOptions.data = JSON.stringify(ajaxOptions.data); - ajaxOptions.contentType = 'application/json'; - } - if (w2utils.settings.dataType == 'HTTPJSON') { - ajaxOptions.data = { request: JSON.stringify(ajaxOptions.data) }; - } - if (options.method != null) ajaxOptions.type = options.method; - obj.tmp.xhr = $.ajax(ajaxOptions) - .done(function (data, status, xhr) { - // trigger event - var edata2 = obj.trigger({ phase: 'before', type: 'load', target: obj.el, search: postData.search, data: data, xhr: xhr }); - if (edata2.isCancelled === true) return; - // default behavior - data = edata2.data; - if (typeof data == 'string') data = JSON.parse(data); - if (data.records == null && data.items != null) { - // needed for backward compatibility - data.records = data.items; - delete data.items; - } - if (data.status != 'success' || !Array.isArray(data.records)) { - console.log('ERROR: server did not return proper structure. It should return', { status: 'success', records: [{ id: 1, text: 'item' }] }); - return; - } - // remove all extra items if more then needed for cache - if (data.records.length > options.cacheMax) data.records.splice(options.cacheMax, 100000); - // map id and text - if (options.recId == null && options.recid != null) options.recId = options.recid; // since lower-case recid is used in grid - if (options.recId || options.recText) { - data.records.forEach(function (item) { - if (typeof options.recId == 'string') item.id = item[options.recId]; - if (typeof options.recId == 'function') item.id = options.recId(item); - if (typeof options.recText == 'string') item.text = item[options.recText]; - if (typeof options.recText == 'function') item.text = options.recText(item); - }); - } - // remember stats - obj.tmp.xhr_loading = false; - obj.tmp.xhr_search = search; - obj.tmp.xhr_total = data.records.length; - options.items = obj.normMenu(data.records); - if (search == '' && data.records.length == 0) obj.tmp.emptySet = true; else obj.tmp.emptySet = false; - obj.search(); - // event after - obj.trigger($.extend(edata2, { phase: 'after' })); - }) - .fail(function (xhr, status, error) { - // trigger event - var errorObj = { status: status, error: error, rawResponseText: xhr.responseText }; - var edata2 = obj.trigger({ phase: 'before', type: 'error', target: obj.el, search: search, error: errorObj, xhr: xhr }); - if (edata2.isCancelled === true) return; - // default behavior - if (status != 'abort') { - var data; - try { data = $.parseJSON(xhr.responseText); } catch (e) {} - console.log('ERROR: Server communication failed.', - '\n EXPECTED:', { status: 'success', records: [{ id: 1, text: 'item' }] }, - '\n OR:', { status: 'error', message: 'error message' }, - '\n RECEIVED:', typeof data == 'object' ? data : xhr.responseText); - } - // reset stats - obj.clearCache(); - obj.search(); - // event after - obj.trigger($.extend(edata2, { phase: 'after' })); - }); - // event after - obj.trigger($.extend(edata, { phase: 'after' })); - }, interval); - } - }, - - search: function () { - var obj = this; - var options = this.options; - var search = $(obj.el).val(); - var target = obj.el; - var ids = []; - var selected = $(obj.el).data('selected'); - if (obj.type == 'enum') { - target = $(obj.helpers.multi).find('input'); - search = target.val(); - for (var s in selected) { if (selected[s]) ids.push(selected[s].id); } - } - if (obj.type == 'list') { - target = $(obj.helpers.focus).find('input'); - search = target.val(); - for (var s in selected) { if (selected[s]) ids.push(selected[s].id); } - } - if (obj.tmp.xhr_loading !== true) { - var shown = 0; - for (var i = 0; i < options.items.length; i++) { - var item = options.items[i]; - if (options.compare != null) { - if (typeof options.compare == 'function') { - item.hidden = (options.compare.call(this, item, search) === false ? true : false); - } - } else { - var prefix = ''; - var suffix = ''; - if (['is', 'begins'].indexOf(options.match) != -1) prefix = '^'; - if (['is', 'ends'].indexOf(options.match) != -1) suffix = '$'; - try { - var re = new RegExp(prefix + search + suffix, 'i'); - if (re.test(item.text) || item.text == '...') item.hidden = false; else item.hidden = true; - } catch (e) {} - } - if (options.filter === false) item.hidden = false; - // do not show selected items - if (obj.type == 'enum' && $.inArray(item.id, ids) != -1) item.hidden = true; - if (item.hidden !== true) { shown++; delete item.hidden; } - } - // preselect first item - options.index = -1; - while (options.items[options.index] && options.items[options.index].hidden) options.index++; - if (shown <= 0) options.index = -1; - options.spinner = false; - obj.updateOverlay(); - setTimeout(function () { - var html = $('#w2ui-overlay').html() || ''; - if (options.markSearch && html.indexOf('$.fn.w2menuHandler') != -1) { // do not highlight when no items - $('#w2ui-overlay').w2marker(search); - } - }, 1); - } else { - options.items.splice(0, options.cacheMax); - options.spinner = true; - obj.updateOverlay(); - } - }, - - updateOverlay: function (indexOnly) { - var obj = this; - var options = this.options; - // color - if (this.type == 'color') { - if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; - $(this.el).w2color({ color: $(this.el).val(), transparent: options.transparent }, function (color) { - if (color == null) return; - $(obj.el).val(color).change(); - }); - } - // date - if (this.type == 'date') { - if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; - if ($('#w2ui-overlay').length == 0) { - $(obj.el).w2overlay('
    ', { - css: { "background-color": "#f5f5f5" } - }); - } - var month, year; - var dt = w2utils.isDate($(obj.el).val(), obj.options.format, true); - if (dt) { month = dt.getMonth() + 1; year = dt.getFullYear(); } - (function refreshCalendar(month, year) { - $('#w2ui-overlay > div > div').html(obj.getMonthHTML(month, year, $(obj.el).val())); - $('#w2ui-overlay .w2ui-calendar-title') - .on('mousedown', function () { - if ($(this).next().hasClass('w2ui-calendar-jump')) { - $(this).next().remove(); - } else { - var selYear, selMonth; - $(this).after('
    '); - $(this).next().hide().html(obj.getYearHTML()).fadeIn(200); - setTimeout(function () { - $('#w2ui-overlay .w2ui-calendar-jump') - .find('.w2ui-jump-month, .w2ui-jump-year') - .on('click', function () { - if ($(this).hasClass('w2ui-jump-month')) { - $(this).parent().find('.w2ui-jump-month').removeClass('selected'); - $(this).addClass('selected'); - selMonth = $(this).attr('name'); - } - if ($(this).hasClass('w2ui-jump-year')) { - $(this).parent().find('.w2ui-jump-year').removeClass('selected'); - $(this).addClass('selected'); - selYear = $(this).attr('name'); - } - if (selYear != null && selMonth != null) { - $('#w2ui-overlay .w2ui-calendar-jump').fadeOut(100); - setTimeout(function () { refreshCalendar(parseInt(selMonth)+1, selYear); }, 100); - } - }); - $('#w2ui-overlay .w2ui-calendar-jump >:last-child').prop('scrollTop', 2000); - }, 1); - } - }); - $('#w2ui-overlay .w2ui-date') - .on('mousedown', function () { - var day = $(this).attr('date'); - $(obj.el).val(day).change(); - $(this).css({ 'background-color': '#B6D5FB', 'border-color': '#aaa' }); - }) - .on('mouseup', function () { - setTimeout(function () { - if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay').removeData('keepOpen')[0].hide(); - }, 10); - }); - $('#w2ui-overlay .previous').on('mousedown', function () { - var tmp = obj.options.current.split('/'); - tmp[0] = parseInt(tmp[0]) - 1; - refreshCalendar(tmp[0], tmp[1]); - }); - $('#w2ui-overlay .next').on('mousedown', function () { - var tmp = obj.options.current.split('/'); - tmp[0] = parseInt(tmp[0]) + 1; - refreshCalendar(tmp[0], tmp[1]); - }); - }) (month, year); - } - // time - if (this.type == 'time') { - if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; - if ($('#w2ui-overlay').length == 0) { - $(obj.el).w2overlay('
    ', { - css: { "background-color": "#fff" } - }); - } - var h24 = (this.options.format == 'h24'); - $('#w2ui-overlay > div').html(obj.getHourHTML()); - $('#w2ui-overlay .w2ui-time') - .on('mousedown', function (event) { - $(this).css({ 'background-color': '#B6D5FB', 'border-color': '#aaa' }); - var hour = $(this).attr('hour'); - $(obj.el).val((hour > 12 && !h24 ? hour - 12 : hour) + ':00' + (!h24 ? (hour < 12 ? ' am' : ' pm') : '')).change(); - }) - if (this.options.noMinutes == null || this.options.noMinutes === false) { - $('#w2ui-overlay .w2ui-time') - .on('mouseup', function () { - var hour = $(this).attr('hour'); - if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); - $(obj.el).w2overlay('
    ', { css: { "background-color": "#fff" } }); - $('#w2ui-overlay > div').html(obj.getMinHTML(hour)); - $('#w2ui-overlay .w2ui-time') - .on('mousedown', function () { - $(this).css({ 'background-color': '#B6D5FB', 'border-color': '#aaa' }); - var min = $(this).attr('min'); - $(obj.el).val((hour > 12 && !h24 ? hour - 12 : hour) + ':' + (min < 10 ? 0 : '') + min + (!h24 ? (hour < 12 ? ' am' : ' pm') : '')).change(); - }) - .on('mouseup', function () { - setTimeout(function () { if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay').removeData('keepOpen')[0].hide(); }, 10); - }); - }); - } else { - $('#w2ui-overlay .w2ui-time') - .on('mouseup', function () { - setTimeout(function () { if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay').removeData('keepOpen')[0].hide(); }, 10); - }); - } - } - // datetime - if (this.type == 'datetime') { - if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; - // hide overlay if we are in the time selection - if ($("#w2ui-overlay .w2ui-time").length > 0) $('#w2ui-overlay')[0].hide(); - if ($('#w2ui-overlay').length == 0) { - $(obj.el).w2overlay('
    ', { - css: { "background-color": "#f5f5f5" } - }); - } - var month, year; - var dt = w2utils.isDate($(obj.el).val(), obj.options.format, true); - if (dt) { month = dt.getMonth() + 1; year = dt.getFullYear(); } - var selDate = null; - (function refreshCalendar(month, year) { - $('#w2ui-overlay > div > div').html( - obj.getMonthHTML(month, year, $(obj.el).val()) - + (options.btn_now ? '
    '+ w2utils.lang('Current Date & Time') + '
    ' : '') - ); - $('#w2ui-overlay .w2ui-calendar-title') - .on('mousedown', function () { - if ($(this).next().hasClass('w2ui-calendar-jump')) { - $(this).next().remove(); - } else { - var selYear, selMonth; - $(this).after('
    '); - $(this).next().hide().html(obj.getYearHTML()).fadeIn(200); - setTimeout(function () { - $('#w2ui-overlay .w2ui-calendar-jump') - .find('.w2ui-jump-month, .w2ui-jump-year') - .on('click', function () { - if ($(this).hasClass('w2ui-jump-month')) { - $(this).parent().find('.w2ui-jump-month').removeClass('selected'); - $(this).addClass('selected'); - selMonth = $(this).attr('name'); - } - if ($(this).hasClass('w2ui-jump-year')) { - $(this).parent().find('.w2ui-jump-year').removeClass('selected'); - $(this).addClass('selected'); - selYear = $(this).attr('name'); - } - if (selYear != null && selMonth != null) { - $('#w2ui-overlay .w2ui-calendar-jump').fadeOut(100); - setTimeout(function () { refreshCalendar(parseInt(selMonth)+1, selYear); }, 100); - } - }); - $('#w2ui-overlay .w2ui-calendar-jump >:last-child').prop('scrollTop', 2000); - }, 1); - } - }); - $('#w2ui-overlay .w2ui-date') - .on('mousedown', function () { - var day = $(this).attr('date'); - $(obj.el).val(day).change(); - $(this).css({ 'background-color': '#B6D5FB', 'border-color': '#aaa' }); - selDate = new Date($(this).attr('data-date')); - }) - .on('mouseup', function () { - // continue with time picker - var selHour, selMin; - if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); - $(obj.el).w2overlay('
    ', { css: { "background-color": "#fff" } }); - var h24 = (obj.options.format == 'h24'); - $('#w2ui-overlay > div').html(obj.getHourHTML()); - $('#w2ui-overlay .w2ui-time') - .on('mousedown', function (event) { - $(this).css({ 'background-color': '#B6D5FB', 'border-color': '#aaa' }); - selHour = $(this).attr('hour'); - selDate.setHours(selHour); - var txt = w2utils.formatDateTime(selDate, obj.options.format); - $(obj.el).val(txt).change(); - //$(obj.el).val((hour > 12 && !h24 ? hour - 12 : hour) + ':00' + (!h24 ? (hour < 12 ? ' am' : ' pm') : '')).change(); - }); - if (obj.options.noMinutes == null || obj.options.noMinutes === false) { - $('#w2ui-overlay .w2ui-time') - .on('mouseup', function () { - var hour = $(this).attr('hour'); - if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); - $(obj.el).w2overlay('
    ', { css: { "background-color": "#fff" } }); - $('#w2ui-overlay > div').html(obj.getMinHTML(hour)); - $('#w2ui-overlay .w2ui-time') - .on('mousedown', function () { - $(this).css({ 'background-color': '#B6D5FB', 'border-color': '#aaa' }); - selMin = $(this).attr('min'); - selDate.setHours(selHour, selMin); - var txt = w2utils.formatDateTime(selDate, obj.options.format); - $(obj.el).val(txt).change(); - //$(obj.el).val((hour > 12 && !h24 ? hour - 12 : hour) + ':' + (min < 10 ? 0 : '') + min + (!h24 ? (hour < 12 ? ' am' : ' pm') : '')).change(); - }) - .on('mouseup', function () { - setTimeout(function () { if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay').removeData('keepOpen')[0].hide(); }, 10); - }); - }); - } else { - $('#w2ui-overlay .w2ui-time') - .on('mouseup', function () { - setTimeout(function () { if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay').removeData('keepOpen')[0].hide(); }, 10); - }); - } - }); - $('#w2ui-overlay .previous').on('mousedown', function () { - var tmp = obj.options.current.split('/'); - tmp[0] = parseInt(tmp[0]) - 1; - refreshCalendar(tmp[0], tmp[1]); - }); - $('#w2ui-overlay .next').on('mousedown', function () { - var tmp = obj.options.current.split('/'); - tmp[0] = parseInt(tmp[0]) + 1; - refreshCalendar(tmp[0], tmp[1]); - }); - // "now" button - $('#w2ui-overlay .now') - .on('mousedown', function () { - // this currently ignores blocked days or start / end dates! - var tmp = w2utils.formatDateTime(new Date(), obj.options.format); - $(obj.el).val(tmp).change(); - return false; - }) - .on('mouseup', function () { - setTimeout(function () { - if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay').removeData('keepOpen')[0].hide(); - }, 10); - }); - }) (month, year); - } - // list - if (['list', 'combo', 'enum'].indexOf(this.type) != -1) { - var el = this.el; - var input = this.el; - if (this.type == 'enum') { - el = $(this.helpers.multi); - input = $(el).find('input'); - } - if (this.type == 'list') { - var sel = $(input).data('selected'); - if ($.isPlainObject(sel) && !$.isEmptyObject(sel) && options.index == -1) { - options.items.forEach(function (item, ind) { - if (item.id == sel.id) { - options.index = ind; - } - }); - } - input = $(this.helpers.focus).find('input'); - } - if ($(input).is(':focus')) { - if (options.openOnFocus === false && $(input).val() == '' && obj.tmp.force_open !== true) { - $().w2overlay(); - return; - } - if (obj.tmp.force_hide) { - $().w2overlay(); - setTimeout(function () { - delete obj.tmp.force_hide; - }, 1); - return; - } - if ($(input).val() != '') delete obj.tmp.force_open; - var msgNoItems = w2utils.lang('No matches'); - if (options.url != null && $(input).val().length < options.minLength && obj.tmp.emptySet !== true) msgNoItems = options.minLength + ' ' + w2utils.lang('letters or more...'); - if (options.url != null && $(input).val() == '' && obj.tmp.emptySet !== true) msgNoItems = w2utils.lang('Type to search...'); - if (options.url == null && options.items.length == 0) msgNoItems = w2utils.lang('Empty list'); - $(el).w2menu((!indexOnly ? 'refresh' : 'refresh-index'), $.extend(true, {}, options, { - search : false, - render : options.renderDrop, - maxHeight : options.maxDropHeight, - maxWidth : options.maxDropWidth, - msgNoItems : msgNoItems, - // selected with mouse - onSelect: function (event) { - if (obj.type == 'enum') { - var selected = $(obj.el).data('selected'); - if (event.item) { - // trigger event - var edata = obj.trigger({ phase: 'before', type: 'add', target: obj.el, originalEvent: event.originalEvent, item: event.item }); - if (edata.isCancelled === true) return; - // default behavior - if (selected.length >= options.max && options.max > 0) selected.pop(); - delete event.item.hidden; - selected.push(event.item); - $(obj.el).data('selected', selected).change(); - $(obj.helpers.multi).find('input').val('').width(20); - obj.refresh(); - if ($("#w2ui-overlay").length > 0) $('#w2ui-overlay')[0].hide(); - // event after - obj.trigger($.extend(edata, { phase: 'after' })); - } - } else { - $(obj.el).data('selected', event.item).val(event.item.text).change(); - if (obj.helpers.focus) obj.helpers.focus.find('input').val(''); - } - } - })); - } - } - }, - - inRange: function (str, onlyDate) { - var inRange = false; - if (this.type == 'date') { - var dt = w2utils.isDate(str, this.options.format, true); - if (dt) { - // enable range - if (this.options.start || this.options.end) { - var st = (typeof this.options.start == 'string' ? this.options.start : $(this.options.start).val()); - var en = (typeof this.options.end == 'string' ? this.options.end : $(this.options.end).val()); - var start = w2utils.isDate(st, this.options.format, true); - var end = w2utils.isDate(en, this.options.format, true); - var current = new Date(dt); - if (!start) start = current; - if (!end) end = current; - if (current >= start && current <= end) inRange = true; - } else { - inRange = true; - } - // block predefined dates - if (this.options.blocked && $.inArray(str, this.options.blocked) != -1) inRange = false; - - /* - clockWeekDay - type: array or integers. every element - number of week day. - number of weekday (1 - monday, 2 - tuesday, 3 - wensday, 4 - thursday, 5 - friday, 6 - saturday, 0 - sunday) - for block in calendar (for example, block all sundays so user can't choose sunday in calendar) - */ - if (this.options.blockWeekDays != null && this.options.blockWeekDays != undefined - && this.options.blockWeekDays.length != undefined){ - var l = this.options.blockWeekDays.length; - for (var i=0; i= tm1 && tm <= tm2) inRange = true; - } else { - inRange = true; - } - } else if (this.type == 'datetime') { - var dt = w2utils.isDateTime(str, this.options.format, true); - if (dt) { - // enable range - if (this.options.start || this.options.end) { - var start, end; - if (typeof this.options.start == 'object' && this.options.start instanceof Date) { - start = this.options.start; - } else { - var st = (typeof this.options.start == 'string' ? this.options.start : $(this.options.start).val()); - if (st.trim() != '') { - start = w2utils.isDateTime(st, this.options.format, true); - } else { - start = ''; - } - } - if (typeof this.options.end == 'object' && this.options.end instanceof Date) { - end = this.options.end; - } else { - var en = (typeof this.options.end == 'string' ? this.options.end : $(this.options.end).val()); - if (en.trim() != '') { - end = w2utils.isDateTime(en, this.options.format, true); - } else { - end = ''; - } - } - var current = dt; // new Date(dt); - if (!start) start = current; - if (!end) end = current; - if (onlyDate && start instanceof Date) { - start.setHours(0); - start.setMinutes(0); - start.setSeconds(0); - } - if (current >= start && current <= end) inRange = true; - } else { - inRange = true; - } - // block predefined dates - if (inRange && this.options.blocked) { - for (var i=0; i'+ - obj.options.prefix + - '' - ); - helper = $(obj.el).prev(); - helper - .css({ - 'color' : $(obj.el).css('color'), - 'font-family' : $(obj.el).css('font-family'), - 'font-size' : $(obj.el).css('font-size'), - 'padding-top' : $(obj.el).css('padding-top'), - 'padding-bottom' : $(obj.el).css('padding-bottom'), - 'padding-left' : $(obj.el).css('padding-left'), - 'padding-right' : 0, - 'margin-top' : (parseInt($(obj.el).css('margin-top'), 10) + 2) + 'px', - 'margin-bottom' : (parseInt($(obj.el).css('margin-bottom'), 10) + 1) + 'px', - 'margin-left' : $(obj.el).css('margin-left'), - 'margin-right' : 0 - }) - .on('click', function (event) { - if (obj.options.icon && typeof obj.onIconClick == 'function') { - // event before - var edata = obj.trigger({ phase: 'before', type: 'iconClick', target: obj.el, el: $(this).find('span.w2ui-icon')[0] }); - if (edata.isCancelled === true) return; - - // intentionally empty - - // event after - obj.trigger($.extend(edata, { phase: 'after' })); - } else { - if (obj.type == 'list') { - $(obj.helpers.focus).find('input').focus(); - } else { - $(obj.el).focus(); - } - } - }); - $(obj.el).css('padding-left', (helper.width() + parseInt($(obj.el).css('padding-left'), 10)) + 'px'); - // remember helper - obj.helpers.prefix = helper; - } - }, 1); - }, - - addSuffix: function () { - var obj = this; - var helper, pr; - setTimeout(function () { - if (obj.type === 'clear') return; - var tmp = $(obj.el).data('tmp') || {}; - if (tmp['old-padding-right']) $(obj.el).css('padding-right', tmp['old-padding-right']); - tmp['old-padding-right'] = $(obj.el).css('padding-right'); - $(obj.el).data('tmp', tmp); - pr = parseInt($(obj.el).css('padding-right'), 10); - if (obj.options.arrows) { - // remove if already displayed - if (obj.helpers.arrows) $(obj.helpers.arrows).remove(); - // add fresh - $(obj.el).after( - '
     '+ - '
    '+ - '
    '+ - '
    '+ - '
    '+ - '
    '+ - '
    '+ - '
    '); - var height = w2utils.getSize(obj.el, 'height'); - helper = $(obj.el).next(); - helper.css({ - 'color' : $(obj.el).css('color'), - 'font-family' : $(obj.el).css('font-family'), - 'font-size' : $(obj.el).css('font-size'), - 'height' : ($(obj.el).height() + parseInt($(obj.el).css('padding-top'), 10) + parseInt($(obj.el).css('padding-bottom'), 10) ) + 'px', - 'padding' : 0, - 'margin-top' : (parseInt($(obj.el).css('margin-top'), 10) + 1) + 'px', - 'margin-bottom' : 0, - 'border-left' : '1px solid silver' - }) - .css('margin-left', '-'+ (helper.width() + parseInt($(obj.el).css('margin-right'), 10) + 12) + 'px') - .on('mousedown', function (event) { - var body = $('body'); - body.on('mouseup', tmp); - body.data('_field_update_timer', setTimeout(update, 700)); - update(false); - // timer function - function tmp() { - clearTimeout(body.data('_field_update_timer')); - body.off('mouseup', tmp); - } - // update function - function update(notimer) { - $(obj.el).focus(); - obj.keyDown($.Event("keydown"), { - keyCode : ($(event.target).attr('type') == 'up' ? 38 : 40) - }); - if (notimer !== false) $('body').data('_field_update_timer', setTimeout(update, 60)); - } - }); - pr += helper.width() + 12; - $(obj.el).css('padding-right', pr + 'px'); - // remember helper - obj.helpers.arrows = helper; - } - if (obj.options.suffix !== '') { - // remove if already displayed - if (obj.helpers.suffix) $(obj.helpers.suffix).remove(); - // add fresh - $(obj.el).after( - '
    '+ - obj.options.suffix + - '
    '); - helper = $(obj.el).next(); - helper - .css({ - 'color' : $(obj.el).css('color'), - 'font-family' : $(obj.el).css('font-family'), - 'font-size' : $(obj.el).css('font-size'), - 'padding-top' : $(obj.el).css('padding-top'), - 'padding-bottom' : $(obj.el).css('padding-bottom'), - 'padding-left' : '3px', - 'padding-right' : $(obj.el).css('padding-right'), - 'margin-top' : (parseInt($(obj.el).css('margin-top'), 10) + 2) + 'px', - 'margin-bottom' : (parseInt($(obj.el).css('margin-bottom'), 10) + 1) + 'px' - }) - .on('click', function (event) { - if (obj.type == 'list') { - $(obj.helpers.focus).find('input').focus(); - } else { - $(obj.el).focus(); - } - }); - - helper.css('margin-left', '-'+ (w2utils.getSize(helper, 'width') + parseInt($(obj.el).css('margin-right'), 10) + 2) + 'px'); - pr += helper.width() + 3; - $(obj.el).css('padding-right', pr + 'px'); - // remember helper - obj.helpers.suffix = helper; - } - }, 1); - }, - - addFocus: function () { - var obj = this; - var options = this.options; - var width = 0; // 11 - show search icon, 0 do not show - var pholder; - // clean up & init - $(obj.helpers.focus).remove(); - // remember original tabindex - var tabIndex = $(obj.el).attr('tabIndex'); - if (tabIndex && tabIndex != -1) obj.el._tabIndex = tabIndex; - if (obj.el._tabIndex) tabIndex = obj.el._tabIndex; - // build helper - var html = - '
    '+ - ' '+ - ' '+ - '
    '; - $(obj.el).attr('tabindex', -1).before(html); - var helper = $(obj.el).prev(); - obj.helpers.focus = helper; - helper.css({ - width : $(obj.el).width(), - "margin-top" : $(obj.el).css('margin-top'), - "margin-left" : (parseInt($(obj.el).css('margin-left')) + parseInt($(obj.el).css('padding-left'))) + 'px', - "margin-bottom" : $(obj.el).css('margin-bottom'), - "margin-right" : $(obj.el).css('margin-right') - }) - .find('input') - .css({ - cursor : 'default', - width : '100%', - outline : 'none', - opacity : 1, - margin : 0, - border : '1px solid transparent', - padding : $(obj.el).css('padding-top'), - "padding-left" : 0, - "margin-left" : (width > 0 ? width + 6 : 0), - "background-color" : 'transparent' - }); - // INPUT events - helper.find('input') - .on('click', function (event) { - if ($('#w2ui-overlay').length == 0) obj.focus(event); - event.stopPropagation(); - }) - .on('focus', function (event) { - pholder = $(obj.el).attr('placeholder'); - $(obj.el).css({ 'outline': 'auto 5px #7DB4F3', 'outline-offset': '-2px' }); - $(this).val(''); - $(obj.el).triggerHandler('focus'); - if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; - }) - .on('blur', function (event) { - $(obj.el).css('outline', 'none'); - $(this).val(''); - obj.refresh(); - $(obj.el).triggerHandler('blur'); - if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; - if (pholder != null) $(obj.el).attr('placeholder', pholder); - }) - .on('keydown', function (event) { - var el = this; - obj.keyDown(event); - setTimeout(function () { - if (el.value == '') $(obj.el).attr('placeholder', pholder); else $(obj.el).attr('placeholder', ''); - }, 10); - }) - .on('keyup', function (event) { obj.keyUp(event); }) - .on('keypress', function (event) { obj.keyPress(event); }); - // MAIN div - helper.on('click', function (event) { $(this).find('input').focus(); }); - obj.refresh(); - }, - - addMulti: function () { - var obj = this; - var options = this.options; - // clean up & init - $(obj.helpers.multi).remove(); - // build helper - var html = ''; - var margin = - 'margin-top : 0px; ' + - 'margin-bottom : 0px; ' + - 'margin-left : ' + $(obj.el).css('margin-left') + '; ' + - 'margin-right : ' + $(obj.el).css('margin-right') + '; '+ - 'width : ' + (w2utils.getSize(obj.el, 'width') - - parseInt($(obj.el).css('margin-left'), 10) - - parseInt($(obj.el).css('margin-right'), 10)) - + 'px;'; - if (obj.type == 'enum') { - html = '
    '+ - '
    '+ - '
      '+ - '
    • '+ - ' '+ - '
    • '+ - '
    '+ - '
    '+ - '
    '; - } - if (obj.type == 'file') { - html = '
    '+ - '
    '+ - ' '+ - '
    '+ - '
    '+ - '
    '+ - '
    '+ - '
    '; - } - // old bg and boder - var tmp = $(obj.el).data('tmp') || {}; - tmp['old-background-color'] = $(obj.el).css('background-color'); - tmp['old-border-color'] = $(obj.el).css('border-color'); - $(obj.el).data('tmp', tmp); - - $(obj.el) - .before(html) - .css({ - 'background-color' : 'transparent', - 'border-color' : 'transparent' - }); - - var div = $(obj.el).prev(); - obj.helpers.multi = div; - if (obj.type == 'enum') { - $(obj.el).attr('tabindex', -1); - // INPUT events - div.find('input') - .on('click', function (event) { - if ($('#w2ui-overlay').length == 0) obj.focus(event); - $(obj.el).triggerHandler('click'); - }) - .on('focus', function (event) { - $(div).css({ 'outline': 'auto 5px #7DB4F3', 'outline-offset': '-2px' }); - $(obj.el).triggerHandler('focus'); - if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; - }) - .on('blur', function (event) { - $(div).css('outline', 'none'); - $(obj.el).triggerHandler('blur'); - if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true; - }) - .on('keyup', function (event) { obj.keyUp(event); }) - .on('keydown', function (event) { obj.keyDown(event); }) - .on('keypress', function (event) { obj.keyPress(event); }); - // MAIN div - div.on('click', function (event) { $(this).find('input').focus(); }); - } - if (obj.type == 'file') { - $(obj.el).css('outline', 'none'); - div.on('click', function (event) { - $(obj.el).focus(); - if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; - obj.blur(event); - obj.resize(); - setTimeout(function () { div.find('input').click(); }, 10); // needed this when clicked on items div - }) - .on('dragenter', function (event) { - if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; - $(div).addClass('w2ui-file-dragover'); - }) - .on('dragleave', function (event) { - if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; - var tmp = $(event.target).parents('.w2ui-field-helper'); - if (tmp.length == 0) $(div).removeClass('w2ui-file-dragover'); - }) - .on('drop', function (event) { - if ($(obj.el).prop('readonly') || $(obj.el).prop('disabled')) return; - $(div).removeClass('w2ui-file-dragover'); - var files = event.originalEvent.dataTransfer.files; - for (var i = 0, l = files.length; i < l; i++) obj.addFile.call(obj, files[i]); - // cancel to stop browser behaviour - event.preventDefault(); - event.stopPropagation(); - }) - .on('dragover', function (event) { - // cancel to stop browser behaviour - event.preventDefault(); - event.stopPropagation(); - }); - div.find('input') - .on('click', function (event) { - event.stopPropagation(); - }) - .on('change', function () { - if (typeof this.files !== "undefined") { - for (var i = 0, l = this.files.length; i < l; i++) { - obj.addFile.call(obj, this.files[i]); - } - } - }); - } - obj.refresh(); - }, - - addFile: function (file) { - var obj = this; - var options = this.options; - var selected = $(obj.el).data('selected'); - var newItem = { - name : file.name, - type : file.type, - modified : file.lastModifiedDate, - size : file.size, - content : null, - file : file - }; - var size = 0; - var cnt = 0; - var err; - if (selected) { - for (var s = 0; s < selected.length; s++) { - // check for dups - if (selected[s].name == file.name && selected[s].size == file.size) return; - size += selected[s].size; - cnt++; - } - } - // trigger event - var edata = obj.trigger({ phase: 'before', type: 'add', target: obj.el, file: newItem, total: cnt, totalSize: size }); - if (edata.isCancelled === true) return; - // check params - if (options.maxFileSize !== 0 && newItem.size > options.maxFileSize) { - err = 'Maximum file size is '+ w2utils.formatSize(options.maxFileSize); - if (options.silent === false) $(obj.el).w2tag(err); - console.log('ERROR: '+ err); - return; - } - if (options.maxSize !== 0 && size + newItem.size > options.maxSize) { - err = 'Maximum total size is '+ w2utils.formatSize(options.maxSize); - if (options.silent === false) $(obj.el).w2tag(err); - console.log('ERROR: '+ err); - return; - } - if (options.max !== 0 && cnt >= options.max) { - err = 'Maximum number of files is '+ options.max; - if (options.silent === false) $(obj.el).w2tag(err); - console.log('ERROR: '+ err); - return; - } - selected.push(newItem); - // read file as base64 - if (typeof FileReader !== "undefined" && options.readContent === true) { - var reader = new FileReader(); - // need a closure - reader.onload = (function () { - return function (event) { - var fl = event.target.result; - var ind = fl.indexOf(','); - newItem.content = fl.substr(ind+1); - obj.refresh(); - $(obj.el).trigger('change'); - // event after - obj.trigger($.extend(edata, { phase: 'after' })); - }; - })(); - reader.readAsDataURL(file); - } else { - obj.refresh(); - $(obj.el).trigger('change'); - } - }, - - normMenu: function (menu) { - if ($.isArray(menu)) { - for (var m = 0; m < menu.length; m++) { - if (typeof menu[m] == 'string') { - menu[m] = { id: menu[m], text: menu[m] }; - } else { - if (menu[m].text != null && menu[m].id == null) menu[m].id = menu[m].text; - if (menu[m].text == null && menu[m].id != null) menu[m].text = menu[m].id; - if (menu[m].caption != null) menu[m].text = menu[m].caption; - } - } - return menu; - } else if (typeof menu == 'function') { - return this.normMenu(menu()); - } else if (typeof menu == 'object') { - var tmp = []; - for (var m in menu) tmp.push({ id: m, text: menu[m] }); - return tmp; - } - }, - - getMonthHTML: function (month, year, selected) { - var td = new Date(); - var months = w2utils.settings.fullmonths; - var daysCount = ['31', '28', '31', '30', '31', '30', '31', '31', '30', '31', '30', '31']; - var today = td.getFullYear() + '/' + (Number(td.getMonth()) + 1) + '/' + td.getDate(); - var days = w2utils.settings.fulldays.slice(); // creates copy of the array - var sdays = w2utils.settings.shortdays.slice(); // creates copy of the array - if (w2utils.settings.weekStarts != 'M') { - days.unshift(days.pop()); - sdays.unshift(sdays.pop()); - } - var options = this.options; - if (options == null) options = {}; - // normalize date - year = w2utils.isInt(year) ? parseInt(year) : td.getFullYear(); - month = w2utils.isInt(month) ? parseInt(month) : td.getMonth() + 1; - if (month > 12) { month -= 12; year++; } - if (month < 1 || month === 0) { month += 12; year--; } - if (year/4 == Math.floor(year/4)) { daysCount[1] = '29'; } else { daysCount[1] = '28'; } - options.current = month + '/' + year; - - // start with the required date - td = new Date(year, month-1, 1); - var weekDay = td.getDay(); - var dayTitle = ''; - for (var i = 0; i < sdays.length; i++) dayTitle += '' + sdays[i] + ''; - - var html = - '
    '+ - ' '+ - ' '+ - months[month-1] +', '+ year + - '
    '+ - ''+ - ' ' + dayTitle + ''+ - ' '; - - var day = 1; - if (w2utils.settings.weekStarts != 'M') weekDay++; - if(this.type === 'datetime') { - var dt_sel = w2utils.isDateTime(selected, options.format, true); - selected = w2utils.formatDate(dt_sel, w2utils.settings.dateFormat); - } - for (var ci = 1; ci < 43; ci++) { - if (weekDay === 0 && ci == 1) { - for (var ti = 0; ti < 6; ti++) html += ''; - ci += 6; - } else { - if (ci < weekDay || day > daysCount[month-1]) { - html += ''; - if ((ci) % 7 === 0) html += ''; - continue; - } - } - var dt = year + '/' + month + '/' + day; - var DT = new Date(dt); - var className = ''; - if (DT.getDay() == 6) className = ' w2ui-saturday'; - if (DT.getDay() == 0) className = ' w2ui-sunday'; - if (dt == today) className += ' w2ui-today'; - - var dspDay = day; - var col = ''; - var bgcol = ''; - var tmp_dt, tmp_dt_fmt; - if(this.type === 'datetime') { - // var fm = options.format.split('|')[0].trim(); - // tmp_dt = w2utils.formatDate(dt, fm); - tmp_dt = w2utils.formatDateTime(dt, options.format); - tmp_dt_fmt = w2utils.formatDate(dt, w2utils.settings.dateFormat); - } else { - tmp_dt = w2utils.formatDate(dt, options.format); - tmp_dt_fmt = tmp_dt; - } - if (options.colored && options.colored[tmp_dt_fmt] !== undefined) { // if there is predefined colors for dates - var tmp = options.colored[tmp_dt_fmt].split(':'); - bgcol = 'background-color: ' + tmp[0] + ';'; - col = 'color: ' + tmp[1] + ';'; - } - html += ''; - if (ci % 7 === 0 || (weekDay === 0 && ci == 1)) html += ''; - day++; - } - html += '
      
    '+ - dspDay + - '
    '; - return html; - }, - - getYearHTML: function () { - var months = w2utils.settings.shortmonths; - var start_year = w2utils.settings.dateStartYear; - var end_year = w2utils.settings.dateEndYear; - var mhtml = ''; - var yhtml = ''; - for (var m = 0; m < months.length; m++) { - mhtml += '
    '+ months[m] + '
    '; - } - for (var y = start_year; y <= end_year; y++) { - yhtml += '
    '+ y + '
    '; - } - return '
    '+ mhtml +'
    '+ yhtml +'
    '; - }, - - getHourHTML: function () { - var tmp = []; - var options = this.options; - if (options == null) options = { format: w2utils.settings.timeFormat }; - var h24 = (options.format.indexOf('h24') > -1); - for (var a = 0; a < 24; a++) { - var time = (a >= 12 && !h24 ? a - 12 : a) + ':00' + (!h24 ? (a < 12 ? ' am' : ' pm') : ''); - if (a == 12 && !h24) time = '12:00 pm'; - if (!tmp[Math.floor(a/8)]) tmp[Math.floor(a/8)] = ''; - var tm1 = this.fromMin(this.toMin(time)); - var tm2 = this.fromMin(this.toMin(time) + 59); - if (this.type === 'datetime') { - var dt = w2utils.isDateTime(this.el.value, options.format, true); - var fm = options.format.split('|')[0].trim(); - tm1 = w2utils.formatDate(dt, fm) + ' ' + tm1; - tm2 = w2utils.formatDate(dt, fm) + ' ' + tm2; - } - tmp[Math.floor(a/8)] += '
    '+ time +'
    '; - } - var html = - '
    '+ - '
    '+ w2utils.lang('Select Hour') +'
    '+ - '
    '+ - ' ' + - ' ' + - ' ' + - '
    '+ tmp[0] +''+ tmp[1] +''+ tmp[2] +'
    '+ - '
    '; - return html; - }, - - getMinHTML: function (hour) { - if (hour == null) hour = 0; - var options = this.options; - if (options == null) options = { format: w2utils.settings.timeFormat }; - var h24 = (options.format.indexOf('h24') > -1); - var tmp = []; - for (var a = 0; a < 60; a += 5) { - var time = (hour > 12 && !h24 ? hour - 12 : hour) + ':' + (a < 10 ? 0 : '') + a + ' ' + (!h24 ? (hour < 12 ? 'am' : 'pm') : ''); - var tm = time; - var ind = a < 20 ? 0 : (a < 40 ? 1 : 2); - if (!tmp[ind]) tmp[ind] = ''; - if (this.type === 'datetime') { - var dt = w2utils.isDateTime(this.el.value, options.format, true); - var fm = options.format.split('|')[0].trim(); - tm = w2utils.formatDate(dt, fm) + ' ' + tm; - } - tmp[ind] += '
    '+ time +'
    '; - } - var html = - '
    '+ - '
    '+ w2utils.lang('Select Minute') +'
    '+ - '
    '+ - ' ' + - ' ' + - ' ' + - '
    '+ tmp[0] +''+ tmp[1] +''+ tmp[2] +'
    '+ - '
    '; - return html; - }, - - toMin: function (str) { - if (typeof str != 'string') return null; - var tmp = str.split(':'); - if (tmp.length == 2) { - tmp[0] = parseInt(tmp[0]); - tmp[1] = parseInt(tmp[1]); - if (str.indexOf('pm') != -1 && tmp[0] != 12) tmp[0] += 12; - } else { - return null; - } - return tmp[0] * 60 + tmp[1]; - }, - - fromMin: function (time) { - var ret = ''; - if (time >= 24 * 60) time = time % (24 * 60); - if (time < 0) time = 24 * 60 + time; - var hour = Math.floor(time/60); - var min = ((time % 60) < 10 ? '0' : '') + (time % 60); - var options = this.options; - if (options == null) options = { format: w2utils.settings.timeFormat }; - if (options.format.indexOf('h24') != -1) { - ret = hour + ':' + min; - } else { - ret = (hour <= 12 ? hour : hour - 12) + ':' + min + ' ' + (hour >= 12 ? 'pm' : 'am'); - } - return ret; - } - }; - - $.extend(w2field.prototype, w2utils.event); - w2obj.field = w2field; - -}) (jQuery); - -/************************************************************************ -* Library: Web 2.0 UI for jQuery (using prototypical inheritance) -* - Following objects defined -* - w2form - form widget -* - $().w2form - jQuery wrapper -* - Dependencies: jQuery, w2utils, w2fields, w2tabs, w2toolbar -* -* == NICE TO HAVE == -* - include delta on save -* - form should read '; - switch (field.type) { - case 'pass': - case 'password': - input = ''; - break; - case 'checkbox': - input = ''; - break; - case 'radio': - input = ''; - // normalized options - var items = field.options.items ? field.options.items : field.html.items; - if (!$.isArray(items)) items = []; - if (items.length > 0) { - items = w2obj.field.prototype.normMenu(items); - } - // generate - for (var i = 0; i < items.length; i++) { - input += '
    '; - } - break; - case 'select': - input = ''; - break; - case 'textarea': - input = ''; - break; - case 'toggle': - input = '
    '; - break; - case 'html': - case 'custom': - case 'empty': - input = ''; - break; - - } - if (group != ''){ - if(page != field.html.page || column != field.html.column || (field.html.group && (group != field.html.group))){ - pages[page][column] += '\n '; - group = ''; - } - } - if (field.html.group && (group != field.html.group)) { - html += '\n
    '+ field.html.group + '
    \n
    '; - group = field.html.group; - } - html += '\n
    '+ - '\n '+ - '\n
    '+ input + w2utils.lang(field.html.text) + '
    '+ - '\n
    '; - if (pages[field.html.page] == null) pages[field.html.page] = []; - if (pages[field.html.page][field.html.column] == null) pages[field.html.page][field.html.column] = ''; - pages[field.html.page][field.html.column] += html; - page = field.html.page; - column = field.html.column; - } - if (group != '') pages[page][column] += '\n
    '; - if (this.tabs.tabs) { - for (var i = 0; i < this.tabs.tabs.length; i++) if (pages[i] == null) pages[i] = []; - } - // buttons if any - var buttons = ''; - if (!$.isEmptyObject(this.actions)) { - var addClass = ''; - buttons += '\n
    '; - for (var a in this.actions) { // it is an object - var act = this.actions[a]; - var info = { caption: '', style: '', "class": '' }; - if ($.isPlainObject(act)) { - if (act.caption) info.caption = act.caption; - if (act.style) info.style = act.style; - if (act["class"]) info['class'] = act['class']; - } else { - info.caption = a; - if (['save', 'update', 'create'].indexOf(a.toLowerCase()) != -1) info['class'] = 'w2ui-btn-blue'; else info['class'] = ''; - } - buttons += '\n '; - } - buttons += '\n
    '; - } - html = ''; - for (var p = 0; p < pages.length; p++){ - html += '
    '; - for (var c = 0; c < pages[p].length; c++){ - html += '
    ' + (pages[p][c] || '') + '\n
    '; - } - html += '\n
    '; - } - html += buttons; - return html; - }, - - action: function (action, event) { - var click = null; - var act = this.actions[action]; - var click = act; - if ($.isPlainObject(act) && act.onClick) click = act.onClick; - // event before - var edata = this.trigger({ phase: 'before', target: action, type: 'action', click: click, originalEvent: event }); - if (edata.isCancelled === true) return; - // default actions - if (typeof click == 'function') click.call(this, event); - // event after - this.trigger($.extend(edata, { phase: 'after' })); - }, - - resize: function () { - var obj = this; - // event before - var edata = this.trigger({ phase: 'before', target: this.name, type: 'resize' }); - if (edata.isCancelled === true) return; - // default behaviour - var main = $(this.box).find('> div.w2ui-form-box'); - var header = $(this.box).find('> div .w2ui-form-header'); - var toolbar = $(this.box).find('> div .w2ui-form-toolbar'); - var tabs = $(this.box).find('> div .w2ui-form-tabs'); - var page = $(this.box).find('> div .w2ui-page'); - var cpage = $(this.box).find('> div .w2ui-page.page-'+ this.page); - var dpage = $(this.box).find('> div .w2ui-page.page-'+ this.page + ' > div'); - var buttons = $(this.box).find('> div .w2ui-buttons'); - // if no height, calculate it - resizeElements(); - if (parseInt($(this.box).height()) == 0 || $(this.box).data('auto-size') === true) { - $(this.box).height( - (header.length > 0 ? w2utils.getSize(header, 'height') : 0) + - ((typeof this.tabs === 'object' && $.isArray(this.tabs.tabs) && this.tabs.tabs.length > 0) ? w2utils.getSize(tabs, 'height') : 0) + - ((typeof this.toolbar == 'object' && $.isArray(this.toolbar.items) && this.toolbar.items.length > 0) ? w2utils.getSize(toolbar, 'height') : 0) + - (page.length > 0 ? w2utils.getSize(dpage, 'height') + w2utils.getSize(cpage, '+height') + 12 : 0) + // why 12 ??? - (buttons.length > 0 ? w2utils.getSize(buttons, 'height') : 0) - ); - $(this.box).data('auto-size', true); - } - resizeElements(); - if (this.toolbar && this.toolbar.resize) this.toolbar.resize(); - if (this.tabs && this.tabs.resize) this.tabs.resize(); - // event after - obj.trigger($.extend(edata, { phase: 'after' })); - - function resizeElements() { - // resize elements - main.width($(obj.box).width()).height($(obj.box).height()); - toolbar.css('top', (obj.header != '' ? w2utils.getSize(header, 'height') : 0)); - tabs.css('top', (obj.header != '' ? w2utils.getSize(header, 'height') : 0) - + ((typeof obj.toolbar == 'object' && $.isArray(obj.toolbar.items) && obj.toolbar.items.length > 0) ? w2utils.getSize(toolbar, 'height') : 0)); - page.css('top', (obj.header != '' ? w2utils.getSize(header, 'height') : 0) - + ((typeof obj.toolbar == 'object' && $.isArray(obj.toolbar.items) && obj.toolbar.items.length > 0) ? w2utils.getSize(toolbar, 'height') + 5 : 0) - + ((typeof obj.tabs === 'object' && $.isArray(obj.tabs.tabs) && obj.tabs.tabs.length > 0) ? w2utils.getSize(tabs, 'height') + 5 : 0)); - page.css('bottom', (buttons.length > 0 ? w2utils.getSize(buttons, 'height') : 0)); - } - }, - - refresh: function (field) { - var time = (new Date()).getTime(); - var obj = this; - if (!this.box) return; - if (!this.isGenerated || $(this.box).html() == null) return; - // event before - var edata = this.trigger({ phase: 'before', target: this.name, type: 'refresh', page: this.page, field: field }) - if (edata.isCancelled === true) return; - if (field != null) { - var from_field = obj.get(field, true); - var to_field = from_field + 1; - } else { - // update what page field belongs - $(this.box).find('input, textarea, select').each(function (index, el) { - var name = ($(el).attr('name') != null ? $(el).attr('name') : $(el).attr('id')); - var field = obj.get(name); - if (field) { - // find page - var div = $(el).parents('.w2ui-page'); - if (div.length > 0) { - for (var i = 0; i < 100; i++) { - if (div.hasClass('page-'+i)) { field.page = i; break; } - } - } - } - }); - // default action - $(this.box).find('.w2ui-page').hide(); - $(this.box).find('.w2ui-page.page-' + this.page).show(); - $(this.box).find('.w2ui-form-header').html(this.header); - // refresh tabs if needed - if (typeof this.tabs === 'object' && $.isArray(this.tabs.tabs) && this.tabs.tabs.length > 0) { - $('#form_'+ this.name +'_tabs').show(); - this.tabs.active = this.tabs.tabs[this.page].id; - this.tabs.refresh(); - } else { - $('#form_'+ this.name +'_tabs').hide(); - } - // refresh tabs if needed - if (typeof this.toolbar == 'object' && $.isArray(this.toolbar.items) && this.toolbar.items.length > 0) { - $('#form_'+ this.name +'_toolbar').show(); - this.toolbar.refresh(); - } else { - $('#form_'+ this.name +'_toolbar').hide(); - } - var from_field = 0; - var to_field = this.fields.length; - } - // refresh values of fields - for (var f = from_field; f < to_field; f++) { - var field = this.fields[f]; - if (field.name == null && field.field != null) field.name = field.field; - if (field.field == null && field.name != null) field.field = field.name; - field.$el = $(this.box).find('[name="'+ String(field.name).replace(/\\/g, '\\\\') +'"]'); - field.el = field.$el[0]; - if (field.el == null) { - console.log('ERROR: Cannot associate field "'+ field.name + '" with html control. Make sure html control exists with the same name.'); - //return; - } - if (field.el) field.el.id = field.name; - var tmp = $(field).data('w2field'); - if (tmp) tmp.clear(); - $(field.$el).off('change').on('change', function () { - var value_new = this.value; - var value_previous = obj.record[this.name] ? obj.record[this.name] : ''; - var field = obj.get(this.name); - if (['list', 'enum', 'file'].indexOf(field.type) != -1 && $(this).data('selected')) { - var nv = $(this).data('selected'); - var cv = obj.record[this.name]; - if ($.isArray(nv)) { - value_new = []; - for (var i = 0; i < nv.length; i++) value_new[i] = $.extend(true, {}, nv[i]); // clone array - } - if ($.isPlainObject(nv)) { - value_new = $.extend(true, {}, nv); // clone object - } - if ($.isArray(cv)) { - value_previous = []; - for (var i = 0; i < cv.length; i++) value_previous[i] = $.extend(true, {}, cv[i]); // clone array - } - if ($.isPlainObject(cv)) { - value_previous = $.extend(true, {}, cv); // clone object - } - } - if (['toggle', 'checkbox'].indexOf(field.type) != -1) { - value_new = ($(this).prop('checked') ? ($(this).prop('value') == 'on' ? true : $(this).prop('value')) : false); - } - // clean extra chars - if (['int', 'float', 'percent', 'money', 'currency'].indexOf(field.type) != -1) { - value_new = $(this).data('w2field').clean(value_new); - } - if (value_new === value_previous) return; - // event before - var edata2 = obj.trigger({ phase: 'before', target: this.name, type: 'change', value_new: value_new, value_previous: value_previous }); - if (edata2.isCancelled === true) { - $(this).val(obj.record[this.name]); // return previous value - return; - } - // default action - var val = this.value; - if (this.type == 'select') val = this.value; - if (this.type == 'checkbox') val = this.checked ? true : false; - if (this.type == 'radio') { - field.$el.each(function (index, el) { - if (el.checked) val = el.value; - }); - } - if (['int', 'float', 'percent', 'money', 'currency', 'list', 'combo', 'enum', 'file', 'toggle'].indexOf(field.type) != -1) { - val = value_new; - } - if (['enum', 'file'].indexOf(field.type) != -1) { - if (val.length > 0) { - var fld = $(field.el).data('w2field').helpers.multi; - $(fld).removeClass('w2ui-error'); - } - } - if (val === '' || val == null || ($.isArray(val) && val.length == 0) || ($.isPlainObject(val) && $.isEmptyObject(val))) { - val = null; - } - obj.record[this.name] = val; - // event after - obj.trigger($.extend(edata2, { phase: 'after' })); - }); - // required - if (field.required) { - $(field.el).parent().parent().addClass('w2ui-required'); - } else { - $(field.el).parent().parent().removeClass('w2ui-required'); - } - // disabled - if (field.disabled != null) { - if (field.disabled) { - $(field.el).prop('readonly', true); - } else { - $(field.el).prop('readonly', false); - } - } - // hidden - if (field.hidden) { - $(field.el).parent().parent().hide(); - } else { - $(field.el).parent().parent().show(); - } - } - // attach actions on buttons - $(this.box).find('button, input[type=button]').each(function (index, el) { - $(el).off('click').on('click', function (event) { - var action = this.value; - if (this.id) action = this.id; - if (this.name) action = this.name; - obj.action(action, event); - }); - }); - // init controls with record - for (var f = from_field; f < to_field; f++) { - var field = this.fields[f]; - var value = (this.record[field.name] != null ? this.record[field.name] : ''); - if (!field.el) continue; - if (!$(field.el).hasClass('w2ui-input')) $(field.el).addClass('w2ui-input'); - field.type = String(field.type).toLowerCase(); - if (!field.options) field.options = {}; - switch (field.type) { - case 'text': - case 'textarea': - case 'email': - case 'pass': - case 'password': - field.el.value = value; - break; - case 'int': - case 'float': - case 'money': - case 'currency': - case 'percent': - // issue #761 - field.el.value = value; - $(field.el).w2field($.extend({}, field.options, { type: field.type })); - break; - case 'hex': - case 'alphanumeric': - case 'color': - case 'date': - case 'time': - field.el.value = value; - $(field.el).w2field($.extend({}, field.options, { type: field.type })); - break; - case 'toggle': - if (w2utils.isFloat(value)) value = parseFloat(value); - $(field.el).prop('checked', (value ? true : false)); - this.record[field.name] = (value ? value : false); - break; - // enums - case 'list': - case 'combo': - if (field.type == 'list') { - var tmp_value = ($.isPlainObject(value) ? value.id : ($.isPlainObject(field.options.selected) ? field.options.selected.id : value)); - // normalized options - if (!field.options.items) field.options.items = []; - var items = field.options.items; - if ($.isArray(items) && items.length > 0 && !$.isPlainObject(items[0])) { - field.options.items = w2obj.field.prototype.normMenu(items); - } - // find value from items - for (var i = 0; i < field.options.items.length; i++) { - var item = field.options.items[i]; - if (item.id == tmp_value) { - value = $.extend(true, {}, item); - obj.record[field.name] = value; - break; - } - } - } else if (field.type == 'combo' && !$.isPlainObject(value)) { - field.el.value = value; - } else if ($.isPlainObject(value) && value.text != null) { - field.el.value = value.text; - } else { - field.el.value = ''; - } - if (!$.isPlainObject(value)) value = {}; - $(field.el).w2field($.extend({}, field.options, { type: field.type, selected: value })); - break; - case 'enum': - case 'file': - if (!$.isArray(value)) value = []; - $(field.el).w2field($.extend({}, field.options, { type: field.type, selected: value })); - break; - - // standard HTML - case 'select': - // generate options - var items = field.options.items; - if (items != null && items.length > 0) { - items = w2obj.field.prototype.normMenu(items); - $(field.el).html(''); - for (var it = 0; it < items.length; it++) { - $(field.el).append('
    ${action}` + }) + text = this.execTemplate(text, actions) + } + let html = ` +
    +
    + ${text} + +
    +
    ` + query(options.where).append(html) + query(options.where).find('#w2ui-notify').find('.w2ui-notify-close') + .on('click', event => { + query(options.where).find('#w2ui-notify').remove() + resolve() + }) + if (options.actions) { + query(options.where).find('#w2ui-notify .w2ui-notify-link') + .on('click', event => { + let value = query(event.target).attr('value') + options.actions[value]() + query(options.where).find('#w2ui-notify').remove() + resolve() + }) + } + if (options.timeout > 0) { + this.tmp.notify_timer = setTimeout(() => { + query(options.where).find('#w2ui-notify').remove() + resolve() + }, options.timeout) + } + } + }) + } + confirm(where, options) { + if (typeof options == 'string') { + options = { text: options } + } + w2utils.normButtons(options, { yes: 'Yes', no: 'No' }) + let prom = w2utils.message(where, options) + if (prom) { + prom.action(event => { + event.detail.self.close() + }) + } + return prom + } + /** + * Normalizes yes, no buttons for confirmation dialog + * + * @param {*} options + * @returns options + */ + normButtons(options, btn) { + options.actions = options.actions ?? {} + let btns = Object.keys(btn) + btns.forEach(name => { + let action = options['btn_' + name] + if (action) { + btn[name] = { + text: w2utils.lang(action.text ?? ''), + class: action.class ?? '', + style: action.style ?? '', + attrs: action.attrs ?? '' + } + delete options['btn_' + name] + } + Array('text', 'class', 'style', 'attrs').forEach(suffix => { + if (options[name + '_' + suffix]) { + if (typeof btn[name] == 'string') { + btn[name] = { text: btn[name] } + } + btn[name][suffix] = options[name + '_' + suffix] + delete options[name + '_' + suffix] + } + }) + }) + if (btns.includes('yes') && btns.includes('no')) { + if (w2utils.settings.macButtonOrder) { + w2utils.extend(options.actions, { no: btn.no, yes: btn.yes }) + } else { + w2utils.extend(options.actions, { yes: btn.yes, no: btn.no }) + } + } + if (btns.includes('ok') && btns.includes('cancel')) { + if (w2utils.settings.macButtonOrder) { + w2utils.extend(options.actions, { cancel: btn.cancel, ok: btn.ok }) + } else { + w2utils.extend(options.actions, { ok: btn.ok, cancel: btn.cancel }) + } + } + return options + } + getSize(el, type) { + el = query(el) // for backward compatibility + let ret = 0 + if (el.length > 0) { + el = el[0] + let styles = getComputedStyle(el) + switch (type) { + case 'width' : + ret = parseFloat(styles.width) + if (styles.width === 'auto') ret = 0 + break + case 'height' : + ret = parseFloat(styles.height) + if (styles.height === 'auto') ret = 0 + break + default: + ret = parseFloat(styles[type] ?? 0) || 0 + break + } + } + return ret + } + getStrWidth(str, styles) { + query('body').append(` +
    + ${this.encodeTags(str)} +
    `) + let width = query('#_tmp_width')[0].clientWidth + query('#_tmp_width').remove() + return width + } + execTemplate(str, replace_obj) { + if (typeof str !== 'string' || !replace_obj || typeof replace_obj !== 'object') { + return str + } + return str.replace(/\${([^}]+)?}/g, function($1, $2) { return replace_obj[$2]||$2 }) + } + marker(el, items, options = { onlyFirst: false, wholeWord: false }) { + if (!Array.isArray(items)) { + if (items != null && items !== '') { + items = [items] + } else { + items = [] + } + } + let ww = options.wholeWord + query(el).each(el => { + clearMerkers(el) + items.forEach(str => { + if (typeof str !== 'string') str = String(str) + let replaceValue = (matched) => { // mark new + return '' + matched + '' + } + // escape regex special chars + str = str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&').replace(/&/g, '&') + .replace(//g, '<') + let regex = new RegExp((ww ? '\\b' : '') + str + (ww ? '\\b' : '')+ '(?!([^<]+)?>)', + 'i' + (!options.onlyFirst ? 'g' : '')) // only outside tags + el.innerHTML = el.innerHTML.replace(regex, replaceValue) + }) + }) + function clearMerkers(el) { + let markerRE = /\((.|\n|\r)*)\<\/span\>/ig + while (el.innerHTML.indexOf('='.includes(phrase)) { + return this.execTemplate(phrase, params) + } + let translation = this.settings.phrases[phrase] + if (translation == null) { + translation = phrase + if (this.settings.warnNoPhrase) { + if (!this.settings.missing) { + this.settings.missing = {} + } + this.settings.missing[phrase] = '---' // collect phrases for translation, warn once + this.settings.phrases[phrase] = '---' + console.log(`Missing translation for "%c${phrase}%c", see %c w2utils.settings.phrases %c with value "---"`, + 'color: orange', '', + 'color: #999', '') + } + } else if (translation === '---' && !this.settings.warnNoPhrase) { + translation = phrase + } + if (translation === '---') { + translation = `---` + } + return this.execTemplate(translation, params) + } + locale(locale, keepPhrases, noMerge) { + return new Promise((resolve, reject) => { + // if locale is an array we call this function recursively and merge the results + if (Array.isArray(locale)) { + this.settings.phrases = {} + let proms = [] + let files = {} + locale.forEach((file, ind) => { + if (file.length === 5) { + file = 'locale/'+ file.toLowerCase() +'.json' + locale[ind] = file + } + proms.push(this.locale(file, true, false)) + }) + Promise.allSettled(proms) + .then(res => { + // order of files is important to merge + res.forEach(r => { if (r.value) files[r.value.file] = r.value.data }) + locale.forEach(file => { + this.settings = this.extend({}, this.settings, files[file]) + }) + resolve() + }) + return + } + if (!locale) locale = 'en-us' + // if locale is an object, then merge it with w2utils.settings + if (locale instanceof Object) { + this.settings = this.extend({}, this.settings, w2locale, locale) + return + } + if (locale.length === 5) { + locale = 'locale/'+ locale.toLowerCase() +'.json' + } + // load from the file + fetch(locale, { method: 'GET' }) + .then(res => res.json()) + .then(data => { + if (noMerge !== true) { + if (keepPhrases) { + // keep phrases, useful for recursive calls + this.settings = this.extend({}, this.settings, data) + } else { + // clear phrases from language before merging + this.settings = this.extend({}, this.settings, w2locale, { phrases: {} }, data) + } + } + resolve({ file: locale, data }) + }) + .catch((err) => { + console.log('ERROR: Cannot load locale '+ locale) + reject(err) + }) + }) + } + scrollBarSize() { + if (this.tmp.scrollBarSize) return this.tmp.scrollBarSize + let html = ` +
    +
    1
    +
    + ` + query('body').append(html) + this.tmp.scrollBarSize = 100 - query('#_scrollbar_width > div')[0].clientWidth + query('#_scrollbar_width').remove() + return this.tmp.scrollBarSize + } + checkName(name) { + if (name == null) { + console.log('ERROR: Property "name" is required but not supplied.') + return false + } + if (w2ui[name] != null) { + console.log(`ERROR: Object named "${name}" is already registered as w2ui.${name}.`) + return false + } + if (!this.isAlphaNumeric(name)) { + console.log('ERROR: Property "name" has to be alpha-numeric (a-z, 0-9, dash and underscore).') + return false + } + return true + } + checkUniqueId(id, items, desc, obj) { + if (!Array.isArray(items)) items = [items] + let isUnique = true + items.forEach(item => { + if (item.id === id) { + console.log(`ERROR: The item id="${id}" is not unique within the ${desc} "${obj}".`, items) + isUnique = false + } + }) + return isUnique + } + /** + * Takes an object and encodes it into params string to be passed as a url + * { a: 1, b: 'str'} => "a=1&b=str" + * { a: 1, b: { c: 2 }} => "a=1&b[c]=2" + * { a: 1, b: {c: { k: 'dfdf' } } } => "a=1&b[c][k]=dfdf" + */ + encodeParams(obj, prefix = '') { + let str = '' + Object.keys(obj).forEach(key => { + if (str != '') str += '&' + if (typeof obj[key] == 'object') { + str += this.encodeParams(obj[key], prefix + key + (prefix ? ']' : '') + '[') + } else { + str += `${prefix}${key}${prefix ? ']' : ''}=${obj[key]}` + } + }) + return str + } + parseRoute(route) { + let keys = [] + let path = route + .replace(/\/\(/g, '(?:/') + .replace(/\+/g, '__plus__') + .replace(/(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?/g, (_, slash, format, key, capture, optional) => { + keys.push({ name: key, optional: !! optional }) + slash = slash || '' + return '' + (optional ? '' : slash) + '(?:' + (optional ? slash : '') + (format || '') + (capture || (format && '([^/.]+?)' || '([^/]+?)')) + ')' + (optional || '') + }) + .replace(/([\/.])/g, '\\$1') + .replace(/__plus__/g, '(.+)') + .replace(/\*/g, '(.*)') + return { + path : new RegExp('^' + path + '$', 'i'), + keys : keys + } + } + getCursorPosition(input) { + if (input == null) return null + let caretOffset = 0 + let doc = input.ownerDocument || input.document + let win = doc.defaultView || doc.parentWindow + let sel + if (['INPUT', 'TEXTAREA'].includes(input.tagName)) { + caretOffset = input.selectionStart + } else { + if (win.getSelection) { + sel = win.getSelection() + if (sel.rangeCount > 0) { + let range = sel.getRangeAt(0) + let preCaretRange = range.cloneRange() + preCaretRange.selectNodeContents(input) + preCaretRange.setEnd(range.endContainer, range.endOffset) + caretOffset = preCaretRange.toString().length + } + } else if ( (sel = doc.selection) && sel.type !== 'Control') { + let textRange = sel.createRange() + let preCaretTextRange = doc.body.createTextRange() + preCaretTextRange.moveToElementText(input) + preCaretTextRange.setEndPoint('EndToEnd', textRange) + caretOffset = preCaretTextRange.text.length + } + } + return caretOffset + } + setCursorPosition(input, pos, posEnd) { + if (input == null) return + let range = document.createRange() + let el, sel = window.getSelection() + if (['INPUT', 'TEXTAREA'].includes(input.tagName)) { + input.setSelectionRange(pos, posEnd ?? pos) + } else { + for (let i = 0; i < input.childNodes.length; i++) { + let tmp = query(input.childNodes[i]).text() + if (input.childNodes[i].tagName) { + tmp = query(input.childNodes[i]).html() + tmp = tmp.replace(/</g, '<') + .replace(/>/g, '>') + .replace(/&/g, '&') + .replace(/"/g, '"') + .replace(/ /g, ' ') + } + if (pos <= tmp.length) { + el = input.childNodes[i] + if (el.childNodes && el.childNodes.length > 0) el = el.childNodes[0] + if (el.childNodes && el.childNodes.length > 0) el = el.childNodes[0] + break + } else { + pos -= tmp.length + } + } + if (el == null) return + if (pos > el.length) pos = el.length + range.setStart(el, pos) + if (posEnd) { + range.setEnd(el, posEnd) + } else { + range.collapse(true) + } + sel.removeAllRanges() + sel.addRange(range) + } + } + parseColor(str) { + if (typeof str !== 'string') return null; else str = str.trim().toUpperCase() + if (str[0] === '#') str = str.substr(1) + let color = {} + if (str.length === 3) { + color = { + r: parseInt(str[0] + str[0], 16), + g: parseInt(str[1] + str[1], 16), + b: parseInt(str[2] + str[2], 16), + a: 1 + } + } else if (str.length === 6) { + color = { + r: parseInt(str.substr(0, 2), 16), + g: parseInt(str.substr(2, 2), 16), + b: parseInt(str.substr(4, 2), 16), + a: 1 + } + } else if (str.length === 8) { + color = { + r: parseInt(str.substr(0, 2), 16), + g: parseInt(str.substr(2, 2), 16), + b: parseInt(str.substr(4, 2), 16), + a: Math.round(parseInt(str.substr(6, 2), 16) / 255 * 100) / 100 // alpha channel 0-1 + } + } else if (str.length > 4 && str.substr(0, 4) === 'RGB(') { + let tmp = str.replace('RGB', '').replace(/\(/g, '').replace(/\)/g, '').split(',') + color = { + r: parseInt(tmp[0], 10), + g: parseInt(tmp[1], 10), + b: parseInt(tmp[2], 10), + a: 1 + } + } else if (str.length > 5 && str.substr(0, 5) === 'RGBA(') { + let tmp = str.replace('RGBA', '').replace(/\(/g, '').replace(/\)/g, '').split(',') + color = { + r: parseInt(tmp[0], 10), + g: parseInt(tmp[1], 10), + b: parseInt(tmp[2], 10), + a: parseFloat(tmp[3]) + } + } else { + // word color + return null + } + return color + } + // h=0..360, s=0..100, v=0..100 + hsv2rgb(h, s, v, a) { + let r, g, b, i, f, p, q, t + if (arguments.length === 1) { + s = h.s; v = h.v; a = h.a; h = h.h + } + h = h / 360 + s = s / 100 + v = v / 100 + i = Math.floor(h * 6) + f = h * 6 - i + p = v * (1 - s) + q = v * (1 - f * s) + t = v * (1 - (1 - f) * s) + switch (i % 6) { + case 0: r = v, g = t, b = p; break + case 1: r = q, g = v, b = p; break + case 2: r = p, g = v, b = t; break + case 3: r = p, g = q, b = v; break + case 4: r = t, g = p, b = v; break + case 5: r = v, g = p, b = q; break + } + return { + r: Math.round(r * 255), + g: Math.round(g * 255), + b: Math.round(b * 255), + a: (a != null ? a : 1) + } + } + // r=0..255, g=0..255, b=0..255 + rgb2hsv(r, g, b, a) { + if (arguments.length === 1) { + g = r.g; b = r.b; a = r.a; r = r.r + } + let max = Math.max(r, g, b), min = Math.min(r, g, b), + d = max - min, + h, + s = (max === 0 ? 0 : d / max), + v = max / 255 + switch (max) { + case min: h = 0; break + case r: h = (g - b) + d * (g < b ? 6: 0); h /= 6 * d; break + case g: h = (b - r) + d * 2; h /= 6 * d; break + case b: h = (r - g) + d * 4; h /= 6 * d; break + } + return { + h: Math.round(h * 360), + s: Math.round(s * 100), + v: Math.round(v * 100), + a: (a != null ? a : 1) + } + } + tooltip(html, options) { + let actions + let showOn = 'mouseenter' + let hideOn = 'mouseleave' + if (typeof html == 'object') { + options = html + } + options = options || {} + if (typeof html == 'string') { + options.html = html + } + if (options.showOn) { + showOn = options.showOn + delete options.showOn + } + if (options.hideOn) { + hideOn = options.hideOn + delete options.hideOn + } + if (!options.name) options.name = 'no-name' + // base64 is needed to avoid '"<> and other special chars conflicts + actions = ` on${showOn}="w2tooltip.show(this, ` + + `JSON.parse(w2utils.base64decode('${this.base64encode(JSON.stringify(options))}')))" ` + + `on${hideOn}="w2tooltip.hide('${options.name}')"` + return actions + } + // determins if it is plain Object, not DOM element, nor a function, event, etc. + isPlainObject(value) { + if (value == null) { // null or undefined + return false + } + if (Object.prototype.toString.call(value) !== '[object Object]') { + return false + } + if (value.constructor === undefined) { + return true + } + let proto = Object.getPrototypeOf(value) + return proto === null || proto === Object.prototype + } + /** + * Deep copy of an object or an array. Function, events and HTML elements will not be cloned, + * you can choose to include them or not, by default they are included. + * You can also exclude certain elements from final object if used with options: { exclude } + */ + clone(obj, options) { + let ret + options = Object.assign({ functions: true, elements: true, events: true, exclude: [] }, options ?? {}) + if (Array.isArray(obj)) { + ret = Array.from(obj) + ret.forEach((value, ind) => { + ret[ind] = this.clone(value, options) + }) + } else if (this.isPlainObject(obj)) { + ret = {} + Object.assign(ret, obj) + if (options.exclude) { + options.exclude.forEach(key => { delete ret[key] }) // delete excluded keys + } + Object.keys(ret).forEach(key => { + ret[key] = this.clone(ret[key], options) + if (ret[key] === undefined) delete ret[key] // do not include undefined elements + }) + } else { + if ((obj instanceof Function && !options.functions) + || (obj instanceof Node && !options.elements) + || (obj instanceof Event && !options.events) + ) { + // do not include these objects, otherwise include them uncloned + } else { + // primitive variable or function, event, dom element, etc, - all these are not cloned + ret = obj + } + } + return ret + } + /** + * Deep extend an object, if an array, it overwrrites it, cloning objects in the process + * target, source1, source2, ... + */ + extend(target, source) { + if (Array.isArray(target)) { + if (Array.isArray(source)) { + target.splice(0, target.length) // empty array but keep the reference + source.forEach(s => { target.push(this.clone(s)) }) + } else { + throw new Error('Arrays can be extended with arrays only') + } + } else if (target instanceof Node || target instanceof Event) { + throw new Error('HTML elmenents and events cannot be extended') + } else if (target && typeof target == 'object' && source != null) { + if (typeof source != 'object') { + throw new Error('Object can be extended with other objects only.') + } + Object.keys(source).forEach(key => { + if (target[key] != null && typeof target[key] == 'object' + && source[key] != null && typeof source[key] == 'object') { + let src = this.clone(source[key]) + // do not extend HTML elements and events, but overwrite them + if (target[key] instanceof Node || target[key] instanceof Event) { + target[key] = src + } else { + // if an array needs to be extended with an object, then convert it to empty object + if (Array.isArray(target[key]) && this.isPlainObject(src)) { + target[key] = {} + } + this.extend(target[key], src) + } + } else { + target[key] = this.clone(source[key]) + } + }) + } else if (source != null) { + throw new Error('Object is not extendable, only {} or [] can be extended.') + } + // other arguments + if (arguments.length > 2) { + for (let i = 2; i < arguments.length; i++) { + this.extend(target, arguments[i]) + } + } + return target + } + /* + * @author Lauri Rooden (https://github.com/litejs/natural-compare-lite) + * @license MIT License + */ + naturalCompare(a, b) { + let i, codeA + , codeB = 1 + , posA = 0 + , posB = 0 + , alphabet = String.alphabet + function getCode(str, pos, code) { + if (code) { + for (i = pos; code = getCode(str, i), code < 76 && code > 65;) ++i + return +str.slice(pos - 1, i) + } + code = alphabet && alphabet.indexOf(str.charAt(pos)) + return code > -1 ? code + 76 : ((code = str.charCodeAt(pos) || 0), code < 45 || code > 127) ? code + : code < 46 ? 65 // - + : code < 48 ? code - 1 + : code < 58 ? code + 18 // 0-9 + : code < 65 ? code - 11 + : code < 91 ? code + 11 // A-Z + : code < 97 ? code - 37 + : code < 123 ? code + 5 // a-z + : code - 63 + } + + if ((a+='') != (b+='')) for (;codeB;) { + codeA = getCode(a, posA++) + codeB = getCode(b, posB++) + if (codeA < 76 && codeB < 76 && codeA > 66 && codeB > 66) { + codeA = getCode(a, posA, posA) + codeB = getCode(b, posB, posA = i) + posB = i + } + if (codeA != codeB) return (codeA < codeB) ? -1 : 1 + } + return 0 + } + normMenu(menu, el) { + if (Array.isArray(menu)) { + menu.forEach((it, m) => { + if (typeof it === 'string' || typeof it === 'number') { + menu[m] = { id: it, text: String(it) } + } else if (it != null) { + if (it.caption != null && it.text == null) it.text = it.caption + if (it.text != null && it.id == null) it.id = it.text + if (it.text == null && it.id != null) it.text = it.id + } else { + menu[m] = { id: null, text: 'null' } + } + }) + return menu + } else if (typeof menu === 'function') { + let newMenu = menu.call(this, menu, el) + return w2utils.normMenu.call(this, newMenu) + } else if (typeof menu === 'object') { + return Object.keys(menu).map(key => { return { id: key, text: menu[key] } }) + } + } + /** + * Takes Url object and fetchOptions and changes it in place applying selected user dataType. Since + * dataType is in w2utils. This method is used in grid, form and tooltip to prepare fetch parameters + */ + prepareParams(url, fetchOptions, defDataType) { + let dataType = defDataType ?? w2utils.settings.dataType + let postParams = fetchOptions.body + switch (dataType) { + case 'HTTPJSON': + postParams = { request: postParams } + if (['PUT', 'DELETE'].includes(fetchOptions.method)) { + fetchOptions.method = 'POST' + } + body2params() + break + case 'HTTP': + if (['PUT', 'DELETE'].includes(fetchOptions.method)) { + fetchOptions.method = 'POST' + } + body2params() + break + case 'RESTFULL': + if (['PUT', 'DELETE'].includes(fetchOptions.method)) { + fetchOptions.headers['Content-Type'] = 'application/json' + } else { + body2params() + } + break + case 'JSON': + if (fetchOptions.method == 'GET') { + postParams = { request: postParams } + body2params() + } else { + fetchOptions.headers['Content-Type'] = 'application/json' + fetchOptions.method = 'POST' + } + break + } + fetchOptions.body = typeof fetchOptions.body == 'string' ? fetchOptions.body : JSON.stringify(fetchOptions.body) + return fetchOptions + function body2params() { + Object.keys(postParams).forEach(key => { + let param = postParams[key] + if (typeof param == 'object') param = JSON.stringify(param) + url.searchParams.append(key, param) + }) + delete fetchOptions.body + } + } + bindEvents(selector, subject) { + // format is + //
    ='["","param1","param2",...]'> -- should be valid JSON (no undefined) + //
    ="|param1|param2"> + // -- can have "event", "this", "stop", "stopPrevent", "alert" - as predefined objects + if (selector.length == 0) return + // for backward compatibility + if (selector?.[0] instanceof Node) { + selector = Array.isArray(selector) ? selector : selector.get() + } + query(selector).each((el) => { + let actions = query(el).data() + Object.keys(actions).forEach(name => { + let events = ['click', 'dblclick', 'mouseenter', 'mouseleave', 'mouseover', 'mouseout', 'mousedown', 'mousemove', 'mouseup', + 'contextmenu', 'focus', 'focusin', 'focusout', 'blur', 'input', 'change', 'keydown', 'keyup', 'keypress'] + if (events.indexOf(String(name).toLowerCase()) == -1) { + return + } + let params = actions[name] + if (typeof params == 'string') { + params = params.split('|').map(key => { + if (key === 'true') key = true + if (key === 'false') key = false + if (key === 'undefined') key = undefined + if (key === 'null') key = null + if (parseFloat(key) == key) key = parseFloat(key) + let quotes = ['\'', '"', '`'] + if (typeof key == 'string' && quotes.includes(key[0]) && quotes.includes(key[key.length-1])) { + key = key.substring(1, key.length-1) + } + return key + }) + } + let method = params[0] + params = params.slice(1) // should be new array + query(el) + .off(name + '.w2utils-bind') + .on(name + '.w2utils-bind', function(event) { + switch (method) { + case 'alert': + alert(params[0]) // for testing purposes + break + case 'stop': + event.stopPropagation() + break + case 'prevent': + event.preventDefault() + break + case 'stopPrevent': + event.stopPropagation() + event.preventDefault() + return false + break + default: + if (subject[method] == null) { + throw new Error(`Cannot dispatch event as the method "${method}" does not exist.`) + } + subject[method].apply(subject, params.map((key, ind) => { + switch (String(key).toLowerCase()) { + case 'event': + return event + case 'this': + return this + default: + return key + } + })) + } + }) + }) + }) + } + debounce(func, wait = 250) { + let timeout + return (...args) => { + clearTimeout(timeout) + timeout = setTimeout(() => { func(...args) }, wait) + } + } +} +var w2utils = new Utils() // eslint-disable-line -- needs to be functional/module scope variable +/** + * Part of w2ui 2.0 library + * - Dependencies: mQuery, w2utils, w2base + * + * == 2.0 changes + * - CSP - fixed inline events + * - removed jQuery dependency + * - popup.open - returns promise like object + * - popup.confirm - refactored + * - popup.message - refactored + * - removed popup.options.mutliple + * - refactores w2alert, w2confirm, w2prompt + * - add w2popup.open().on('') + * - removed w2popup.restoreTemplate + * - deprecated onMsgOpen and onMsgClose + * - deprecated options.bgColor + * - rename focus -> setFocus + * - added center() // will auto center on window resize + * - close(immediate), also refactored if popup is closed when opening + */ + +class Dialog extends w2base { + constructor() { + super() + this.defaults = { + title: '', + text: '', // just a text (will be centered) + body: '', + buttons: '', + width: 450, + height: 250, + focus: null, // brings focus to the element, can be a number or selector + actions: null, // actions object + style: '', // style of the message div + speed: 0.3, + modal: false, + maximized: false, // this is a flag to show the state - to open the popup maximized use openMaximized instead + keyboard: true, // will close popup on esc if not modal + showClose: true, + showMax: false, + transition: null, + openMaximized: false, + moved: false + } + this.name = 'popup' + this.status = 'closed' // string that describes current status + this.onOpen = null + this.onClose = null + this.onMax = null + this.onMin = null + this.onToggle = null + this.onKeydown = null + this.onAction = null + this.onMove = null + this.tmp = {} + // event handler for resize + this.handleResize = (event) => { + // if it was moved by the user, do not auto resize + if (!this.options.moved) { + this.center(undefined, undefined, true) + } + } + } + /** + * Sample calls + * - w2popup.open('ddd').ok(() => { w2popup.close() }) + * - w2popup.open('ddd', { height: 120 }).ok(() => { w2popup.close() }) + * - w2popup.open({ body: 'text', title: 'caption', actions: ["Close"] }).close(() => { w2popup.close() }) + * - w2popup.open({ body: 'text', title: 'caption', actions: { Close() { w2popup.close() }} }) + */ + open(options) { + let self = this + if (this.status == 'closing' || query('#w2ui-popup').hasClass('animating')) { + // if called when previous is closing + this.close(true) + } + // get old options and merge them + let old_options = this.options + if (['string', 'number'].includes(typeof options)) { + options = w2utils.extend({ + title: 'Notification', + body: `
    ${options}
    `, + actions: { Ok() { self.close() }}, + cancelAction: 'ok' + }, arguments[1] ?? {}) + } + if (options.text != null) options.body = `
    ${options.text}
    ` + options = Object.assign({}, this.defaults, old_options, { title: '', body : '' }, options, { maximized: false }) + this.options = options + // if new - reset event handlers + if (query('#w2ui-popup').length === 0) { + this.off('*') + Object.keys(this).forEach(key => { + if (key.startsWith('on') && key != 'on') this[key] = null + }) + } + // reassign events + Object.keys(options).forEach(key => { + if (key.startsWith('on') && key != 'on' && options[key]) { + this[key] = options[key] + } + }) + options.width = parseInt(options.width) + options.height = parseInt(options.height) + let edata, msg, tmp + let { top, left } = this.center() + let prom = { + self: this, + action(callBack) { + self.on('action.prom', callBack) + return prom + }, + close(callBack) { + self.on('close.prom', callBack) + return prom + }, + then(callBack) { + self.on('open:after.prom', callBack) + return prom + } + } + // convert action arrays into buttons + if (options.actions != null && !options.buttons) { + options.buttons = '' + Object.keys(options.actions).forEach((action) => { + let handler = options.actions[action] + let btnAction = action + if (typeof handler == 'function') { + options.buttons += `` + } + if (typeof handler == 'object') { + options.buttons += `` + btnAction = Array.isArray(options.actions) ? handler.text : action + } + if (typeof handler == 'string') { + options.buttons += `` + btnAction = handler + } + if (typeof btnAction == 'string') { + btnAction = btnAction[0].toLowerCase() + btnAction.substr(1).replace(/\s+/g, '') + } + prom[btnAction] = function (callBack) { + self.on('action.buttons', (event) => { + let target = event.detail.action[0].toLowerCase() + event.detail.action.substr(1).replace(/\s+/g, '') + if (target == btnAction) callBack(event) + }) + return prom + } + }) + } + // check if message is already displayed + if (query('#w2ui-popup').length === 0) { + // trigger event + edata = this.trigger('open', { target: 'popup', present: false }) + if (edata.isCancelled === true) return + this.status = 'opening' + // output message + w2utils.lock(document.body, { + opacity: 0.3, + onClick: options.modal ? null : () => { this.close() } + }) + let btn = '' + if (options.showClose) { + btn += `
    + +
    ` + } + if (options.showMax) { + btn += `
    + +
    ` + } + // first insert just body + let styles = ` + left: ${left}px; + top: ${top}px; + width: ${parseInt(options.width)}px; + height: ${parseInt(options.height)}px; + transition: ${options.speed}s + ` + msg = `
    ` + query('body').append(msg) + query('#w2ui-popup')[0]._w2popup = { + self: this, + created: new Promise((resolve) => { this._promCreated = resolve }), + opened: new Promise((resolve) => { this._promOpened = resolve }), + closing: new Promise((resolve) => { this._promClosing = resolve }), + closed: new Promise((resolve) => { this._promClosed = resolve }), + } + // then content + styles = `${!options.title ? 'top: 0px !important;' : ''} ${!options.buttons ? 'bottom: 0px !important;' : ''}` + msg = ` + +
    ${btn}
    +
    +
    +
    +
    +
    +
    + + ` + query('#w2ui-popup').html(msg) + if (options.title) query('#w2ui-popup .w2ui-popup-title').append(w2utils.lang(options.title)) + if (options.buttons) query('#w2ui-popup .w2ui-popup-buttons').append(options.buttons) + if (options.body) query('#w2ui-popup .w2ui-popup-body').append(options.body) + // allow element to render + setTimeout(() => { + query('#w2ui-popup') + .css('transition', options.speed + 's') + .removeClass('w2ui-anim-open') + w2utils.bindEvents('#w2ui-popup .w2ui-eaction', this) + query('#w2ui-popup').find('.w2ui-popup-body').show() + this._promCreated() + }, 1) + // clean transform + clearTimeout(this._timer) + this._timer = setTimeout(() => { + this.status = 'open' + self.setFocus(options.focus) + // event after + edata.finish() + this._promOpened() + query('#w2ui-popup').removeClass('animating') + }, options.speed * 1000) + } else { + // trigger event + edata = this.trigger('open', { target: 'popup', present: true }) + if (edata.isCancelled === true) return + // check if size changed + this.status = 'opening' + if (old_options != null) { + if (!old_options.maximized && (old_options.width != options.width || old_options.height != options.height)) { + this.resize(options.width, options.height) + } + options.prevSize = options.width + 'px:' + options.height + 'px' + options.maximized = old_options.maximized + } + // show new items + let cloned = query('#w2ui-popup .w2ui-box').get(0).cloneNode(true) + query(cloned).removeClass('w2ui-box').addClass('w2ui-box-temp').find('.w2ui-popup-body').empty().append(options.body) + query('#w2ui-popup .w2ui-box').after(cloned) + if (options.buttons) { + query('#w2ui-popup .w2ui-popup-buttons').show().html('').append(options.buttons) + query('#w2ui-popup .w2ui-popup-body').removeClass('w2ui-popup-no-buttons') + query('#w2ui-popup .w2ui-box, #w2ui-popup .w2ui-box-temp').css('bottom', '') + } else { + query('#w2ui-popup .w2ui-popup-buttons').hide().html('') + query('#w2ui-popup .w2ui-popup-body').addClass('w2ui-popup-no-buttons') + query('#w2ui-popup .w2ui-box, #w2ui-popup .w2ui-box-temp').css('bottom', '0px') + } + if (options.title) { + query('#w2ui-popup .w2ui-popup-title') + .show() + .html((options.showClose + ? `
    + +
    ` + : '') + + (options.showMax + ? `
    + +
    ` + : '')) + .append(options.title) + query('#w2ui-popup .w2ui-popup-body').removeClass('w2ui-popup-no-title') + query('#w2ui-popup .w2ui-box, #w2ui-popup .w2ui-box-temp').css('top', '') + } else { + query('#w2ui-popup .w2ui-popup-title').hide().html('') + query('#w2ui-popup .w2ui-popup-body').addClass('w2ui-popup-no-title') + query('#w2ui-popup .w2ui-box, #w2ui-popup .w2ui-box-temp').css('top', '0px') + } + // transition + let div_old = query('#w2ui-popup .w2ui-box')[0] + let div_new = query('#w2ui-popup .w2ui-box-temp')[0] + query('#w2ui-popup').addClass('animating') + w2utils.transition(div_old, div_new, options.transition, () => { + // clean up + query(div_old).remove() + query(div_new).removeClass('w2ui-box-temp').addClass('w2ui-box') + let $body = query(div_new).find('.w2ui-popup-body') + if ($body.length == 1) { + $body[0].style.cssText = options.style + $body.show() + } + // focus on first button + self.setFocus(options.focus) + query('#w2ui-popup').removeClass('animating') + }) + // call event onOpen + this.status = 'open' + edata.finish() + w2utils.bindEvents('#w2ui-popup .w2ui-eaction', this) + query('#w2ui-popup').find('.w2ui-popup-body').show() + } + if (options.openMaximized) { + this.max() + } + // save new options + options._last_focus = document.activeElement + // keyboard events + if (options.keyboard) { + query(document.body).on('keydown', (event) => { + this.keydown(event) + }) + } + query(window).on('resize', this.handleResize) + // initialize move + tmp = { + resizing : false, + mvMove : mvMove, + mvStop : mvStop + } + query('#w2ui-popup .w2ui-popup-title').on('mousedown', function(event) { + if (!self.options.maximized) mvStart(event) + }) + return prom + // handlers + function mvStart(evt) { + if (!evt) evt = window.event + self.status = 'moving' + let rect = query('#w2ui-popup').get(0).getBoundingClientRect() + Object.assign(tmp, { + resizing: true, + isLocked: query('#w2ui-popup > .w2ui-lock').length == 1 ? true : false, + x : evt.screenX, + y : evt.screenY, + pos_x : rect.x, + pos_y : rect.y, + }) + if (!tmp.isLocked) self.lock({ opacity: 0 }) + query(document.body) + .on('mousemove.w2ui-popup', tmp.mvMove) + .on('mouseup.w2ui-popup', tmp.mvStop) + if (evt.stopPropagation) evt.stopPropagation(); else evt.cancelBubble = true + if (evt.preventDefault) evt.preventDefault(); else return false + } + function mvMove(evt) { + if (tmp.resizing != true) return + if (!evt) evt = window.event + tmp.div_x = evt.screenX - tmp.x + tmp.div_y = evt.screenY - tmp.y + // trigger event + let edata = self.trigger('move', { target: 'popup', div_x: tmp.div_x, div_y: tmp.div_y, originalEvent: evt }) + if (edata.isCancelled === true) return + // default behavior + query('#w2ui-popup').css({ + 'transition': 'none', + 'transform' : 'translate3d('+ tmp.div_x +'px, '+ tmp.div_y +'px, 0px)' + }) + self.options.moved = true + // event after + edata.finish() + } + function mvStop(evt) { + if (tmp.resizing != true) return + if (!evt) evt = window.event + self.status = 'open' + tmp.div_x = (evt.screenX - tmp.x) + tmp.div_y = (evt.screenY - tmp.y) + query('#w2ui-popup') + .css({ + 'left': (tmp.pos_x + tmp.div_x) + 'px', + 'top' : (tmp.pos_y + tmp.div_y) + 'px' + }) + .css({ + 'transition': 'none', + 'transform' : 'translate3d(0px, 0px, 0px)' + }) + tmp.resizing = false + query(document.body).off('.w2ui-popup') + if (!tmp.isLocked) self.unlock() + } + } + load(options) { + return new Promise((resolve, reject) => { + if (typeof options == 'string') { + options = { url: options } + } + if (options.url == null) { + console.log('ERROR: The url is not defined.') + reject('The url is not defined') + return + } + this.status = 'loading' + let [url, selector] = String(options.url).split('#') + if (url) { + fetch(url).then(res => res.text()).then(html => { + resolve(this.template(html, selector, options)) + }) + } + }) + } + template(data, id, options = {}) { + let html + try { + html = query(data) + } catch (e) { + html = query.html(data) + } + if (id) html = html.filter('#' + id) + Object.assign(options, { + width: parseInt(query(html).css('width')), + height: parseInt(query(html).css('height')), + title: query(html).find('[rel=title]').html(), + body: query(html).find('[rel=body]').html(), + buttons: query(html).find('[rel=buttons]').html(), + style: query(html).find('[rel=body]').get(0).style.cssText, + }) + return this.open(options) + } + action(action, event) { + let click = this.options.actions[action] + if (click instanceof Object && click.onClick) click = click.onClick + // event before + let edata = this.trigger('action', { action, target: 'popup', self: this, + originalEvent: event, value: this.input ? this.input.value : null }) + if (edata.isCancelled === true) return + // default actions + if (typeof click === 'function') click.call(this, event) + // event after + edata.finish() + } + keydown(event) { + if (this.options && !this.options.keyboard) return + // trigger event + let edata = this.trigger('keydown', { target: 'popup', originalEvent: event }) + if (edata.isCancelled === true) return + // default behavior + switch (event.keyCode) { + case 27: + event.preventDefault() + if (query('#w2ui-popup .w2ui-message').length == 0) { + if (this.options.cancelAction) { + this.action(this.options.cancelAction) + } else { + this.close() + } + } + break + } + // event after + edata.finish() + } + close(immediate) { + // trigger event + let edata = this.trigger('close', { target: 'popup' }) + if (edata.isCancelled === true) return + let cleanUp = () => { + // return template + query('#w2ui-popup').remove() + // restore active + if (this.options._last_focus && this.options._last_focus.length > 0) this.options._last_focus.focus() + this.status = 'closed' + this.options = {} + // event after + edata.finish() + this._promClosed() + } + if (query('#w2ui-popup').length === 0 || this.status == 'closed') { // already closed + return + } + if (this.status == 'opening') { // if it is opening + immediate = true + } + if (this.status == 'closing' && immediate === true) { + cleanUp() + clearTimeout(this.tmp.closingTimer) + w2utils.unlock(document.body, 0) + return + } + // default behavior + this.status = 'closing' + query('#w2ui-popup') + .css('transition', this.options.speed + 's') + .addClass('w2ui-anim-close animating') + w2utils.unlock(document.body, 300) + this._promClosing() + if (immediate) { + cleanUp() + } else { + this.tmp.closingTimer = setTimeout(cleanUp, this.options.speed * 1000) + } + // remove keyboard events + if (this.options.keyboard) { + query(document.body).off('keydown', this.keydown) + } + query(window).off('resize', this.handleResize) + } + toggle() { + let edata = this.trigger('toggle', { target: 'popup' }) + if (edata.isCancelled === true) return + // default action + if (this.options.maximized === true) this.min(); else this.max() + // event after + setTimeout(() => { + edata.finish() + }, (this.options.speed * 1000) + 50) + } + max() { + if (this.options.maximized === true) return + // trigger event + let edata = this.trigger('max', { target: 'popup' }) + if (edata.isCancelled === true) return + // default behavior + this.status = 'resizing' + let rect = query('#w2ui-popup').get(0).getBoundingClientRect() + this.options.prevSize = rect.width + ':' + rect.height + // do resize + this.resize(10000, 10000, () => { + this.status = 'open' + this.options.maximized = true + edata.finish() + }) + } + min() { + if (this.options.maximized !== true) return + let size = this.options.prevSize.split(':') + // trigger event + let edata = this.trigger('min', { target: 'popup' }) + if (edata.isCancelled === true) return + // default behavior + this.status = 'resizing' + // do resize + this.options.maximized = false + this.resize(parseInt(size[0]), parseInt(size[1]), () => { + this.status = 'open' + this.options.prevSize = null + edata.finish() + }) + } + clear() { + query('#w2ui-popup .w2ui-popup-title').html('') + query('#w2ui-popup .w2ui-popup-body').html('') + query('#w2ui-popup .w2ui-popup-buttons').html('') + } + reset() { + this.open(this.defaults) + } + message(options) { + return w2utils.message({ + owner: this, + box : query('#w2ui-popup').get(0), + after: '.w2ui-popup-title' + }, options) + } + confirm(options) { + return w2utils.confirm({ + owner: this, + box : query('#w2ui-popup'), + after: '.w2ui-popup-title' + }, options) + } + setFocus(focus) { + let box = query('#w2ui-popup') + let sel = 'input, button, select, textarea, [contentEditable], .w2ui-input' + if (focus != null) { + let el = isNaN(focus) + ? box.find(sel).filter(focus).get(0) + : box.find(sel).get(focus) + el?.focus() + } else { + let el = box.find('[name=hidden-first]').get(0) + if (el) el.focus() + } + // keep focus/blur inside popup + query(box).find(sel + ',[name=hidden-first],[name=hidden-last]') + .off('.keep-focus') + .on('blur.keep-focus', function (event) { + setTimeout(() => { + let focus = document.activeElement + let inside = query(box).find(sel).filter(focus).length > 0 + let name = query(focus).attr('name') + if (!inside && focus && focus !== document.body) { + query(box).find(sel).get(0)?.focus() + } + if (name == 'hidden-last') { + query(box).find(sel).get(0)?.focus() + } + if (name == 'hidden-first') { + query(box).find(sel).get(-1)?.focus() + } + }, 1) + }) + } + lock(msg, showSpinner) { + let args = Array.from(arguments) + args.unshift(query('#w2ui-popup')) + w2utils.lock(...args) + } + unlock(speed) { + w2utils.unlock(query('#w2ui-popup'), speed) + } + center(width, height, force) { + let maxW, maxH + if (window.innerHeight == undefined) { + maxW = parseInt(document.documentElement.offsetWidth) + maxH = parseInt(document.documentElement.offsetHeight) + } else { + maxW = parseInt(window.innerWidth) + maxH = parseInt(window.innerHeight) + } + width = parseInt(width ?? this.options.width) + height = parseInt(height ?? this.options.height) + if (this.options.maximized === true) { + width = maxW + height = maxH + } + if (maxW - 10 < width) width = maxW - 10 + if (maxH - 10 < height) height = maxH - 10 + let top = (maxH - height) / 2 + let left = (maxW - width) / 2 + if (force) { + query('#w2ui-popup').css({ + 'transition': 'none', + 'top' : top + 'px', + 'left' : left + 'px', + 'width' : width + 'px', + 'height': height + 'px' + }) + this.resizeMessages() // then messages resize nicely + } + return { top, left, width, height } + } + resize(newWidth, newHeight, callBack) { + let self = this + if (this.options.speed == null) this.options.speed = 0 + // calculate new position + let { top, left, width, height } = this.center(newWidth, newHeight) + let speed = this.options.speed + query('#w2ui-popup').css({ + 'transition': `${speed}s width, ${speed}s height, ${speed}s left, ${speed}s top`, + 'top' : top + 'px', + 'left' : left + 'px', + 'width' : width + 'px', + 'height': height + 'px' + }) + let tmp_int = setInterval(() => { self.resizeMessages() }, 10) // then messages resize nicely + setTimeout(() => { + clearInterval(tmp_int) + self.resizeMessages() + if (typeof callBack == 'function') callBack() + }, (this.options.speed * 1000) + 50) // give extra 50 ms + } + // internal function + resizeMessages() { + // see if there are messages and resize them + query('#w2ui-popup .w2ui-message').each(msg => { + let mopt = msg._msg_options + let popup = query('#w2ui-popup') + if (parseInt(mopt.width) < 10) mopt.width = 10 + if (parseInt(mopt.height) < 10) mopt.height = 10 + let rect = popup[0].getBoundingClientRect() + let titleHeight = parseInt(popup.find('.w2ui-popup-title')[0].clientHeight) + let pWidth = parseInt(rect.width) + let pHeight = parseInt(rect.height) + // re-calc width + mopt.width = mopt.originalWidth + if (mopt.width > pWidth - 10) { + mopt.width = pWidth - 10 + } + // re-calc height + mopt.height = mopt.originalHeight + if (mopt.height > pHeight - titleHeight - 5) { + mopt.height = pHeight - titleHeight - 5 + } + if (mopt.originalHeight < 0) mopt.height = pHeight + mopt.originalHeight - titleHeight + if (mopt.originalWidth < 0) mopt.width = pWidth + mopt.originalWidth * 2 // x 2 because there is left and right margin + query(msg).css({ + left : ((pWidth - mopt.width) / 2) + 'px', + width : mopt.width + 'px', + height : mopt.height + 'px' + }) + }) + } +} +function w2alert(msg, title, callBack) { + let prom + let options = { + title: w2utils.lang(title ?? 'Notification'), + body: `
    ${msg}
    `, + showClose: false, + actions: ['Ok'], + cancelAction: 'ok' + } + if (query('#w2ui-popup').length > 0 && w2popup.status != 'closing') { + prom = w2popup.message(options) + } else { + prom = w2popup.open(options) + } + prom.ok((event) => { + if (typeof event.detail.self?.close == 'function') { + event.detail.self.close() + } + if (typeof callBack == 'function') callBack() + }) + return prom +} +function w2confirm(msg, title, callBack) { + let prom + let options = msg + if (['string', 'number'].includes(typeof options)) { + options = { msg: options } + } + if (options.msg) { + options.body = `
    ${options.msg}
    `, + delete options.msg + } + w2utils.extend(options, { + title: w2utils.lang(title ?? 'Confirmation'), + showClose: false, + modal: true, + cancelAction: 'no' + }) + w2utils.normButtons(options, { yes: 'Yes', no: 'No' }) + if (query('#w2ui-popup').length > 0 && w2popup.status != 'closing') { + prom = w2popup.message(options) + } else { + prom = w2popup.open(options) + } + prom.self + .off('.confirm') + .on('action:after.confirm', (event) => { + if (typeof event.detail.self?.close == 'function') { + event.detail.self.close() + } + if (typeof callBack == 'function') callBack(event.detail.action) + }) + return prom +} +function w2prompt(label, title, callBack) { + let prom + let options = label + if (['string', 'number'].includes(typeof options)) { + options = { label: options } + } + if (options.label) { + options.focus = 0 + options.body = (options.textarea + ? `
    +
    ${options.label}
    + +
    ` + : `
    + + +
    ` + ) + } + w2utils.extend(options, { + title: w2utils.lang(title ?? 'Notification'), + showClose: false, + modal: true, + cancelAction: 'cancel' + }) + w2utils.normButtons(options, { ok: 'Ok', cancel: 'Cancel' }) + if (query('#w2ui-popup').length > 0 && w2popup.status != 'closing') { + prom = w2popup.message(options) + } else { + prom = w2popup.open(options) + } + if (prom.self.box) { + prom.self.input = query(prom.self.box).find('#w2prompt').get(0) + } else { + prom.self.input = query('#w2ui-popup .w2ui-popup-body #w2prompt').get(0) + } + if (options.value !== null) { + prom.self.input.select() + } + prom.change = function (callback) { + prom.self.on('change', callback) + return this + } + prom.self + .off('.prompt') + .on('open:after.prompt', (event) => { + let box = event.detail.box ? event.detail.box : query('#w2ui-popup .w2ui-popup-body').get(0) + w2utils.bindEvents(query(box).find('#w2prompt'), { + keydown(evt) { + if (evt.keyCode == 27) evt.stopPropagation() + }, + change(evt) { + let edata = prom.self.trigger('change', { target: 'prompt', originalEvent: evt }) + if (edata.isCancelled === true) return + if (evt.keyCode == 13 && evt.ctrlKey) { + prom.self.action('Ok', evt) + } + if (evt.keyCode == 27) { + prom.self.action('Cancel', evt) + } + edata.finish() + } + }) + query(box).find('.w2ui-eaction').trigger('keyup') + }) + .on('action:after.prompt', (event) => { + if (typeof event.detail.self?.close == 'function') { + event.detail.self.close() + } + if (typeof callBack == 'function') callBack(event.detail.action) + }) + return prom +} +let w2popup = new Dialog() +/** + * Part of w2ui 2.0 library + * - Dependencies: mQuery, w2utils, w2base + * + * 2.0 Changes + * - multiple tooltips to the same anchor + * + */ + +class Tooltip { + // no need to extend w2base, as each individual tooltip extends it + static active = {} // all defined tooltips + constructor() { + this.defaults = { + name : null, // name for the overlay, otherwise input id is used + html : '', // text or html + style : '', // additional style for the overlay + class : '', // add class for w2ui-tooltip-body + position : 'top|bottom', // can be left, right, top, bottom + align : '', // can be: both, both:XX left, right, both, top, bottom + anchor : null, // element it is attached to, if anchor is body, then it is context menu + anchorClass : '', // add class for anchor when tooltip is shown + anchorStyle : '', // add style for anchor when tooltip is shown + autoShow : false, // if autoShow true, then tooltip will show on mouseEnter and hide on mouseLeave + autoShowOn : null, // when options.autoShow = true, mouse event to show on + autoHideOn : null, // when options.autoShow = true, mouse event to hide on + arrowSize : 8, // size of the carret + margin : 0, // extra margin from the anchor + screenMargin : 2, // min margin from screen to tooltip + autoResize : true, // auto resize based on content size and available size + margin : 1, // distance from the anchor + offsetX : 0, // delta for left coordinate + offsetY : 0, // delta for top coordinate + maxWidth : null, // max width + maxHeight : null, // max height + watchScroll : null, // attach to onScroll event // TODO: + watchResize : null, // attach to onResize event // TODO: + hideOn : null, // events when to hide tooltip, ['click', 'change', 'key', 'focus', 'blur'], + onThen : null, // called when displayed + onShow : null, // callBack when shown + onHide : null, // callBack when hidden + onUpdate : null, // callback when tooltip gets updated + onMove : null // callback when tooltip is moved + } + } + static observeRemove = new MutationObserver((mutations) => { + let cnt = 0 + Object.keys(Tooltip.active).forEach(name => { + let overlay = Tooltip.active[name] + if (overlay.displayed) { + if (!overlay.anchor || !overlay.anchor.isConnected) { + overlay.hide() + } else { + cnt++ + } + } + }) + // remove observer, as there is no active tooltips + if (cnt === 0) { + Tooltip.observeRemove.disconnect() + } + }) + trigger(event, data) { + if (arguments.length == 2) { + let type = event + event = data + data.type = type + } + if (event.overlay) { + return event.overlay.trigger(event) + } else { + console.log('ERROR: cannot find overlay where to trigger events') + } + } + get(name) { + if (arguments.length == 0) { + return Object.keys(Tooltip.active) + } else if (name === true) { + return Tooltip.active + } else { + return Tooltip.active[name.replace(/[\s\.#]/g, '_')] + } + } + attach(anchor, text) { + let options, overlay + let self = this + if (arguments.length == 0) { + return + } else if (arguments.length == 1 && anchor.anchor) { + options = anchor + anchor = options.anchor + } else if (arguments.length === 2 && typeof text === 'string') { + options = { anchor, html: text } + text = options.html + } else if (arguments.length === 2 && text != null && typeof text === 'object') { + options = text + text = options.html + } + options = w2utils.extend({}, this.defaults, options || {}) + if (!text && options.text) text = options.text + if (!text && options.html) text = options.html + // anchor is func var + delete options.anchor + // define tooltip + let name = (options.name ? options.name : anchor.id) + if (anchor == document || anchor == document.body) { + anchor = document.body + name = 'context-menu' + } + if (!name) { + name = 'noname-' + Object.keys(Tooltip.active).length + console.log('NOTICE: name property is not defined for tooltip, could lead to too many instances') + } + // clean name as it is used as id and css selector + name = name.replace(/[\s\.#]/g, '_') + if (Tooltip.active[name]) { + overlay = Tooltip.active[name] + overlay.prevOptions = overlay.options + overlay.options = options // do not merge or extend, otherwiser menu items get merged too + // overlay.options = w2utils.extend({}, overlay.options, options) + overlay.anchor = anchor // as HTML elements are not copied + if (overlay.prevOptions.html != overlay.options.html || overlay.prevOptions.class != overlay.options.class + || overlay.prevOptions.style != overlay.options.style) { + overlay.needsUpdate = true + } + options = overlay.options // it was recreated + } else { + overlay = new w2base() + Object.assign(overlay, { + id: 'w2overlay-' + name, name, options, anchor, + displayed: false, + tmp: { + observeResize: new ResizeObserver(() => { + this.resize(overlay.name) + }) + }, + hide() { + self.hide(name) + } + }) + Tooltip.active[name] = overlay + } + // move events on to overlay layer + Object.keys(overlay.options).forEach(key => { + let val = overlay.options[key] + if (key.startsWith('on') && typeof val == 'function') { + overlay[key] = val + delete overlay.options[key] + } + }) + // add event for auto show/hide + if (options.autoShow === true) { + options.autoShowOn = options.autoShowOn ?? 'mouseenter' + options.autoHideOn = options.autoHideOn ?? 'mouseleave' + options.autoShow = false + } + if (options.autoShowOn) { + let scope = 'autoShow-' + overlay.name + query(anchor) + .off(`.${scope}`) + .on(`${options.autoShowOn}.${scope}`, event => { + self.show(overlay.name) + event.stopPropagation() + }) + delete options.autoShowOn + } + if (options.autoHideOn) { + let scope = 'autoHide-' + overlay.name + query(anchor) + .off(`.${scope}`) + .on(`${options.autoHideOn}.${scope}`, event => { + self.hide(overlay.name) + event.stopPropagation() + }) + delete options.autoHideOn + } + overlay.off('.attach') + let ret = { + overlay, + then: (callback) => { + overlay.on('show:after.attach', event => { callback(event) }) + return ret + }, + show: (callback) => { + overlay.on('show.attach', event => { callback(event) }) + return ret + }, + hide: (callback) => { + overlay.on('hide.attach', event => { callback(event) }) + return ret + }, + update: (callback) => { + overlay.on('update.attach', event => { callback(event) }) + return ret + }, + move: (callback) => { + overlay.on('move.attach', event => { callback(event) }) + return ret + } + } + return ret + } + update(name, html) { + let overlay = Tooltip.active[name] + if (overlay) { + overlay.needsUpdate = true + overlay.options.html = html + this.show(name) + } else { + console.log(`Tooltip "${name}" is not displayed. Cannot update it.`) + } + } + show(name) { + if (name instanceof HTMLElement || name instanceof Object) { + let options = name + if (name instanceof HTMLElement) { + options = arguments[1] || {} + options.anchor = name + } + let ret = this.attach(options) + query(ret.overlay.anchor) + .off('.autoShow-' + ret.overlay.name) + .off('.autoHide-' + ret.overlay.name) + // need a timer, so that events would be preperty set + setTimeout(() => { + this.show(ret.overlay.name) + if (this.initControls) { + this.initControls(ret.overlay) + } + }, 1) + return ret + } + let edata + let self = this + let overlay = Tooltip.active[name.replace(/[\s\.#]/g, '_')] + if (!overlay) return + let options = overlay.options + if (!overlay || (overlay.displayed && !overlay.needsUpdate)) { + this.resize(overlay?.name) + return + } + let position = options.position.split('|') + let isVertical = ['top', 'bottom'].includes(position[0]) + // enforce nowrap only when align=both and vertical + let overlayStyles = (options.align == 'both' && isVertical ? '' : 'white-space: nowrap;') + if (options.maxWidth && w2utils.getStrWidth(options.html, '') > options.maxWidth) { + overlayStyles = 'width: '+ options.maxWidth + 'px; white-space: inherit; overflow: auto;' + } + overlayStyles += ' max-height: '+ (options.maxHeight ? options.maxHeight : window.innerHeight - 40) + 'px;' + // if empty content - then hide it + if (options.html === '' || options.html == null) { + self.hide(name) + return + } else if (overlay.box) { + // if already present, update it + edata = this.trigger('update', { target: name, overlay }) + if (edata.isCancelled === true) { + // restore previous options + if (overlay.prevOptions) { + overlay.options = overlay.prevOptions + delete overlay.prevOptions + } + return + } + query(overlay.box) + .find('.w2ui-overlay-body') + .attr('style', (options.style || '') + '; ' + overlayStyles) + .removeClass() // removes all classes + .addClass('w2ui-overlay-body ' + options.class) + .html(options.html) + this.resize(overlay.name) + } else { + // event before + edata = this.trigger('show', { target: name, overlay }) + if (edata.isCancelled === true) return + // normal processing + query('body').append( + // pointer-events will be re-enabled leter + ``) + overlay.box = query('#'+w2utils.escapeId(overlay.id))[0] + overlay.displayed = true + let names = query(overlay.anchor).data('tooltipName') ?? [] + names.push(name) + query(overlay.anchor).data('tooltipName', names) // make available to element overlay attached to + w2utils.bindEvents(overlay.box, {}) + // remember anchor's original styles + overlay.tmp.originalCSS = '' + if (query(overlay.anchor).length > 0) { + overlay.tmp.originalCSS = query(overlay.anchor)[0].style.cssText + } + this.resize(overlay.name) + } + if (options.anchorStyle) { + overlay.anchor.style.cssText += ';' + options.anchorStyle + } + if (options.anchorClass) { + // do not add w2ui-focus to body + if (!(options.anchorClass == 'w2ui-focus' && overlay.anchor == document.body)) { + query(overlay.anchor).addClass(options.anchorClass) + } + } + // add on hide events + if (typeof options.hideOn == 'string') options.hideOn = [options.hideOn] + if (!Array.isArray(options.hideOn)) options.hideOn = [] + // initial scroll + Object.assign(overlay.tmp, { + scrollLeft: document.body.scrollLeft, + scrollTop: document.body.scrollTop + }) + addHideEvents() + addWatchEvents(document.body) + // first show empty tooltip, so it will popup up in the right position + query(overlay.box).show() + overlay.tmp.observeResize.observe(overlay.box) + // observer element removal from DOM + Tooltip.observeRemove.observe(document.body, { subtree: true, childList: true }) + // then insert html and it will adjust + query(overlay.box) + .css('opacity', 1) + .find('.w2ui-overlay-body') + .html(options.html) + /** + * pointer-events: none is needed to avoid cases when popup is shown right under the cursor + * or it will trigger onmouseout, onmouseleave and other events. + */ + setTimeout(() => { query(overlay.box).css({ 'pointer-events': 'auto' }).data('ready', 'yes') }, 100) + delete overlay.needsUpdate + // expose overlay to DOM element + overlay.box.overlay = overlay + // event after + if (edata) edata.finish() + return { overlay } + function addWatchEvents(el) { + let scope = 'tooltip-' + overlay.name + let queryEl = el + if (el.tagName == 'BODY') { + queryEl = el.ownerDocument + } + query(queryEl) + .off(`.${scope}`) + .on(`scroll.${scope}`, event => { + Object.assign(overlay.tmp, { + scrollLeft: el.scrollLeft, + scrollTop: el.scrollTop + }) + self.resize(overlay.name) + }) + } + function addHideEvents() { + let hide = (event) => { self.hide(overlay.name) } + let $anchor = query(overlay.anchor) + let scope = 'tooltip-' + overlay.name + // document click + query('body').off(`.${scope}`) + if (options.hideOn.includes('doc-click')) { + if (['INPUT', 'TEXTAREA'].includes(overlay.anchor.tagName)) { + // otherwise hides on click to focus + $anchor + .off(`.${scope}-doc`) + .on(`click.${scope}-doc`, (event) => { event.stopPropagation() }) + } + query('body').on(`click.${scope}`, hide) + } + if (options.hideOn.includes('focus-change')) { + query('body') + .on(`focusin.${scope}`, (e) => { + if (document.activeElement != overlay.anchor) { + self.hide(overlay.name) + } + }) + } + if (['INPUT', 'TEXTAREA'].includes(overlay.anchor.tagName)) { + $anchor.off(`.${scope}`) + options.hideOn.forEach(event => { + if (['doc-click', 'focus-change'].indexOf(event) == -1) { + $anchor.on(`${event}.${scope}`, { once: true }, hide) + } + }) + } + } + } + hide(name) { + let overlay + if (arguments.length == 0) { + // hide all tooltips + Object.keys(Tooltip.active).forEach(name => { this.hide(name) }) + return + } + if (name instanceof HTMLElement) { + let names = query(name).data('tooltipName') ?? [] + names.forEach(name => { this.hide(name) }) + return + } + if (typeof name == 'string') { + name = name.replace(/[\s\.#]/g, '_') + overlay = Tooltip.active[name] + } + if (!overlay || !overlay.box) return + delete Tooltip.active[name] + // event before + let edata = this.trigger('hide', { target: name, overlay }) + if (edata.isCancelled === true) return + let scope = 'tooltip-' + overlay.name + // normal processing + overlay.tmp.observeResize?.disconnect() + if (overlay.options.watchScroll) { + query(overlay.options.watchScroll) + .off('.w2scroll-' + overlay.name) + } + // if no active tooltip then disable observeRemove + let cnt = 0 + Object.keys(Tooltip.active).forEach(key => { + let overlay = Tooltip.active[key] + if (overlay.displayed) { + cnt++ + } + }) + if (cnt == 0) { + Tooltip.observeRemove.disconnect() + } + query('body').off(`.${scope}`) // hide to click event here + query(document).off(`.${scope}`) // scroll event here + // remove element + overlay.box.remove() + overlay.box = null + overlay.displayed = false + // remove name from anchor properties + let names = query(overlay.anchor).data('tooltipName') ?? [] + let ind = names.indexOf(overlay.name) + if (ind != -1) names.splice(names.indexOf(overlay.name), 1) + if (names.length == 0) { + query(overlay.anchor).removeData('tooltipName') + } else { + query(overlay.anchor).data('tooltipName', names) + } + // restore original CSS + overlay.anchor.style.cssText = overlay.tmp.originalCSS + query(overlay.anchor) + .off(`.${scope}`) + .removeClass(overlay.options.anchorClass) + // event after + edata.finish() + } + resize(name) { + if (arguments.length == 0) { + Object.keys(Tooltip.active).forEach(key => { + let overlay = Tooltip.active[key] + if (overlay.displayed) this.resize(overlay.name) + }) + return + } + let overlay = Tooltip.active[name.replace(/[\s\.#]/g, '_')] + let pos = this.getPosition(overlay.name) + let newPos = pos.left + 'x' + pos.top + let edata + if (overlay.tmp.lastPos != newPos) { + edata = this.trigger('move', { target: name, overlay, pos }) + } + query(overlay.box) + .css({ + left: pos.left + 'px', + top : pos.top + 'px' + }) + .then(query => { + if (pos.width != null) { + query.css('width', pos.width + 'px') + .find('.w2ui-overlay-body') + .css('width', '100%') + } + if (pos.height != null) { + query.css('height', pos.height + 'px') + .find('.w2ui-overlay-body') + .css('height', '100%') + } + }) + .find('.w2ui-overlay-body') + .removeClass('w2ui-arrow-right w2ui-arrow-left w2ui-arrow-top w2ui-arrow-bottom') + .addClass(pos.arrow.class) + .closest('.w2ui-overlay') + .find('style') + .text(pos.arrow.style) + if (overlay.tmp.lastPos != newPos && edata) { + overlay.tmp.lastPos = newPos + edata.finish() + } + } + getPosition(name) { + let overlay = Tooltip.active[name.replace(/[\s\.#]/g, '_')] + if (!overlay || !overlay.box) { + return + } + let options = overlay.options + if (overlay.tmp.resizedY || overlay.tmp.resizedX) { + query(overlay.box).css({ width: '', height: '', scroll: 'auto' }) + } + let scrollSize = w2utils.scrollBarSize() + let hasScrollBarX = !(document.body.scrollWidth == document.body.clientWidth) + let hasScrollBarY = !(document.body.scrollHeight == document.body.clientHeight) + let max = { + width: window.innerWidth - (hasScrollBarY ? scrollSize : 0), + height: window.innerHeight - (hasScrollBarX ? scrollSize : 0) + } + let position = options.position == 'auto' ? 'top|bottom|right|left'.split('|') : options.position.split('|') + let isVertical = ['top', 'bottom'].includes(position[0]) + let content = overlay.box.getBoundingClientRect() + let anchor = overlay.anchor.getBoundingClientRect() + if (overlay.anchor == document.body) { + // context menu + let { x, y, width, height } = options.originalEvent + anchor = { left: x - 2, top: y - 4, width, height, arrow: 'none' } + } + let arrowSize = options.arrowSize + if (anchor.arrow == 'none') arrowSize = 0 + // space available + let available = { // tipsize adjustment should be here, not in max.width/max.height + top: anchor.top, + bottom: max.height - (anchor.top + anchor.height) - + (hasScrollBarX ? scrollSize : 0), + left: anchor.left, + right: max.width - (anchor.left + anchor.width) + (hasScrollBarY ? scrollSize : 0), + } + // size of empty tooltip + if (content.width < 22) content.width = 22 + if (content.height < 14) content.height = 14 + let left, top, width, height // tooltip position + let found = '' + let arrow = { + offset: 0, + class: '', + style: `#${overlay.id} { --tip-size: ${arrowSize}px; }` + } + let adjust = { left: 0, top: 0 } + let bestFit = { posX: '', x: 0, posY: '', y: 0 } + // find best position + position.forEach(pos => { + if (['top', 'bottom'].includes(pos)) { + if (!found && (content.height + arrowSize/1.893) < available[pos]) { // 1.893 = 1 + sin(90) + found = pos + } + if (available[pos] > bestFit.y) { + Object.assign(bestFit, { posY: pos, y: available[pos] }) + } + } + if (['left', 'right'].includes(pos)) { + if (!found && (content.width + arrowSize/1.893) < available[pos]) { // 1.893 = 1 + sin(90) + found = pos + } + if (available[pos] > bestFit.x) { + Object.assign(bestFit, { posX: pos, x: available[pos] }) + } + } + }) + // if not found, use best (greatest available space) position + if (!found) { + if (isVertical) { + found = bestFit.posY + } else { + found = bestFit.posX + } + } + if (options.autoResize) { + if (['top', 'bottom'].includes(found)) { + if (content.height > available[found]) { + height = available[found] + overlay.tmp.resizedY = true + } else { + overlay.tmp.resizedY = false + } + } + if (['left', 'right'].includes(found)) { + if (content.width > available[found]) { + width = available[found] + overlay.tmp.resizedX = true + } else { + overlay.tmp.resizedX = false + } + } + } + usePosition(found) + if (isVertical) anchorAlignment() + screenAdjust() + let extraTop = (found == 'top' ? -options.margin : (found == 'bottom' ? options.margin : 0)) + let extraLeft = (found == 'left' ? -options.margin : (found == 'right' ? options.margin : 0)) + // adjust for scrollbar + top = Math.floor((top + parseFloat(options.offsetY) + parseFloat(extraTop)) * 100) / 100 + left = Math.floor((left + parseFloat(options.offsetX) + parseFloat(extraLeft)) * 100) / 100 + return { left, top, arrow, adjust, width, height, pos: found } + function usePosition(pos) { + arrow.class = anchor.arrow ? anchor.arrow : `w2ui-arrow-${pos}` + switch (pos) { + case 'top': { + left = anchor.left + (anchor.width - (width ?? content.width)) / 2 + top = anchor.top - (height ?? content.height) - arrowSize / 1.5 + 1 + break + } + case 'bottom': { + left = anchor.left + (anchor.width - (width ?? content.width)) / 2 + top = anchor.top + anchor.height + arrowSize / 1.25 + 1 + break + } + case 'left': { + left = anchor.left - (width ?? content.width) - arrowSize / 1.2 - 1 + top = anchor.top + (anchor.height - (height ?? content.height)) / 2 + break + } + case 'right': { + left = anchor.left + anchor.width + arrowSize / 1.2 + 1 + top = anchor.top + (anchor.height - (height ?? content.height)) / 2 + break + } + } + } + function anchorAlignment() { + // top/bottom alignments + if (options.align == 'left') { + adjust.left = anchor.left - left + left = anchor.left + } + if (options.align == 'right') { + adjust.left = (anchor.left + anchor.width - (width ?? content.width)) - left + left = anchor.left + anchor.width - (width ?? content.width) + } + if (['top', 'bottom'].includes(found) && options.align.startsWith('both')) { + let minWidth = options.align.split(':')[1] ?? 50 + if (anchor.width >= minWidth) { + left = anchor.left + width = anchor.width + } + } + // left/right alignments + if (options.align == 'top') { + adjust.top = anchor.top - top + top = anchor.top + } + if (options.align == 'bottom') { + adjust.top = (anchor.top + anchor.height - (height ?? content.height)) - top + top = anchor.top + anchor.height - (height ?? content.height) + } + if (['left', 'right'].includes(found) && options.align.startsWith('both')) { + let minHeight = options.align.split(':')[1] ?? 50 + if (anchor.height >= minHeight) { + top = anchor.top + height = anchor.height + } + } + } + function screenAdjust() { + let adjustArrow + // adjust tip if needed after alignment + if ((['left', 'right'].includes(options.align) && anchor.width < (width ?? content.width)) + || (['top', 'bottom'].includes(options.align) && anchor.height < (height ?? content.height)) + ) { + adjustArrow = true + } + // if off screen then adjust + let minLeft = (found == 'right' ? arrowSize : options.screenMargin) + let minTop = (found == 'bottom' ? arrowSize : options.screenMargin) + let maxLeft = max.width - (width ?? content.width) - (found == 'left' ? arrowSize : options.screenMargin) + let maxTop = max.height - (height ?? content.height) - (found == 'top' ? arrowSize : options.screenMargin) + 3 + // adjust X + if (['top', 'bottom'].includes(found) || options.autoResize) { + if (left < minLeft) { + adjustArrow = true + adjust.left -= left + left = minLeft + } + if (left > maxLeft) { + adjustArrow = true + adjust.left -= left - maxLeft + left += maxLeft - left + } + } + // adjust Y + if (['left', 'right'].includes(found) || options.autoResize) { + if (top < minTop) { + adjustArrow = true + adjust.top -= top + top = minTop + } + if (top > maxTop) { + adjustArrow = true + adjust.top -= top - maxTop + top += maxTop - top + } + } + // moves carret to adjust it with element width + if (adjustArrow) { + let aType = isVertical ? 'left' : 'top' + let sType = isVertical ? 'width' : 'height' + arrow.offset = -adjust[aType] + let maxOffset = content[sType] / 2 - arrowSize + if (Math.abs(arrow.offset) > maxOffset + arrowSize) { + arrow.class = '' // no arrow + } + if (Math.abs(arrow.offset) > maxOffset) { + arrow.offset = arrow.offset < 0 ? -maxOffset : maxOffset + } + arrow.style = w2utils.stripSpaces(`#${overlay.id} .w2ui-overlay-body:after, + #${overlay.id} .w2ui-overlay-body:before { + --tip-size: ${arrowSize}px; + margin-${aType}: ${arrow.offset}px; + }`) + } + } + } +} +class ColorTooltip extends Tooltip { + constructor() { + super() + this.palette = [ + ['000000', '333333', '555555', '777777', '888888', '999999', 'AAAAAA', 'CCCCCC', 'DDDDDD', 'EEEEEE', 'F7F7F7', 'FFFFFF'], + ['FF011B', 'FF9838', 'FFC300', 'FFFD59', '86FF14', '14FF7A', '2EFFFC', '2693FF', '006CE7', '9B24F4', 'FF21F5', 'FF0099'], + ['FFEAEA', 'FCEFE1', 'FCF4DC', 'FFFECF', 'EBFFD9', 'D9FFE9', 'E0FFFF', 'E8F4FF', 'ECF4FC', 'EAE6F4', 'FFF5FE', 'FCF0F7'], + ['F4CCCC', 'FCE5CD', 'FFF1C2', 'FFFDA1', 'D5FCB1', 'B5F7D0', 'BFFFFF', 'D6ECFF', 'CFE2F3', 'D9D1E9', 'FFE3FD', 'FFD9F0'], + ['EA9899', 'F9CB9C', 'FFE48C', 'F7F56F', 'B9F77E', '84F0B1', '83F7F7', 'B5DAFF', '9FC5E8', 'B4A7D6', 'FAB9F6', 'FFADDE'], + ['E06666', 'F6B26B', 'DEB737', 'E0DE51', '8FDB48', '52D189', '4EDEDB', '76ACE3', '6FA8DC', '8E7CC3', 'E07EDA', 'F26DBD'], + ['CC0814', 'E69138', 'AB8816', 'B5B20E', '6BAB30', '27A85F', '1BA8A6', '3C81C7', '3D85C6', '674EA7', 'A14F9D', 'BF4990'], + ['99050C', 'B45F17', '80650E', '737103', '395E14', '10783D', '13615E', '094785', '0A5394', '351C75', '780172', '782C5A'] + ] + this.defaults = w2utils.extend({}, this.defaults, { + advanced : false, + transparent : true, + position : 'top|bottom', + class : 'w2ui-white', + color : '', + liveUpdate : true, + arrowSize : 12, + autoResize : false, + anchorClass : 'w2ui-focus', + autoShowOn : 'focus', + hideOn : ['doc-click', 'focus-change'], + onSelect : null, + onLiveUpdate: null + }) + } + attach(anchor, text) { + let options + if (arguments.length == 1 && anchor.anchor) { + options = anchor + anchor = options.anchor + } else if (arguments.length === 2 && text != null && typeof text === 'object') { + options = text + options.anchor = anchor + } + let prevHideOn = options.hideOn + options = w2utils.extend({}, this.defaults, options || {}) + if (prevHideOn) { + options.hideOn = prevHideOn + } + options.style += '; padding: 0;' + // add remove transparent color + if (options.transparent && this.palette[0][1] == '333333') { + this.palette[0].splice(1, 1) + this.palette[0].push('') + } + if (!options.transparent && this.palette[0][1] != '333333') { + this.palette[0].splice(1, 0, '333333') + this.palette[0].pop() + } + if (options.color) options.color = String(options.color).toUpperCase() + if (typeof options.color === 'string' && options.color.substr(0,1) === '#') options.color = options.color.substr(1) + // needed for keyboard navigation + this.index = [-1, -1] + let ret = super.attach(options) + let overlay = ret.overlay + overlay.options.html = this.getColorHTML(overlay.name, options) + overlay.on('show.attach', event => { + let overlay = event.detail.overlay + let anchor = overlay.anchor + let options = overlay.options + if (['INPUT', 'TEXTAREA'].includes(anchor.tagName) && !options.color && anchor.value) { + overlay.tmp.initColor = anchor.value + } + delete overlay.newColor + }) + overlay.on('show:after.attach', event => { + if (ret.overlay?.box) { + let actions = query(ret.overlay.box).find('.w2ui-eaction') + w2utils.bindEvents(actions, this) + this.initControls(ret.overlay) + } + }) + overlay.on('update:after.attach', event => { + if (ret.overlay?.box) { + let actions = query(ret.overlay.box).find('.w2ui-eaction') + w2utils.bindEvents(actions, this) + this.initControls(ret.overlay) + } + }) + overlay.on('hide.attach', event => { + let overlay = event.detail.overlay + let anchor = overlay.anchor + let color = overlay.newColor ?? overlay.options.color ?? '' + if (['INPUT', 'TEXTAREA'].includes(anchor.tagName) && anchor.value != color) { + anchor.value = color + } + let edata = this.trigger('select', { color, target: overlay.name, overlay }) + if (edata.isCancelled === true) return + // event after + edata.finish() + }) + ret.liveUpdate = (callback) => { + overlay.on('liveUpdate.attach', (event) => { callback(event) }) + return ret + } + ret.select = (callback) => { + overlay.on('select.attach', (event) => { callback(event) }) + return ret + } + return ret + } + // regular panel handler, adds selection class + select(color, name) { + let target + this.index = [-1, -1] + if (typeof name != 'string') { + target = name.target + this.index = query(target).attr('index').split(':') + name = query(target).closest('.w2ui-overlay').attr('name') + } + let overlay = this.get(name) + // event before + let edata = this.trigger('liveUpdate', { color, target: name, overlay, param: arguments[1] }) + if (edata.isCancelled === true) return + // if anchor is input - live update + if (['INPUT', 'TEXTAREA'].includes(overlay.anchor.tagName) && overlay.options.liveUpdate) { + query(overlay.anchor).val(color) + } + overlay.newColor = color + query(overlay.box).find('.w2ui-selected').removeClass('w2ui-selected') + if (target) { + query(target).addClass('w2ui-selected') + } + // event after + edata.finish() + } + // used for keyboard navigation, if any + nextColor(direction) { // TODO: check it + let pal = this.palette + switch (direction) { + case 'up': + this.index[0]-- + break + case 'down': + this.index[0]++ + break + case 'right': + this.index[1]++ + break + case 'left': + this.index[1]-- + break + } + if (this.index[0] < 0) this.index[0] = 0 + if (this.index[0] > pal.length - 2) this.index[0] = pal.length - 2 + if (this.index[1] < 0) this.index[1] = 0 + if (this.index[1] > pal[0].length - 1) this.index[1] = pal[0].length - 1 + return pal[this.index[0]][this.index[1]] + } + tabClick(index, name) { + if (typeof name != 'string') { + name = query(name.target).closest('.w2ui-overlay').attr('name') + } + let overlay = this.get(name) + let tab = query(overlay.box).find(`.w2ui-color-tab:nth-child(${index})`) + query(overlay.box).find('.w2ui-color-tab').removeClass('w2ui-selected') + query(tab).addClass('w2ui-selected') + query(overlay.box) + .find('.w2ui-tab-content') + .hide() + .closest('.w2ui-colors') + .find('.tab-'+ index) + .show() + } + // generate HTML with color pallent and controls + getColorHTML(name, options) { + let html = ` +
    +
    ` + for (let i = 0; i < this.palette.length; i++) { + html += '
    ' + for (let j = 0; j < this.palette[i].length; j++) { + let color = this.palette[i][j] + let border = '' + if (color === 'FFFFFF') border = '; border: 1px solid #efefef' + html += ` +
      +
    ` + } + html += '
    ' + if (i < 2) html += '
    ' + } + html += '
    ' + // advanced tab + html += ` + ` + // color tabs on the bottom + html += ` +
    +
    +
    +
    + ${(typeof options.html == 'string' ? options.html : '')} +
    +
    ` + return html + } + // bind advanced tab controls + initControls(overlay) { + let initial // used for mouse events + let self = this + let options = overlay.options + let rgb = w2utils.parseColor(options.color || overlay.tmp.initColor) + if (rgb == null) { + rgb = { r: 140, g: 150, b: 160, a: 1 } + } + let hsv = w2utils.rgb2hsv(rgb) + if (options.advanced === true) { + this.tabClick(2, overlay.name) + } + setColor(hsv, true, true) + // even for rgb, hsv inputs + query(overlay.box).find('input') + .off('.w2color') + .on('change.w2color', (event) => { + let el = query(event.target) + let val = parseFloat(el.val()) + let max = parseFloat(el.attr('max')) + if (isNaN(val)) { + val = 0 + el.val(0) + } + if (max > 1) val = parseInt(val) // trancate fractions + if (max > 0 && val > max) { + el.val(max) + val = max + } + if (val < 0) { + el.val(0) + val = 0 + } + let name = el.attr('name') + let color = {} + if (['r', 'g', 'b', 'a'].indexOf(name) !== -1) { + rgb[name] = val + hsv = w2utils.rgb2hsv(rgb) + } else if (['h', 's', 'v'].indexOf(name) !== -1) { + color[name] = val + } + setColor(color, true) + }) + // click on original color resets it + query(overlay.box).find('.color-original') + .off('.w2color') + .on('click.w2color', (event) => { + let tmp = w2utils.parseColor(query(event.target).css('background-color')) + if (tmp != null) { + rgb = tmp + hsv = w2utils.rgb2hsv(rgb) + setColor(hsv, true) + } + }) + // color sliders events + let mDown = `${!w2utils.isIOS ? 'mousedown' : 'touchstart'}.w2color` + let mUp = `${!w2utils.isIOS ? 'mouseup' : 'touchend'}.w2color` + let mMove = `${!w2utils.isIOS ? 'mousemove' : 'touchmove'}.w2color` + query(overlay.box).find('.palette, .rainbow, .alpha') + .off('.w2color') + .on(`${mDown}.w2color`, mouseDown) + return + function setColor(color, fullUpdate, initial) { + if (color.h != null) hsv.h = color.h + if (color.s != null) hsv.s = color.s + if (color.v != null) hsv.v = color.v + if (color.a != null) { rgb.a = color.a; hsv.a = color.a } + rgb = w2utils.hsv2rgb(hsv) + let newColor = 'rgba('+ rgb.r +','+ rgb.g +','+ rgb.b +','+ rgb.a +')' + let cl = [ + Number(rgb.r).toString(16).toUpperCase(), + Number(rgb.g).toString(16).toUpperCase(), + Number(rgb.b).toString(16).toUpperCase(), + (Math.round(Number(rgb.a)*255)).toString(16).toUpperCase() + ] + cl.forEach((item, ind) => { if (item.length === 1) cl[ind] = '0' + item }) + newColor = cl[0] + cl[1] + cl[2] + cl[3] + if (rgb.a === 1) { + newColor = cl[0] + cl[1] + cl[2] + } + query(overlay.box).find('.color-preview').css('background-color', '#' + newColor) + query(overlay.box).find('input').each(el => { + if (el.name) { + if (rgb[el.name] != null) el.value = rgb[el.name] + if (hsv[el.name] != null) el.value = hsv[el.name] + if (el.name === 'a') el.value = rgb.a + } + }) + // if it is in pallette + if (initial) { + let color = overlay.tmp?.initColor || newColor + query(overlay.box).find('.color-original') + .css('background-color', '#'+color) + query(overlay.box).find('.w2ui-colors .w2ui-selected') + .removeClass('w2ui-selected') + query(overlay.box).find(`.w2ui-colors [name="${color}"]`) + .addClass('w2ui-selected') + // if has transparent color, open advanced tab + if (newColor.length == 8) { + self.tabClick(2, overlay.name) + } + } else { + self.select(newColor, overlay.name) + } + if (fullUpdate) { + updateSliders() + refreshPalette() + } + } + function updateSliders() { + let el1 = query(overlay.box).find('.palette .value1') + let el2 = query(overlay.box).find('.rainbow .value2') + let el3 = query(overlay.box).find('.alpha .value2') + let offset1 = parseInt(el1[0].clientWidth) / 2 + let offset2 = parseInt(el2[0].clientWidth) / 2 + el1.css({ + 'left': (hsv.s * 150 / 100 - offset1) + 'px', + 'top': ((100 - hsv.v) * 125 / 100 - offset1) + 'px' + }) + el2.css('left', (hsv.h/(360/150) - offset2) + 'px') + el3.css('left', (rgb.a*150 - offset2) + 'px') + } + function refreshPalette() { + let cl = w2utils.hsv2rgb(hsv.h, 100, 100) + let rgb = `${cl.r},${cl.g},${cl.b}` + query(overlay.box).find('.palette') + .css('background-image', `linear-gradient(90deg, rgba(${rgb},0) 0%, rgba(${rgb},1) 100%)`) + } + function mouseDown(event) { + let el = query(this).find('.value1, .value2') + let offset = parseInt(el.prop('clientWidth')) / 2 + if (el.hasClass('move-x')) el.css({ left: (event.offsetX - offset) + 'px' }) + if (el.hasClass('move-y')) el.css({ top: (event.offsetY - offset) + 'px' }) + initial = { + el : el, + x : event.pageX, + y : event.pageY, + width : el.prop('parentNode').clientWidth, + height : el.prop('parentNode').clientHeight, + left : parseInt(el.css('left')), + top : parseInt(el.css('top')) + } + mouseMove(event) + query('body') + .off('.w2color') + .on(mMove, mouseMove) + .on(mUp, mouseUp) + } + function mouseUp(event) { + query('body').off('.w2color') + } + function mouseMove(event) { + let el = initial.el + let divX = event.pageX - initial.x + let divY = event.pageY - initial.y + let newX = initial.left + divX + let newY = initial.top + divY + let offset = parseInt(el.prop('clientWidth')) / 2 + if (newX < -offset) newX = -offset + if (newY < -offset) newY = -offset + if (newX > initial.width - offset) newX = initial.width - offset + if (newY > initial.height - offset) newY = initial.height - offset + if (el.hasClass('move-x')) el.css({ left : newX + 'px' }) + if (el.hasClass('move-y')) el.css({ top : newY + 'px' }) + // move + let name = query(el.get(0).parentNode).attr('name') + let x = parseInt(el.css('left')) + offset + let y = parseInt(el.css('top')) + offset + if (name === 'palette') { + setColor({ + s: Math.round(x / initial.width * 100), + v: Math.round(100 - (y / initial.height * 100)) + }) + } + if (name === 'rainbow') { + let h = Math.round(360 / 150 * x) + setColor({ h: h }) + refreshPalette() + } + if (name === 'alpha') { + setColor({ a: parseFloat(Number(x / 150).toFixed(2)) }) + } + } + } +} +class MenuTooltip extends Tooltip { + constructor() { + super() + // ITEM STRUCTURE + // item : { + // id : null, + // text : '', + // style : '', + // icon : '', + // count : '', + // tooltip : '', + // hotkey : '', + // remove : false, + // items : [] + // indent : 0, + // type : null, // check/radio + // group : false, // groupping for checks + // expanded : false, + // hidden : false, + // checked : null, + // disabled : false + // ... + // } + this.defaults = w2utils.extend({}, this.defaults, { + type : 'normal', // can be normal, radio, check + items : [], + index : null, // current selected + render : null, + spinner : false, + msgNoItems : w2utils.lang('No items found'), + topHTML : '', + menuStyle : '', + filter : false, + markSearch : false, + match : 'contains', // is, begins, ends, contains + search : false, // top search TODO: Check + altRows : false, + arrowSize : 10, + align : 'left', + position : 'bottom|top', + class : 'w2ui-white', + anchorClass : 'w2ui-focus', + autoShowOn : 'focus', + hideOn : ['doc-click', 'focus-change', 'select'], // also can 'item-remove' + onSelect : null, + onSubMenu : null, + onRemove : null + }) + } + attach(anchor, text) { + let options + if (arguments.length == 1 && anchor.anchor) { + options = anchor + anchor = options.anchor + } else if (arguments.length === 2 && text != null && typeof text === 'object') { + options = text + options.anchor = anchor + } + let prevHideOn = options.hideOn + options = w2utils.extend({}, this.defaults, options || {}) + if (prevHideOn) { + options.hideOn = prevHideOn + } + options.style += '; padding: 0;' + if (options.items == null) { + options.items = [] + } + options.html = this.getMenuHTML(options) + let ret = super.attach(options) + let overlay = ret.overlay + overlay.on('show:after.attach, update:after.attach', event => { + if (ret.overlay?.box) { + let search = '' + // reset selected and active chain + overlay.selected = null + overlay.options.items = w2utils.normMenu(overlay.options.items) + if (['INPUT', 'TEXTAREA'].includes(overlay.anchor.tagName)) { + search = overlay.anchor.value + overlay.selected = overlay.anchor.dataset.selectedIndex + } + let actions = query(ret.overlay.box).find('.w2ui-eaction') + w2utils.bindEvents(actions, this) + this.applyFilter(overlay.name, null, search) + .then(data => { + overlay.tmp.searchCount = data.count + overlay.tmp.search = data.search + this.refreshSearch(overlay.name) + this.initControls(ret.overlay) + this.refreshIndex(overlay.name) + }) + } + }) + overlay.on('hide:after.attach', event => { + w2tooltip.hide(overlay.name + '-tooltip') + }) + ret.select = (callback) => { + overlay.on('select.attach', (event) => { callback(event) }) + return ret + } + ret.remove = (callback) => { + overlay.on('remove.attach', (event) => { callback(event) }) + return ret + } + ret.subMenu = (callback) => { + overlay.on('subMenu.attach', (event) => { callback(event) }) + return ret + } + return ret + } + update(name, items) { + let overlay = Tooltip.active[name] + if (overlay) { + let options = overlay.options + if (options.items != items) { + options.items = items + } + let menuHTML = this.getMenuHTML(options) + if (options.html != menuHTML) { + options.html = menuHTML + overlay.needsUpdate = true + this.show(name) + } + } else { + console.log(`Tooltip "${name}" is not displayed. Cannot update it.`) + } + } + initControls(overlay) { + query(overlay.box).find('.w2ui-menu:not(.w2ui-sub-menu)') + .off('.w2menu') + .on('mouseDown.w2menu', { delegate: '.w2ui-menu-item' }, event => { + let dt = event.delegate.dataset + this.menuDown(overlay, event, dt.index, dt.parents) + }) + .on((w2utils.isIOS ? 'touchStart' : 'click') + '.w2menu', { delegate: '.w2ui-menu-item' }, event => { + let dt = event.delegate.dataset + this.menuClick(overlay, event, parseInt(dt.index), dt.parents) + }) + .find('.w2ui-menu-item') + .off('.w2menu') + .on('mouseEnter.w2menu', event => { + let dt = event.target.dataset + let tooltip = overlay.options.items[dt.index]?.tooltip + if (tooltip) { + w2tooltip.show({ + name: overlay.name + '-tooltip', + anchor: event.target, + html: tooltip, + position: 'right|left', + hideOn: ['doc-click'] + }) + } + }) + .on('mouseLeave.w2menu', event => { + w2tooltip.hide(overlay.name + '-tooltip') + }) + if (['INPUT', 'TEXTAREA'].includes(overlay.anchor.tagName)) { + query(overlay.anchor) + .off('.w2menu') + .on('input.w2menu', event => { + // if user types, clear selection + // let dt = event.target.dataset + // delete dt.selected + // delete dt.selectedIndex + }) + .on('keyup.w2menu', event => { + event._searchType = 'filter' + this.keyUp(overlay, event) + }) + } + if (overlay.options.search) { + query(overlay.box).find('#menu-search') + .off('.w2menu') + .on('keyup.w2menu', event => { + event._searchType = 'search' + this.keyUp(overlay, event) + }) + } + } + getCurrent(name, id) { + let overlay = Tooltip.active[name.replace(/[\s\.#]/g, '_')] + let options = overlay.options + let selected = (id ? id : overlay.selected ?? '').split('-') + let last = selected.length-1 + let index = selected[last] + let parents = selected.slice(0, selected.length-1).join('-') + index = w2utils.isInt(index) ? parseInt(index) : 0 + // items + let items = options.items + selected.forEach((id, ind) => { + // do not go to the last one + if (ind < selected.length - 1) { + items = items[id].items + } + }) + return { last, index, items, item: items[index], parents } + } + getMenuHTML(options, items, subMenu, parentIndex) { + if (options.spinner) { + return ` +
    +
    +
    + ${w2utils.lang('Loading...')} +
    +
    ` + } + if (!parentIndex) parentIndex = [] + if (items == null) { + items = options.items + } + if (!Array.isArray(items)) items = [] + let count = 0 + let icon = null + let topHTML = '' + if (!subMenu && options.search) { + topHTML += ` + ` + items.forEach(item => item.hidden = false) + } + if (!subMenu && options.topHTML) { + topHTML += `
    ${options.topHTML}
    ` + } + let menu_html = ` + ${topHTML} +
    + ` + items.forEach((mitem, f) => { + icon = mitem.icon + let index = (parentIndex.length > 0 ? parentIndex.join('-') + '-' : '') + f + if (icon == null) icon = null // icon might be undefined + if (['radio', 'check'].indexOf(options.type) != -1 && !Array.isArray(mitem.items) && mitem.group !== false) { + if (mitem.checked === true) icon = 'w2ui-icon-check'; else icon = 'w2ui-icon-empty' + } + if (mitem.hidden !== true) { + let txt = mitem.text + let icon_dsp = '' + let subMenu_dsp = '' + if (typeof options.render === 'function') txt = options.render(mitem, options) + if (typeof txt == 'function') txt = txt(mitem, options) + if (icon) { + if (String(icon).slice(0, 1) !== '<') { + icon = `` + } + icon_dsp = `` + } + // render only if non-empty + if (mitem.type !== 'break' && txt != null && txt !== '' && String(txt).substr(0, 2) != '--') { + let classes = ['w2ui-menu-item'] + if (options.altRows == true) { + classes.push(count % 2 === 0 ? 'w2ui-even' : 'w2ui-odd') + } + let colspan = 1 + if (icon_dsp === '') colspan++ + if (mitem.count == null && mitem.hotkey == null && mitem.remove !== true && mitem.items == null) colspan++ + if (mitem.tooltip == null && mitem.hint != null) mitem.tooltip = mitem.hint // for backward compatibility + let count_dsp = '' + if (mitem.remove === true) { + count_dsp = 'x' + } else if (mitem.items != null) { + let _items = [] + if (typeof mitem.items == 'function') { + _items = mitem.items(mitem) + } else if (Array.isArray(mitem.items)) { + _items = mitem.items + } + count_dsp = '' + subMenu_dsp = ` +
    + ${this.getMenuHTML(options, _items, true, parentIndex.concat(f))} +
    ` + } else { + if (mitem.count != null) count_dsp += '' + mitem.count + '' + if (mitem.hotkey != null) count_dsp += '' + mitem.hotkey + '' + } + if (mitem.disabled === true) classes.push('w2ui-disabled') + if (mitem._noSearchInside === true) classes.push('w2ui-no-search-inside') + if (subMenu_dsp !== '') { + classes.push('has-sub-menu') + if (mitem.expanded) { + classes.push('expanded') + } else { + classes.push('collapsed') + } + } + menu_html += ` +
    +
    + ${icon_dsp} + + +
    + ${subMenu_dsp}` + count++ + } else { + // horizontal line + let divText = (txt ?? '').replace(/^-+/g, '') + menu_html += ` +
    +
    + ${divText ? `
    ${divText}
    ` : ''} +
    ` + } + } + items[f] = mitem + }) + if (count === 0 && options.msgNoItems) { + menu_html += ` +
    + ${w2utils.lang(options.msgNoItems)} +
    ` + } + menu_html += '
    ' + return menu_html + } + // Refreshed only selected item highligh, used in keyboard navigation + refreshIndex(name) { + let overlay = Tooltip.active[name.replace(/[\s\.#]/g, '_')] + if (!overlay) return + if (!overlay.displayed) { + this.show(overlay.name) + } + let view = query(overlay.box).find('.w2ui-overlay-body').get(0) + let search = query(overlay.box).find('.w2ui-menu-search, .w2ui-menu-top').get(0) + query(overlay.box).find('.w2ui-menu-item.w2ui-selected') + .removeClass('w2ui-selected') + let el = query(overlay.box).find(`.w2ui-menu-item[index="${overlay.selected}"]`) + .addClass('w2ui-selected') + .get(0) + if (el) { + if (el.offsetTop + el.clientHeight > view.clientHeight + view.scrollTop) { + el.scrollIntoView({ behavior: 'smooth', block: 'start', inline: 'start' }) + } + if (el.offsetTop < view.scrollTop + (search ? search.clientHeight : 0)) { + el.scrollIntoView({ behavior: 'smooth', block: 'end', inline: 'end' }) + } + } + } + // show/hide searched items + refreshSearch(name) { + let overlay = Tooltip.active[name.replace(/[\s\.#]/g, '_')] + if (!overlay) return + if (!overlay.displayed) { + this.show(overlay.name) + } + query(overlay.box).find('.w2ui-no-items').hide() + query(overlay.box).find('.w2ui-menu-item, .w2ui-menu-divider').each(el => { + let cur = this.getCurrent(name, el.getAttribute('index')) + if (cur.item?.hidden) { + query(el).hide() + } else { + let search = overlay.tmp?.search + if (search && overlay.options.markSearch) { + w2utils.marker(el, search, { onlyFirst: overlay.options.match == 'begins' }) + } + query(el).show() + } + }) + // hide empty menus + query(overlay.box).find('.w2ui-sub-menu').each(sub => { + let hasItems = query(sub).find('.w2ui-menu-item').get().some(el => { + return el.style.display != 'none' ? true : false + }) + let parent = this.getCurrent(name, sub.dataset.parent) + // only if parent is expaneded + if (parent.item.expanded) { + if (!hasItems) { + query(sub).parent().hide() + } else { + query(sub).parent().show() + } + } + }) + // show empty message + if (overlay.tmp.searchCount == 0 || overlay.options?.items?.length == 0) { + if (query(overlay.box).find('.w2ui-no-items').length == 0) { + query(overlay.box).find('.w2ui-menu:not(.w2ui-sub-menu)').append(` +
    + ${w2utils.lang(overlay.options.msgNoItems)} +
    `) + } + query(overlay.box).find('.w2ui-no-items').show() + } + } + /** + * Loops through the items and markes item.hidden = true for those that need to be hidden, and item.hidden = false + * for those that are visible. Return a promise (since items can be on the server) with the number of visible items. + */ + applyFilter(name, items, search, debounce) { + let count = 0 + let overlay = Tooltip.active[name.replace(/[\s\.#]/g, '_')] + let options = overlay.options + let resolve, reject + let prom = new Promise((res, rej) => { + resolve = res + reject = rej + }) + if (search == null) { + if (['INPUT', 'TEXTAREA'].includes(overlay.anchor.tagName)) { + search = overlay.anchor.value + } else { + search = '' + } + } + let selectedIds = [] + if (options.selected) { + if (Array.isArray(options.selected)) { + selectedIds = options.selected.map(item => { + return item?.id ?? item + }) + } else if (options.selected?.id) { + selectedIds = [options.selected.id] + } + } + overlay.tmp.activeChain = null + // if url is defined, get items from it + let remote = overlay.tmp.remote ?? { hasMore: true, emtpySet: false, search: null, total: -1 } + if (items == null && options.url && remote.hasMore && remote.search !== search) { + let proceed = true + // only when items == null because it is case of nested items + let msg = w2utils.lang('Loading...') + if (search.length < options.minLength && remote.emptySet !== true) { + msg = w2utils.lang('${count} letters or more...', { count: options.minLength }) + proceed = false + if (search === '') { + msg = w2utils.lang(options.msgSearch) + } + } + query(overlay.box).find('.w2ui-no-items').html(msg) + remote.search = search + options.items = [] + overlay.tmp.remote = remote + if (proceed) { + this.request(overlay, search, debounce) + .then(remoteItems => { + this.update(name, remoteItems) + this.applyFilter(name, null, search).then(data => { + resolve(data) + }) + }) + .catch(error => { + console.log('Server Request error', error) + }) + } + return prom + } + let edata + // only trigger search event when data is present and for the top level + if (items == null) { + edata = this.trigger('search', { search, overlay, prom, resolve, reject }) + if (edata.isCancelled === true) { + return prom + } + } + if (items == null) { + items = overlay.options.items + } + if (options.filter === false) { + resolve({ count: -1, search }) + return prom + } + items.forEach(item => { + let prefix = '' + let suffix = '' + if (['is', 'begins', 'begins with'].indexOf(options.match) !== -1) prefix = '^' + if (['is', 'ends', 'ends with'].indexOf(options.match) !== -1) suffix = '$' + try { + let re = new RegExp(prefix + search + suffix, 'i') + if (re.test(item.text) || item.text === '...') { + item.hidden = false + } else { + item.hidden = true + } + } catch (e) {} + // do not show selected items + if (options.hideSelected && selectedIds.includes(item.id)) { + item.hidden = true + } + // search nested items + if (Array.isArray(item.items) && item.items.length > 0) { + delete item._noSearchInside + this.applyFilter(name, item.items, search).then(data => { + let subCount = data.count + if (subCount > 0) { + count += subCount + if (item.hidden) item._noSearchInside = true + // only expand items if search is not empty + if (search) item.expanded = true + item.hidden = false + } + }) + } + if (item.hidden !== true) count++ + }) + resolve({ count, search }) + edata?.finish() + return prom + } + request(overlay, search, debounce) { + let options = overlay.options + let remote = overlay.tmp.remote + let resolve, reject // promise functions + if ((options.items.length === 0 && remote.total !== 0) + || (remote.total == options.cacheMax && search.length > remote.search.length) + || (search.length >= remote.search.length && search.substr(0, remote.search.length) !== remote.search) + || (search.length < remote.search.length)) + { + // Aabort previous request if any + if (remote.controller) { + remote.controller.abort() + } + remote.loading = true + clearTimeout(remote.timeout) + remote.timeout = setTimeout(() => { + let url = options.url + let postData = { search, max: options.cacheMax } + Object.assign(postData, options.postData) + // trigger event + let edata = this.trigger('request', { + search, overlay, url, postData, + httpMethod: options.method ?? 'GET', + httpHeaders: {} + }) + if (edata.isCancelled === true) return + // if event updated url and postData, use it + url = new URL(edata.detail.url, location) + let fetchOptions = w2utils.prepareParams(url, { + method: edata.detail.httpMethod, + headers: edata.detail.httpHeaders, + body: edata.detail.postData + }) + // Create new abort controller + remote.controller = new AbortController() + fetchOptions.signal = remote.controller.signal + // send request + fetch(url, fetchOptions) + .then(resp => resp.json()) + .then(data => { + remote.controller = null + // trigger event + let edata = overlay.trigger('load', { search: postData.search, overlay, data }) + if (edata.isCancelled === true) return + // default behavior + data = edata.detail.data + if (typeof data === 'string') data = JSON.parse(data) + // if server just returns array + if (Array.isArray(data)) { + data = { records: data } + } + // needed for backward compatibility + if (data.records == null && data.items != null) { + data.records = data.items + delete data.items + } + // handles Golang marshal of empty arrays to null + if (!data.error && data.records == null) { + data.records = [] + } + if (!Array.isArray(data.records)) { + console.error('ERROR: server did not return proper data structure', '\n', + ' - it should return', { records: [{ id: 1, text: 'item' }] }, '\n', + ' - or just an array ', [{ id: 1, text: 'item' }], '\n', + ' - or if errorr ', { error: true, message: 'error message' }) + return + } + // remove all extra items if more then needed for cache + if (data.records.length >= options.cacheMax) { + data.records.splice(options.cacheMax, data.records.length) + remote.hasMore = true + } else { + remote.hasMore = false + } + // map id and text + if (options.recId == null && options.recid != null) options.recId = options.recid // since lower-case recid is used in grid + if (options.recId || options.recText) { + data.records.forEach((item) => { + if (typeof options.recId === 'string') item.id = item[options.recId] + if (typeof options.recId === 'function') item.id = options.recId(item) + if (typeof options.recText === 'string') item.text = item[options.recText] + if (typeof options.recText === 'function') item.text = options.recText(item) + }) + } + // remember stats + remote.loading = false + remote.search = search + remote.total = data.records.length + remote.lastError = '' + remote.emptySet = (search === '' && data.records.length === 0 ? true : false) + // event after + edata.finish() + resolve(w2utils.normMenu(data.records)) + }) + .catch(error => { + let edata = this.trigger('error', { overlay, search, error }) + if (edata.isCancelled === true) return + // default behavior + if (error?.name !== 'AbortError') { + console.error('ERROR: Server communication failed.', '\n', + ' - it should return', { records: [{ id: 1, text: 'item' }] }, '\n', + ' - or just an array ', [{ id: 1, text: 'item' }], '\n', + ' - or if errorr ', { error: true, message: 'error message' }) + } + // reset stats + remote.loading = false + remote.search = '' + remote.total = -1 + remote.emptySet = true + remote.lastError = (edata.detail.error || 'Server communication failed') + options.items = [] + // event after + edata.finish() + reject() + }) + // event after + edata.finish() + }, debounce ? (options.debounce ?? 350) : 0) + } + return new Promise((res, rej) => { + resolve = res + reject = rej + }) + } + /** + * Builds an array of item ids that sequencial in navigation with up/down keys. + * Skips hidden and disabled items and goes into nested structures. + */ + getActiveChain(name, items, parents = [], res = [], noSave) { + let overlay = Tooltip.active[name.replace(/[\s\.#]/g, '_')] + if (overlay.tmp.activeChain != null) { + return overlay.tmp.activeChain + } + if (items == null) items = overlay.options.items + items.forEach((item, ind) => { + if (!item.hidden && !item.disabled && !item?.text?.startsWith('--')) { + res.push(parents.concat([ind]).join('-')) + if (Array.isArray(item.items) && item.items.length > 0 && item.expanded) { + parents.push(ind) + this.getActiveChain(name, item.items, parents, res, true) + parents.pop() + } + } + }) + if (noSave == null) { + overlay.tmp.activeChain = res + } + return res + } + menuDown(overlay, event, index, parentIndex) { + let options = overlay.options + let items = options.items + let icon = query(event.delegate).find('.w2ui-icon') + let menu = query(event.target).closest('.w2ui-menu:not(.w2ui-sub-menu)') + if (typeof parentIndex == 'string' && parentIndex !== '') { + let ids = parentIndex.split('-') + ids.forEach(id => { + items = items[id].items + }) + } + let item = items[index] + if (item.disabled) { + return + } + let uncheck = (items, parent) => { + items.forEach((other, ind) => { + if (other.id == item.id) return + if (other.group === item.group && other.checked) { + menu + .find(`.w2ui-menu-item[index="${(parent ? parent + '-' : '') + ind}"] .w2ui-icon`) + .removeClass('w2ui-icon-check') + .addClass('w2ui-icon-empty') + items[ind].checked = false + } + if (Array.isArray(other.items)) { + uncheck(other.items, ind) + } + }) + } + if ((options.type === 'check' || options.type === 'radio') && item.group !== false + && !query(event.target).hasClass('remove') + && !query(event.target).closest('.w2ui-menu-item').hasClass('has-sub-menu')) { + item.checked = options.type == 'radio' ? true : !item.checked + if (item.checked) { + if (options.type === 'radio') { + query(event.target).closest('.w2ui-menu').find('.w2ui-icon') + .removeClass('w2ui-icon-check') + .addClass('w2ui-icon-empty') + } + if (options.type === 'check' && item.group != null) { + uncheck(options.items) + } + icon.removeClass('w2ui-icon-empty').addClass('w2ui-icon-check') + } else if (options.type === 'check') { + icon.removeClass('w2ui-icon-check').addClass('w2ui-icon-empty') + } + } + // highlight record + if (!query(event.target).hasClass('remove')) { + menu.find('.w2ui-menu-item').removeClass('w2ui-selected') + query(event.delegate).addClass('w2ui-selected') + } + } + menuClick(overlay, event, index, parentIndex) { + let options = overlay.options + let items = options.items + let $item = query(event.delegate).closest('.w2ui-menu-item') + let keepOpen = options.hideOn.includes('select') ? false : true + if (event.shiftKey || event.metaKey || event.ctrlKey) { + keepOpen = true + } + if (typeof parentIndex == 'string' && parentIndex !== '') { + let ids = parentIndex.split('-') + ids.forEach(id => { + items = items[id].items + }) + } else { + parentIndex = null + } + if (typeof items == 'function') { + items = items({ overlay, index, parentIndex, event }) + } + let item = items[index] + if (item.disabled && !query(event.target).hasClass('remove')) { + return + } + let edata + if (query(event.target).hasClass('remove')) { + edata = this.trigger('remove', { originalEvent: event, target: overlay.name, + overlay, item, index, parentIndex, el: $item[0] }) + if (edata.isCancelled === true) { + return + } + keepOpen = !options.hideOn.includes('item-remove') + $item.remove() + } else if ($item.hasClass('has-sub-menu')) { + edata = this.trigger('subMenu', { originalEvent: event, target: overlay.name, + overlay, item, index, parentIndex, el: $item[0] }) + if (edata.isCancelled === true) { + return + } + keepOpen = true + if ($item.hasClass('expanded')) { + item.expanded = false + $item.removeClass('expanded').addClass('collapsed') + query($item.get(0).nextElementSibling).hide() + overlay.selected = parseInt($item.attr('index')) + } else { + item.expanded = true + $item.addClass('expanded').removeClass('collapsed') + query($item.get(0).nextElementSibling).show() + overlay.selected = parseInt($item.attr('index')) + } + } else { + // find items that are selected + let selected = this.findChecked(options.items) + overlay.selected = parseInt($item.attr('index')) + edata = this.trigger('select', { originalEvent: event, target: overlay.name, + overlay, item, index, parentIndex, selected, keepOpen, el: $item[0] }) + if (edata.isCancelled === true) { + return + } + if (item.keepOpen != null) { + keepOpen = item.keepOpen + } + if (['INPUT', 'TEXTAREA'].includes(overlay.anchor.tagName)) { + overlay.anchor.dataset.selected = item.id + overlay.anchor.dataset.selectedIndex = overlay.selected + } + } + if (!keepOpen) { + this.hide(overlay.name) + } + // if (['INPUT', 'TEXTAREA'].includes(overlay.anchor.tagName)) { + // overlay.anchor.focus() + // } + // event after + edata.finish() + } + findChecked(items) { + let found = [] + items.forEach(item => { + if (item.checked) found.push(item) + if (Array.isArray(item.items)) { + found = found.concat(this.findChecked(item.items)) + } + }) + return found + } + keyUp(overlay, event) { + let options = overlay.options + let search = event.target.value + let filter = true + let refreshIndex = false + switch (event.keyCode) { + case 46: // delete + case 8: { // backspace + // if search empty and delete is clicked, do not filter nor show overlay + if (search === '' && !overlay.displayed) filter = false + break + } + case 13: { // enter + if (!overlay.displayed || !overlay.selected) return + let { index, parents } = this.getCurrent(overlay.name) + event.delegate = query(overlay.box).find('.w2ui-selected').get(0) + // reset active chain for folders + this.menuClick(overlay, event, parseInt(index), parents) + filter = false + break + } + case 27: { // escape + filter = false + if (overlay.displayed) { + this.hide(overlay.name) + } else { + // clear selected + let el = overlay.anchor + if (['INPUT', 'TEXTAREA'].includes(el.tagName)) { + el.value = '' + delete el.dataset.selected + delete el.dataset.selectedIndex + } + } + break + } + case 37: { // left + if (!overlay.displayed) return + let { item, index, parents } = this.getCurrent(overlay.name) + // collapse parent if any + if (parents) { + item = options.items[parents] + index = parseInt(parents) + parents = '' + refreshIndex = true + } + if (Array.isArray(item?.items) && item.items.length > 0 && item.expanded) { + event.delegate = query(overlay.box).find(`.w2ui-menu-item[index="${index}"]`).get(0) + overlay.selected = index + this.menuClick(overlay, event, parseInt(index), parents) + } + filter = false + break + } + case 39: { // right + if (!overlay.displayed) return + let { item, index, parents } = this.getCurrent(overlay.name) + if (Array.isArray(item?.items) && item.items.length > 0 && !item.expanded) { + event.delegate = query(overlay.box).find('.w2ui-selected').get(0) + this.menuClick(overlay, event, parseInt(index), parents) + } + filter = false + break + } + case 38: { // up + if (!overlay.displayed) { + break + } + let chain = this.getActiveChain(overlay.name) + if (overlay.selected == null || overlay.selected?.length == 0) { + overlay.selected = chain[chain.length-1] + } else { + let ind = chain.indexOf(overlay.selected) + // selected not in chain of items + if (ind == -1) { + overlay.selected = chain[chain.length-1] + } + // not first item + if (ind > 0) { + overlay.selected = chain[ind - 1] + } + } + filter = false + refreshIndex = true + event.preventDefault() + break + } + case 40: { // down + if (!overlay.displayed) { + break + } + let chain = this.getActiveChain(overlay.name) + if (overlay.selected == null || overlay.selected?.length == 0) { + overlay.selected = chain[0] + } else { + let ind = chain.indexOf(overlay.selected) + // selected not in chain of items + if (ind == -1) { + overlay.selected = chain[0] + } + // not the last item + if (ind < chain.length - 1) { + overlay.selected = chain[ind + 1] + } + } + filter = false + refreshIndex = true + event.preventDefault() + break + } + } + // filter + if (filter && overlay.displayed + && ((options.filter && event._searchType == 'filter') || (options.search && event._searchType == 'search'))) { + this.applyFilter(overlay.name, null, search, true) + .then(data => { + overlay.tmp.searchCount = data.count + overlay.tmp.search = data.search + // if selected is not in searched items + if (data.count === 0 || !this.getActiveChain(overlay.name).includes(overlay.selected)) { + overlay.selected = null + } + this.refreshSearch(overlay.name) + }) + } + if (refreshIndex) { + this.refreshIndex(overlay.name) + } + } +} +class DateTooltip extends Tooltip { + constructor() { + super() + let td = new Date() + this.daysCount = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] + this.today = td.getFullYear() + '/' + (Number(td.getMonth()) + 1) + '/' + td.getDate() + this.defaults = w2utils.extend({}, this.defaults, { + position : 'top|bottom', + class : 'w2ui-calendar', + type : 'date', // can be date/time/datetime + format : '', + value : '', // initial date (in w2utils.settings format) + start : null, + end : null, + blockDates : [], // array of blocked dates + blockWeekdays : [], // blocked weekdays 0 - sunday, 1 - monday, etc + colored : {}, // ex: { '3/13/2022': 'bg-color|text-color' } + arrowSize : 12, + autoResize : false, + anchorClass : 'w2ui-focus', + autoShowOn : 'focus', + hideOn : ['doc-click', 'focus-change'], + onSelect : null + }) + } + attach(anchor, text) { + let options + if (arguments.length == 1 && anchor.anchor) { + options = anchor + anchor = options.anchor + } else if (arguments.length === 2 && text != null && typeof text === 'object') { + options = text + options.anchor = anchor + } + let prevHideOn = options.hideOn + options = w2utils.extend({}, this.defaults, options || {}) + if (prevHideOn) { + options.hideOn = prevHideOn + } + if (!options.format) { + let df = w2utils.settings.dateFormat + let tf = w2utils.settings.timeFormat + if (options.type == 'date') { + options.format = df + } else if (options.type == 'time') { + options.format = tf + } else { + options.format = df + '|' + tf + } + } + let cal = options.type == 'time' ? this.getHourHTML(options) : this.getMonthHTML(options) + options.style += '; padding: 0;' + options.html = cal.html + let ret = super.attach(options) + let overlay = ret.overlay + Object.assign(overlay.tmp, cal) + overlay.on('show.attach', event => { + let overlay = event.detail.overlay + let anchor = overlay.anchor + let options = overlay.options + if (['INPUT', 'TEXTAREA'].includes(anchor.tagName) && !options.value && anchor.value) { + overlay.tmp.initValue = anchor.value + } + delete overlay.newValue + delete overlay.newDate + }) + overlay.on('show:after.attach', event => { + if (ret.overlay?.box) { + this.initControls(ret.overlay) + } + }) + overlay.on('update:after.attach', event => { + if (ret.overlay?.box) { + this.initControls(ret.overlay) + } + }) + overlay.on('hide.attach', event => { + let overlay = event.detail.overlay + let anchor = overlay.anchor + if (overlay.newValue != null) { + if (overlay.newDate) { + overlay.newValue = overlay.newDate + ' ' + overlay.newValue + } + if (['INPUT', 'TEXTAREA'].includes(anchor.tagName) && anchor.value != overlay.newValue) { + anchor.value = overlay.newValue + } + let edata = this.trigger('select', { date: overlay.newValue, target: overlay.name, overlay }) + if (edata.isCancelled === true) return + // event after + edata.finish() + } + }) + ret.select = (callback) => { + overlay.on('select.attach', (event) => { callback(event) }) + return ret + } + return ret + } + initControls(overlay) { + let options = overlay.options + let moveMonth = (inc) => { + let { month, year } = overlay.tmp + month += inc + if (month > 12) { + month = 1 + year++ + } + if (month < 1 ) { + month = 12 + year-- + } + let cal = this.getMonthHTML(options, month, year) + Object.assign(overlay.tmp, cal) + query(overlay.box).find('.w2ui-overlay-body').html(cal.html) + this.initControls(overlay) + } + let checkJump = (event, dblclick) => { + query(event.target).parent().find('.w2ui-jump-month, .w2ui-jump-year') + .removeClass('w2ui-selected') + query(event.target).addClass('w2ui-selected') + let dt = new Date() + let { jumpMonth, jumpYear } = overlay.tmp + if (dblclick) { + if (jumpYear == null) jumpYear = dt.getFullYear() + if (jumpMonth == null) jumpMonth = dt.getMonth() + 1 + } + if (jumpMonth && jumpYear) { + let cal = this.getMonthHTML(options, jumpMonth, jumpYear) + Object.assign(overlay.tmp, cal) + query(overlay.box).find('.w2ui-overlay-body').html(cal.html) + overlay.tmp.jump = false + this.initControls(overlay) + } + } + // events for next/prev buttons and title + query(overlay.box).find('.w2ui-cal-title') + .off('.calendar') + // click on title + .on('click.calendar', event => { + Object.assign(overlay.tmp, { jumpYear: null, jumpMonth: null }) + if (overlay.tmp.jump) { + let { month, year } = overlay.tmp + let cal = this.getMonthHTML(options, month, year) + query(overlay.box).find('.w2ui-overlay-body').html(cal.html) + overlay.tmp.jump = false + } else { + query(overlay.box).find('.w2ui-overlay-body .w2ui-cal-days') + .replace(this.getYearHTML()) + let el = query(overlay.box).find(`[name="${overlay.tmp.year}"]`).get(0) + if (el) el.scrollIntoView(true) + overlay.tmp.jump = true + } + this.initControls(overlay) + event.stopPropagation() + }) + // prev button + .find('.w2ui-cal-previous') + .off('.calendar') + .on('click.calendar', event => { + moveMonth(-1) + event.stopPropagation() + }) + .parent() + // next button + .find('.w2ui-cal-next') + .off('.calendar') + .on('click.calendar', event => { + moveMonth(1) + event.stopPropagation() + }) + // now button + query(overlay.box).find('.w2ui-cal-now') + .off('.calendar') + .on('click.calendar', event => { + if (options.type == 'datetime') { + if (overlay.newDate) { + overlay.newValue = w2utils.formatTime(new Date(), options.format.split('|')[1]) + } else { + overlay.newValue = w2utils.formatDateTime(new Date(), options.format) + } + } else if (options.type == 'date') { + overlay.newValue = w2utils.formatDate(new Date(), options.format) + } else if (options.type == 'time') { + overlay.newValue = w2utils.formatTime(new Date(), options.format) + } + this.hide(overlay.name) + }) + // events for dates + query(overlay.box) + .off('.calendar') + .on('click.calendar', { delegate: '.w2ui-day.w2ui-date' }, event => { + if (options.type == 'datetime') { + overlay.newDate = query(event.target).attr('date') + query(overlay.box).find('.w2ui-overlay-body').html(this.getHourHTML(overlay.options).html) + this.initControls(overlay) + } else { + overlay.newValue = query(event.target).attr('date') + this.hide(overlay.name) + } + }) + // click on month + .on('click.calendar', { delegate: '.w2ui-jump-month' }, event => { + overlay.tmp.jumpMonth = parseInt(query(event.target).attr('name')) + checkJump(event) + }) + // double click on month + .on('dblclick.calendar', { delegate: '.w2ui-jump-month' }, event => { + overlay.tmp.jumpMonth = parseInt(query(event.target).attr('name')) + checkJump(event, true) + }) + // click on year + .on('click.calendar', { delegate: '.w2ui-jump-year' }, event => { + overlay.tmp.jumpYear = parseInt(query(event.target).attr('name')) + checkJump(event) + }) + // dbl click on year + .on('dblclick.calendar', { delegate: '.w2ui-jump-year' }, event => { + overlay.tmp.jumpYear = parseInt(query(event.target).attr('name')) + checkJump(event, true) + }) + // click on hour + .on('click.calendar', { delegate: '.w2ui-time.hour' }, event => { + let hour = query(event.target).attr('hour') + let min = this.str2min(options.value) % 60 + if (overlay.tmp.initValue && !options.value) { + min = this.str2min(overlay.tmp.initValue) % 60 + } + if (options.noMinutes) { + overlay.newValue = this.min2str(hour * 60, options.format) + this.hide(overlay.name) + } else { + overlay.newValue = hour + ':' + min + let html = this.getMinHTML(hour, options).html + query(overlay.box).find('.w2ui-overlay-body').html(html) + this.initControls(overlay) + } + }) + // click on minute + .on('click.calendar', { delegate: '.w2ui-time.min' }, event => { + let hour = Math.floor(this.str2min(overlay.newValue) / 60) + let time = (hour * 60) + parseInt(query(event.target).attr('min')) + overlay.newValue = this.min2str(time, options.format) + this.hide(overlay.name) + }) + } + getMonthHTML(options, month, year) { + let days = w2utils.settings.fulldays.slice() // creates copy of the array + let sdays = w2utils.settings.shortdays.slice() // creates copy of the array + if (w2utils.settings.weekStarts !== 'M') { + days.unshift(days.pop()) + sdays.unshift(sdays.pop()) + } + let td = new Date() + let dayLengthMil = 1000 * 60 * 60 * 24 + let selected = options.type === 'datetime' + ? w2utils.isDateTime(options.value, options.format, true) + : w2utils.isDate(options.value, options.format, true) + let selected_dsp = w2utils.formatDate(selected) + // normalize date + if (month == null || year == null) { + year = selected ? selected.getFullYear() : td.getFullYear() + month = selected ? selected.getMonth() + 1 : td.getMonth() + 1 + } + if (month > 12) { month -= 12; year++ } + if (month < 1 || month === 0) { month += 12; year-- } + if (year/4 == Math.floor(year/4)) { this.daysCount[1] = 29 } else { this.daysCount[1] = 28 } + options.current = month + '/' + year + // start with the required date + td = new Date(year, month-1, 1) + let weekDay = td.getDay() + let weekDays = '' + let st = w2utils.settings.weekStarts + for (let i = 0; i < sdays.length; i++) { + let isSat = (st == 'M' && i == 5) || (st != 'M' && i == 6) ? true : false + let isSun = (st == 'M' && i == 6) || (st != 'M' && i == 0) ? true : false + weekDays += `
    ${sdays[i]}
    ` + } + let html = ` +
    +
    +
    +
    +
    +
    +
    + ${w2utils.settings.fullmonths[month-1]}, ${year} + +
    +
    + ${weekDays} + ` + let DT = new Date(`${year}/${month}/1`) // first of month + /** + * Move to noon, instead of midnight. If not, then the date when time saving happens + * will be duplicated in the calendar + */ + DT = new Date(DT.getTime() + dayLengthMil * 0.5) + let weekday = DT.getDay() + if (w2utils.settings.weekStarts == 'M') weekDay-- + if (weekday > 0) { + DT = new Date(DT.getTime() - (weekDay * dayLengthMil)) + } + for (let ci = 0; ci < 42; ci++) { + let className = [] + let dt = `${DT.getFullYear()}/${DT.getMonth()+1}/${DT.getDate()}` + if (DT.getDay() === 6) className.push('w2ui-saturday') + if (DT.getDay() === 0) className.push('w2ui-sunday') + if (DT.getMonth() + 1 !== month) className.push('outside') + if (dt == this.today) className.push('w2ui-today') + let dspDay = DT.getDate() + let col = '' + let bgcol = '' + let tmp_dt, tmp_dt_fmt + if (options.type === 'datetime') { + tmp_dt = w2utils.formatDateTime(dt, options.format) + tmp_dt_fmt = w2utils.formatDate(dt, w2utils.settings.dateFormat) + } else { + tmp_dt = w2utils.formatDate(dt, options.format) + tmp_dt_fmt = tmp_dt + } + if (options.colored && options.colored[tmp_dt_fmt] !== undefined) { // if there is predefined colors for dates + let tmp = options.colored[tmp_dt_fmt].split('|') + bgcol = 'background-color: ' + tmp[0] + ';' + col = 'color: ' + tmp[1] + ';' + } + html += `
    + ${dspDay} +
    ` + DT = new Date(DT.getTime() + dayLengthMil) + } + html += '
    ' + if (options.btnNow) { + let label = w2utils.lang('Today' + (options.type == 'datetime' ? ' & Now' : '')) + html += `
    ${label}
    ` + } + return { html, month, year } + } + getYearHTML() { + let mhtml = '' + let yhtml = '' + for (let m = 0; m < w2utils.settings.fullmonths.length; m++) { + mhtml += `
    ${w2utils.settings.shortmonths[m]}
    ` + } + for (let y = w2utils.settings.dateStartYear; y <= w2utils.settings.dateEndYear; y++) { + yhtml += `
    ${y}
    ` + } + return `
    +
    ${mhtml}
    +
    ${yhtml}
    +
    ` + } + getHourHTML(options) { + options = options ?? {} + if (!options.format) options.format = w2utils.settings.timeFormat + let h24 = (options.format.indexOf('h24') > -1) + let value = options.value ? options.value : (options.anchor ? options.anchor.value : '') + let tmp = [] + for (let a = 0; a < 24; a++) { + let time = (a >= 12 && !h24 ? a - 12 : a) + ':00' + (!h24 ? (a < 12 ? ' am' : ' pm') : '') + if (a == 12 && !h24) time = '12:00 pm' + if (!tmp[Math.floor(a/8)]) tmp[Math.floor(a/8)] = '' + let tm1 = this.min2str(this.str2min(time)) + let tm2 = this.min2str(this.str2min(time) + 59) + if (options.type === 'datetime') { + let dt = w2utils.isDateTime(value, options.format, true) + let fm = options.format.split('|')[0].trim() + tm1 = w2utils.formatDate(dt, fm) + ' ' + tm1 + tm2 = w2utils.formatDate(dt, fm) + ' ' + tm2 + } + let valid = this.inRange(tm1, options) || this.inRange(tm2, options) + tmp[Math.floor(a/8)] += `${time}` + } + let html = `
    +
    ${w2utils.lang('Select Hour')}
    +
    +
    ${tmp[0]}
    +
    ${tmp[1]}
    +
    ${tmp[2]}
    +
    + ${options.btnNow ? `
    ${w2utils.lang('Now')}
    ` : '' } +
    ` + return { html } + } + getMinHTML(hour, options) { + if (hour == null) hour = 0 + options = options ?? {} + if (!options.format) options.format = w2utils.settings.timeFormat + let h24 = (options.format.indexOf('h24') > -1) + let value = options.value ? options.value : (options.anchor ? options.anchor.value : '') + let tmp = [] + for (let a = 0; a < 60; a += 5) { + let time = (hour > 12 && !h24 ? hour - 12 : hour) + ':' + (a < 10 ? 0 : '') + a + ' ' + (!h24 ? (hour < 12 ? 'am' : 'pm') : '') + let tm = time + let ind = a < 20 ? 0 : (a < 40 ? 1 : 2) + if (!tmp[ind]) tmp[ind] = '' + if (options.type === 'datetime') { + let dt = w2utils.isDateTime(value, options.format, true) + let fm = options.format.split('|')[0].trim() + tm = w2utils.formatDate(dt, fm) + ' ' + tm + } + tmp[ind] += `${time}` + } + let html = `
    +
    ${w2utils.lang('Select Minute')}
    +
    +
    ${tmp[0]}
    +
    ${tmp[1]}
    +
    ${tmp[2]}
    +
    + ${options.btnNow ? `
    ${w2utils.lang('Now')}
    ` : '' } +
    ` + return { html } + } + // checks if date is in range (loost at start, end, blockDates, blockWeekdays) + inRange(str, options, dateOnly) { + let inRange = false + if (options.type === 'date') { + let dt = w2utils.isDate(str, options.format, true) + if (dt) { + // enable range + if (options.start || options.end) { + let st = (typeof options.start === 'string' ? options.start : query(options.start).val()) + let en = (typeof options.end === 'string' ? options.end : query(options.end).val()) + let start = w2utils.isDate(st, options.format, true) + let end = w2utils.isDate(en, options.format, true) + let current = new Date(dt) + if (!start) start = current + if (!end) end = current + if (current >= start && current <= end) inRange = true + } else { + inRange = true + } + // block predefined dates + if (Array.isArray(options.blockDates) && options.blockDates.includes(str)) inRange = false + // block weekdays + if (Array.isArray(options.blockWeekdays) && options.blockWeekdays.includes(dt.getDay())) inRange = false + } + } else if (options.type === 'time') { + if (options.start || options.end) { + let tm = this.str2min(str) + let tm1 = this.str2min(options.start) + let tm2 = this.str2min(options.end) + if (!tm1) tm1 = tm + if (!tm2) tm2 = tm + if (tm >= tm1 && tm <= tm2) inRange = true + } else { + inRange = true + } + } else if (options.type === 'datetime') { + let dt = w2utils.isDateTime(str, options.format, true) + if (dt) { + let format = options.format.split('|').map(format => format.trim()) + if (dateOnly) { + let date = w2utils.formatDate(dt, format[0]) + let opts = w2utils.extend({}, options, { type: 'date', format: format[0] }) + if (this.inRange(date, opts)) inRange = true + } else { + let time = w2utils.formatTime(dt, format[1]) + let opts = { type: 'time', format: format[1], start: options.startTime, end: options.endTime } + if (this.inRange(time, opts)) inRange = true + } + } + } + return inRange + } + // converts time into number of minutes since midnight -- '11:50am' => 710 + str2min(str) { + if (typeof str !== 'string') return null + let tmp = str.split(':') + if (tmp.length === 2) { + tmp[0] = parseInt(tmp[0]) + tmp[1] = parseInt(tmp[1]) + if (str.indexOf('pm') !== -1 && tmp[0] !== 12) tmp[0] += 12 + if (str.includes('am') && tmp[0] == 12) tmp[0] = 0 // 12:00am - is midnight + } else { + return null + } + return tmp[0] * 60 + tmp[1] + } + // converts minutes since midnight into time str -- 710 => '11:50am' + min2str(time, format) { + let ret = '' + if (time >= 24 * 60) time = time % (24 * 60) + if (time < 0) time = 24 * 60 + time + let hour = Math.floor(time/60) + let min = ((time % 60) < 10 ? '0' : '') + (time % 60) + if (!format) { format = w2utils.settings.timeFormat} + if (format.indexOf('h24') !== -1) { + ret = hour + ':' + min + } else { + ret = (hour <= 12 ? hour : hour - 12) + ':' + min + ' ' + (hour >= 12 ? 'pm' : 'am') + } + return ret + } +} +let w2tooltip = new Tooltip() +let w2menu = new MenuTooltip() +let w2color = new ColorTooltip() +let w2date = new DateTooltip() +/** + * Part of w2ui 2.0 library + * - Dependencies: mQuery, w2utils, w2base, w2tooltip, w2color, w2menu + * + * == TODO == + * - tab navigation (index state) + * - vertical toolbar + * - w2menu on second click of tb button should hide + * - button display groups for each show/hide, possibly add state: { single: t/f, multiple: t/f, type: 'font' } + * - item.count - should just support html, so a custom block can be created, such as a colored line + * + * == 2.0 changes + * - CSP - fixed inline events + * - removed jQuery dependency + * - item.icon - can be class or or + * - new w2tooltips and w2menu + * - scroll returns promise + * - added onMouseEntter, onMouseLeave, onMouseDown, onMouseUp events + * - add(..., skipRefresh), insert(..., skipRefresh) + */ + +class w2toolbar extends w2base { + constructor(options) { + super(options.name) + this.box = null // DOM Element that holds the element + this.name = null // unique name for w2ui + this.routeData = {} // data for dynamic routes + this.items = [] + this.right = '' // HTML text on the right of toolbar + this.tooltip = 'top|left'// can be top, bottom, left, right + this.onClick = null + this.onMouseDown = null + this.onMouseUp = null + this.onMouseEnter = null // mouse enter the button event + this.onMouseLeave = null + this.onRender = null + this.onRefresh = null + this.onResize = null + this.onDestroy = null + this.item_template = { + id: null, // command to be sent to all event handlers + type: 'button', // button, check, radio, drop, menu, menu-radio, menu-check, break, html, spacer + text: null, + html: '', + tooltip: null, // w2toolbar.tooltip should be + count: null, + hidden: false, + disabled: false, + checked: false, // used for radio buttons + icon: null, + route: null, // if not null, it is route to go + arrow: null, // arrow down for drop/menu types + style: null, // extra css style for caption + group: null, // used for radio buttons + items: null, // for type menu* it is an array of items in the menu + selected: null, // used for menu-check, menu-radio + color: null, // color value - used in color pickers + overlay: { // additional options for overlay + anchorClass: '' + }, + onClick: null, + onRefresh: null + } + this.last = { + badge: {} + } + // mix in options, w/o items + let items = options.items + delete options.items + Object.assign(this, options) + // add item via method to makes sure item_template is applied + if (Array.isArray(items)) this.add(items, true) + // need to reassign back to keep it in config + options.items = items + // render if box specified + if (typeof this.box == 'string') this.box = query(this.box).get(0) + if (this.box) this.render(this.box) + } + add(items, skipRefresh) { + this.insert(null, items, skipRefresh) + } + insert(id, items, skipRefresh) { + if (!Array.isArray(items)) items = [items] + items.forEach((item, idx, arr) => { + if (typeof item === 'string') { + item = arr[idx] = { id: item, text: item } + } + // checks + let valid = ['button', 'check', 'radio', 'drop', 'menu', 'menu-radio', 'menu-check', 'color', 'text-color', 'html', + 'break', 'spacer', 'new-line'] + if (!valid.includes(String(item.type))) { + console.log('ERROR: The parameter "type" should be one of the following:', valid, `, but ${item.type} is supplied.`, item) + return + } + if (item.id == null && !['break', 'spacer', 'new-line'].includes(item.type)) { + console.log('ERROR: The parameter "id" is required but not supplied.', item) + return + } + if (item.type == null) { + console.log('ERROR: The parameter "type" is required but not supplied.', item) + return + } + if (!w2utils.checkUniqueId(item.id, this.items, 'toolbar', this.name)) return + // add item + let newItem = w2utils.extend({}, this.item_template, item) + if (newItem.type == 'menu-check') { + if (!Array.isArray(newItem.selected)) newItem.selected = [] + if (Array.isArray(newItem.items)) { + newItem.items.forEach(it => { + if (typeof it === 'string') { + it = arr[idx] = { id: it, text: it } + } + if (it.checked && !newItem.selected.includes(it.id)) newItem.selected.push(it.id) + if (!it.checked && newItem.selected.includes(it.id)) it.checked = true + if (it.checked == null) it.checked = false + }) + } + } else if (newItem.type == 'menu-radio') { + if (Array.isArray(newItem.items)) { + newItem.items.forEach((it, idx, arr) => { + if (typeof it === 'string') { + it = arr[idx] = { id: it, text: it } + } + if (it.checked && newItem.selected == null) newItem.selected = it.id; else it.checked = false + if (!it.checked && newItem.selected == it.id) it.checked = true + if (it.checked == null) it.checked = false + }) + } + } + if (id == null) { + this.items.push(newItem) + } else { + let middle = this.get(id, true) + this.items = this.items.slice(0, middle).concat([newItem], this.items.slice(middle)) + } + newItem.line = newItem.line ?? 1 + if (skipRefresh !== true) this.refresh(newItem.id) + }) + if (skipRefresh !== true) this.resize() + } + remove() { + let effected = 0 + Array.from(arguments).forEach(item => { + let it = this.get(item) + if (!it || String(item).indexOf(':') != -1) return + effected++ + // remove from screen + query(this.box).find('#tb_'+ this.name +'_item_'+ w2utils.escapeId(it.id)).remove() + // remove from array + let ind = this.get(it.id, true) + if (ind != null) this.items.splice(ind, 1) + }) + this.resize() + return effected + } + set(id, newOptions) { + let item = this.get(id) + if (item == null) return false + Object.assign(item, newOptions) + this.refresh(String(id).split(':')[0]) + return true + } + get(id, returnIndex) { + if (arguments.length === 0) { + let all = [] + for (let i1 = 0; i1 < this.items.length; i1++) if (this.items[i1].id != null) all.push(this.items[i1].id) + return all + } + let tmp = String(id).split(':') + for (let i2 = 0; i2 < this.items.length; i2++) { + let it = this.items[i2] + // find a menu item + if (['menu', 'menu-radio', 'menu-check'].includes(it.type) && tmp.length == 2 && it.id == tmp[0]) { + let subItems = it.items + if (typeof subItems == 'function') subItems = subItems(this) + for (let i = 0; i < subItems.length; i++) { + let item = subItems[i] + if (item.id == tmp[1] || (item.id == null && item.text == tmp[1])) { + if (returnIndex == true) return i; else return item + } + if (Array.isArray(item.items)) { + for (let j = 0; j < item.items.length; j++) { + if (item.items[j].id == tmp[1] || (item.items[j].id == null && item.items[j].text == tmp[1])) { + if (returnIndex == true) return i; else return item.items[j] + } + } + } + } + } else if (it.id == tmp[0]) { + if (returnIndex == true) return i2; else return it + } + } + return null + } + setCount(id, count, className, style) { + let btn = query(this.box).find(`#tb_${this.name}_item_${w2utils.escapeId(id)} .w2ui-tb-count > span`) + if (btn.length > 0) { + btn.removeClass() + .addClass(className ?? '') + .text(count) + .get(0).style.cssText = style ?? '' + this.last.badge[id] = { + className: className ?? '', + style: style ?? '' + } + let item = this.get(id) + item.count = count + } else { + this.set(id, { count: count }) + this.setCount(...arguments) // to update styles + } + } + show() { + let effected = [] + Array.from(arguments).forEach(item => { + let it = this.get(item) + if (!it) return + it.hidden = false + effected.push(String(item).split(':')[0]) + }) + setTimeout(() => { effected.forEach(it => { this.refresh(it); this.resize() }) }, 15) // needs timeout + return effected + } + hide() { + let effected = [] + Array.from(arguments).forEach(item => { + let it = this.get(item) + if (!it) return + it.hidden = true + effected.push(String(item).split(':')[0]) + }) + setTimeout(() => { effected.forEach(it => { this.refresh(it); this.tooltipHide(it); this.resize() }) }, 15) // needs timeout + return effected + } + enable() { + let effected = [] + Array.from(arguments).forEach(item => { + let it = this.get(item) + if (!it) return + it.disabled = false + effected.push(String(item).split(':')[0]) + }) + setTimeout(() => { effected.forEach(it => { this.refresh(it) }) }, 15) // needs timeout + return effected + } + disable() { + let effected = [] + Array.from(arguments).forEach(item => { + let it = this.get(item) + if (!it) return + it.disabled = true + effected.push(String(item).split(':')[0]) + }) + setTimeout(() => { effected.forEach(it => { this.refresh(it); this.tooltipHide(it) }) }, 15) // needs timeout + return effected + } + check() { + let effected = [] + Array.from(arguments).forEach(item => { + let it = this.get(item) + if (!it || String(item).indexOf(':') != -1) return + it.checked = true + effected.push(String(item).split(':')[0]) + }) + setTimeout(() => { effected.forEach(it => { this.refresh(it) }) }, 15) // needs timeout + return effected + } + uncheck() { + let effected = [] + Array.from(arguments).forEach(item => { + let it = this.get(item) + if (!it || String(item).indexOf(':') != -1) return + // remove overlay + if (['menu', 'menu-radio', 'menu-check', 'drop', 'color', 'text-color'].includes(it.type) && it.checked) { + w2tooltip.hide(this.name + '-drop') + } + it.checked = false + effected.push(String(item).split(':')[0]) + }) + setTimeout(() => { effected.forEach(it => { this.refresh(it) }) }, 15) // needs timeout + return effected + } + click(id, event) { + // click on menu items + let tmp = String(id).split(':') + let it = this.get(tmp[0]) + let items = (it && it.items ? w2utils.normMenu.call(this, it.items, it) : []) + if (tmp.length > 1) { + let subItem = this.get(id) + if (subItem && !subItem.disabled) { + this.menuClick({ name: this.name, item: it, subItem: subItem, originalEvent: event }) + } + return + } + if (it && !it.disabled) { + // event before + let edata = this.trigger('click', { + target: (id != null ? id : this.name), + item: it, object: it, originalEvent: event + }) + if (edata.isCancelled === true) return + // read items again, they might have been changed in the click event handler + items = (it && it.items ? w2utils.normMenu.call(this, it.items, it) : []) + let btn = '#tb_'+ this.name +'_item_'+ w2utils.escapeId(it.id) + query(this.box).find(btn).removeClass('down') // need to re-query at the moment -- as well as elsewhere in this function + if (it.type == 'radio') { + for (let i = 0; i < this.items.length; i++) { + let itt = this.items[i] + if (itt == null || itt.id == it.id || itt.type !== 'radio') continue + if (itt.group == it.group && itt.checked) { + itt.checked = false + this.refresh(itt.id) + } + } + it.checked = true + query(this.box).find(btn).addClass('checked') + } + if (['menu', 'menu-radio', 'menu-check', 'drop', 'color', 'text-color'].includes(it.type)) { + this.tooltipHide(id) + if (it.checked) { + w2tooltip.hide(this.name + '-drop') + return + } else { + // timeout is needed to make sure previous overlay hides + setTimeout(() => { + let hideDrop = (id, btn) => { + // need a closure to capture id variable + let self = this + return function () { + self.set(id, { checked: false }) + } + } + let el = query(this.box).find('#tb_'+ this.name +'_item_'+ w2utils.escapeId(it.id)) + if (!w2utils.isPlainObject(it.overlay)) it.overlay = {} + if (it.type == 'drop') { + w2tooltip.show(w2utils.extend({ + html: it.html, + class: 'w2ui-white', + hideOn: ['doc-click'] + }, it.overlay, { + anchor: el[0], + name: this.name + '-drop', + data: { item: it, btn } + })) + .hide(hideDrop(it.id, btn)) + } + if (['menu', 'menu-radio', 'menu-check'].includes(it.type)) { + let menuType = 'normal' + if (it.type == 'menu-radio') { + menuType = 'radio' + items.forEach((item) => { + if (it.selected == item.id) item.checked = true; else item.checked = false + }) + } + if (it.type == 'menu-check') { + menuType = 'check' + items.forEach((item) => { + if (Array.isArray(it.selected) && it.selected.includes(item.id)) item.checked = true; else item.checked = false + }) + } + w2menu.show(w2utils.extend({ + items, + }, it.overlay, { + type: menuType, + name : this.name + '-drop', + anchor: el[0], + data: { item: it, btn } + })) + .hide(hideDrop(it.id, btn)) + .remove(event => { + this.menuClick({ name: this.name, remove: true, item: it, subItem: event.detail.item, + originalEvent: event }) + }) + .select(event => { + this.menuClick({ name: this.name, item: it, subItem: event.detail.item, + originalEvent: event }) + }) + } + if (['color', 'text-color'].includes(it.type)) { + w2color.show(w2utils.extend({ + color: it.color + }, it.overlay, { + anchor: el[0], + name: this.name + '-drop', + data: { item: it, btn } + })) + .hide(hideDrop(it.id, btn)) + .select(event => { + if (event.detail.color != null) { + this.colorClick({ name: this.name, item: it, color: event.detail.color }) + } + }) + } + }, 0) + } + } + if (['check', 'menu', 'menu-radio', 'menu-check', 'drop', 'color', 'text-color'].includes(it.type)) { + it.checked = !it.checked + if (it.checked) { + query(this.box).find(btn).addClass('checked') + } else { + query(this.box).find(btn).removeClass('checked') + } + } + // route processing + if (it.route) { + let route = String('/'+ it.route).replace(/\/{2,}/g, '/') + let info = w2utils.parseRoute(route) + if (info.keys.length > 0) { + for (let k = 0; k < info.keys.length; k++) { + route = route.replace((new RegExp(':'+ info.keys[k].name, 'g')), this.routeData[info.keys[k].name]) + } + } + setTimeout(() => { window.location.hash = route }, 1) + } + // need to refresh toolbar as it might be dynamic + this.tooltipShow(id) + // event after + edata.finish() + } + } + scroll(direction, line, instant) { + return new Promise((resolve, reject) => { + let scrollBox = query(this.box).find(`.w2ui-tb-line:nth-child(${line}) .w2ui-scroll-wrapper`) + let scrollLeft = scrollBox.get(0).scrollLeft + let right = scrollBox.find('.w2ui-tb-right').get(0) + let width1 = scrollBox.parent().get(0).getBoundingClientRect().width + let width2 = scrollLeft + parseInt(right.offsetLeft) + parseInt(right.clientWidth ) + switch (direction) { + case 'left': { + scroll = scrollLeft - width1 + 50 // 35 is width of both button + if (scroll <= 0) scroll = 0 + scrollBox.get(0).scrollTo({ top: 0, left: scroll, behavior: instant ? 'atuo' : 'smooth' }) + break + } + case 'right': { + scroll = scrollLeft + width1 - 50 // 35 is width of both button + if (scroll >= width2 - width1) scroll = width2 - width1 + scrollBox.get(0).scrollTo({ top: 0, left: scroll, behavior: instant ? 'atuo' : 'smooth' }) + break + } + } + setTimeout(() => { this.resize(); resolve() }, instant ? 0 : 500) + }) + } + render(box) { + let time = Date.now() + if (typeof box == 'string') box = query(box).get(0) + // event before + let edata = this.trigger('render', { target: this.name, box: box ?? this.box }) + if (edata.isCancelled === true) return + // defaul action + if (box != null) { + // clean previous box + if (query(this.box).find('.w2ui-scroll-wrapper .w2ui-tb-right').length > 0) { + query(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-toolbar') + .html('') + } + this.box = box + } + if (!this.box) return + if (!Array.isArray(this.right)) { + this.right = [this.right] + } + // render all buttons + let html = '' + let line = 0 + for (let i = 0; i < this.items.length; i++) { + let it = this.items[i] + if (it == null) continue + if (it.id == null) it.id = 'item_' + i + if (it.caption != null) { + console.log('NOTICE: toolbar item.caption property is deprecated, please use item.text. Item -> ', it) + } + if (it.hint != null) { + console.log('NOTICE: toolbar item.hint property is deprecated, please use item.tooltip. Item -> ', it) + } + if (i === 0 || it.type == 'new-line') { + line++ + html += ` +
    +
    +
    ${this.right[line-1] ?? ''}
    +
    +
    +
    +
    + ` + } + it.line = line + } + query(this.box) + .attr('name', this.name) + .addClass('w2ui-reset w2ui-toolbar') + .html(html) + if (query(this.box).length > 0) { + query(this.box)[0].style.cssText += this.style + } + w2utils.bindEvents(query(this.box).find('.w2ui-tb-line .w2ui-eaction'), this) + // observe div resize + this.last.observeResize = new ResizeObserver(() => { this.resize() }) + this.last.observeResize.observe(this.box) + // refresh all + this.refresh() + this.resize() + // event after + edata.finish() + return Date.now() - time + } + refresh(id) { + let time = Date.now() + // event before + let edata = this.trigger('refresh', { target: (id != null ? id : this.name), item: this.get(id) }) + if (edata.isCancelled === true) return + let edata2 + // refresh all + if (id == null) { + for (let i = 0; i < this.items.length; i++) { + let it1 = this.items[i] + if (it1.id == null) it1.id = 'item_' + i + this.refresh(it1.id) + } + return + } + // create or refresh only one item + let it = this.get(id) + if (it == null) return false + if (typeof it.onRefresh == 'function') { + edata2 = this.trigger('refresh', { target: id, item: it, object: it }) + if (edata2.isCancelled === true) return + } + let selector = `#tb_${this.name}_item_${w2utils.escapeId(it.id)}` + let btn = query(this.box).find(selector) + let html = this.getItemHTML(it) + // hide tooltip + this.tooltipHide(id) + // if there is a spacer, then right HTML is not 100% + if (it.type == 'spacer') { + query(this.box).find(`.w2ui-tb-line:nth-child(${it.line}`).find('.w2ui-tb-right').css('width', 'auto') + } + if (btn.length === 0) { + let next = parseInt(this.get(id, true)) + 1 + let $next = query(this.box).find(`#tb_${this.name}_item_${w2utils.escapeId(this.items[next] ? this.items[next].id : '')}`) + if ($next.length == 0) { + $next = query(this.box).find(`.w2ui-tb-line:nth-child(${it.line}`).find('.w2ui-tb-right').before(html) + } else { + $next.after(html) + } + w2utils.bindEvents(query(this.box).find(selector), this) + } else { + // refresh + query(this.box).find(selector).replace(query.html(html)) + let newBtn = query(this.box).find(selector).get(0) + w2utils.bindEvents(newBtn, this) + // update overlay's anchor if changed + let overlays = w2tooltip.get(true) + Object.keys(overlays).forEach(key => { + if (overlays[key].anchor == btn.get(0)) { + overlays[key].anchor = newBtn + } + }) + } + if (['menu', 'menu-radio', 'menu-check'].includes(it.type) && it.checked) { + // check selected items + let selected = Array.isArray(it.selected) ? it.selected : [it.selected] + it.items.forEach((item) => { + if (selected.includes(item.id)) item.checked = true; else item.checked = false + }) + w2menu.update(this.name + '-drop', it.items) + } + // event after + if (typeof it.onRefresh == 'function') { + edata2.finish() + } + edata.finish() + return Date.now() - time + } + resize() { + let time = Date.now() + // event before + let edata = this.trigger('resize', { target: this.name }) + if (edata.isCancelled === true) return + query(this.box).find('.w2ui-tb-line').each(el => { + // show hide overflow buttons + let box = query(el) + box.find('.w2ui-scroll-left, .w2ui-scroll-right').hide() + let scrollBox = box.find('.w2ui-scroll-wrapper').get(0) + let $right = box.find('.w2ui-tb-right') + let boxWidth = box.get(0).getBoundingClientRect().width + let itemsWidth = ($right.length > 0 ? $right[0].offsetLeft + $right[0].clientWidth : 0) + if (boxWidth < itemsWidth) { + // we have overflown content + if (scrollBox.scrollLeft > 0) { + box.find('.w2ui-scroll-left').show() + } + if (boxWidth < itemsWidth - scrollBox.scrollLeft) { + box.find('.w2ui-scroll-right').show() + } + } + }) + // event after + edata.finish() + return Date.now() - time + } + destroy() { + // event before + let edata = this.trigger('destroy', { target: this.name }) + if (edata.isCancelled === true) return + // clean up + if (query(this.box).find('.w2ui-scroll-wrapper .w2ui-tb-right').length > 0) { + query(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-toolbar') + .html('') + } + query(this.box).html('') + this.last.observeResize?.disconnect() + delete w2ui[this.name] + // event after + edata.finish() + } + // ======================================== + // --- Internal Functions + getItemHTML(item) { + let html = '' + if (item.caption != null && item.text == null) item.text = item.caption // for backward compatibility + if (item.text == null) item.text = '' + if (item.tooltip == null && item.hint != null) item.tooltip = item.hint // for backward compatibility + if (item.tooltip == null) item.tooltip = '' + if (typeof item.get !== 'function' && (Array.isArray(item.items) || typeof item.items == 'function')) { + item.get = function get(id) { // need scope, cannot be arrow func + let tmp = item.items + if (typeof tmp == 'function') tmp = item.items(item) + return tmp.find(it => it.id == id ? true : false) + } + } + let icon = '' + let text = (typeof item.text == 'function' ? item.text.call(this, item) : item.text) + if (item.icon) { + icon = item.icon + if (typeof item.icon == 'function') { + icon = item.icon.call(this, item) + } + if (String(icon).slice(0, 1) !== '<') { + icon = `` + } + icon = `
    ${icon}
    ` + } + let classes = ['w2ui-tb-button'] + if (item.checked) classes.push('checked') + if (item.disabled) classes.push('disabled') + if (item.hidden) classes.push('hidden') + if (!icon) classes.push('no-icon') + switch (item.type) { + case 'color': + case 'text-color': + if (typeof item.color == 'string') { + if (item.color.slice(0, 1) == '#') item.color = item.color.slice(1) + if ([3, 6, 8].includes(item.color.length)) item.color = '#' + item.color + } + if (item.type == 'color') { + text = ` + ${(item.text ? `
    ${w2utils.lang(item.text)}
    ` : '')}` + } + if (item.type == 'text-color') { + text = ''+ + (item.text ? w2utils.lang(item.text) : 'Aa') + + '' + } + case 'menu': + case 'menu-check': + case 'menu-radio': + case 'button': + case 'check': + case 'radio': + case 'drop': { + let arrow = (item.arrow === true + || (item.arrow !== false && ['menu', 'menu-radio', 'menu-check', 'drop', 'color', 'text-color'].includes(item.type))) + html = ` +
    + ${ icon } + ${ text != '' + ? `
    + ${ w2utils.lang(text) } + ${ item.count != null + ? w2utils.stripSpaces(` + ${item.count} + `) + : '' + } + ${ arrow + ? '' + : '' + } +
    ` + : ''} +
    + ` + break + } + case 'break': + html = `
    +   +
    ` + break + case 'spacer': + html = `
    +
    ` + break + case 'html': + html = `
    + ${(typeof item.html == 'function' ? item.html.call(this, item) : item.html)} +
    ` + break + } + return html + } + tooltipShow(id) { + if (this.tooltip == null) return + let el = query(this.box).find('#tb_'+ this.name + '_item_'+ w2utils.escapeId(id)).get(0) + let item = this.get(id) + let pos = this.tooltip + let txt = item.tooltip + if (typeof txt == 'function') txt = txt.call(this, item) + // not for opened drop downs + if (['menu', 'menu-radio', 'menu-check', 'drop', 'color', 'text-color'].includes(item.type) + && item.checked == true) { + return + } + w2tooltip.show({ + anchor: el, + name: this.name + '-tooltip', + html: txt, + position: pos + }) + return + } + tooltipHide(id) { + if (this.tooltip == null) return + w2tooltip.hide(this.name + '-tooltip') + } + menuClick(event) { + if (event.item && !event.item.disabled) { + // event before + let edata = this.trigger((event.remove !== true ? 'click' : 'remove'), { + target: event.item.id + ':' + event.subItem.id, item: event.item, + subItem: event.subItem, originalEvent: event.originalEvent + }) + if (edata.isCancelled === true) return + // route processing + let it = event.subItem + let item = this.get(event.item.id) + let items = item.items + if (typeof items == 'function') items = item.items() + if (item.type == 'menu') { + item.selected = it.id + } + if (item.type == 'menu-radio') { + item.selected = it.id + if (Array.isArray(items)) { + items.forEach((item) => { + if (item.checked === true) delete item.checked + if (Array.isArray(item.items)) { + item.items.forEach((item) => { + if (item.checked === true) delete item.checked + }) + } + }) + } + it.checked = true + } + if (item.type == 'menu-check') { + if (!Array.isArray(item.selected)) item.selected = [] + if (it.group == null) { + let ind = item.selected.indexOf(it.id) + if (ind == -1) { + item.selected.push(it.id) + it.checked = true + } else { + item.selected.splice(ind, 1) + it.checked = false + } + } else if (it.group === false) { + // if group is false, then it is not part of checkboxes + } else { + let unchecked = [] + let ind = item.selected.indexOf(it.id) + let checkNested = (items) => { + items.forEach((sub) => { + if (sub.group === it.group) { + let ind = item.selected.indexOf(sub.id) + if (ind != -1) { + if (sub.id != it.id) unchecked.push(sub.id) + item.selected.splice(ind, 1) + } + } + if (Array.isArray(sub.items)) checkNested(sub.items) + }) + } + checkNested(items) + if (ind == -1) { + item.selected.push(it.id) + it.checked = true + } + } + } + if (typeof it.route == 'string') { + let route = it.route !== '' ? String('/'+ it.route).replace(/\/{2,}/g, '/') : '' + let info = w2utils.parseRoute(route) + if (info.keys.length > 0) { + for (let k = 0; k < info.keys.length; k++) { + if (this.routeData[info.keys[k].name] == null) continue + route = route.replace((new RegExp(':'+ info.keys[k].name, 'g')), this.routeData[info.keys[k].name]) + } + } + setTimeout(() => { window.location.hash = route }, 1) + } + this.refresh(event.item.id) + // event after + edata.finish() + } + } + colorClick(event) { + let obj = this + if (event.item && !event.item.disabled) { + // event before + let edata = this.trigger('click', { + target: event.item.id, item: event.item, + color: event.color, final: event.final, originalEvent: event.originalEvent + }) + if (edata.isCancelled === true) return + // default behavior + event.item.color = event.color + obj.refresh(event.item.id) + // event after + edata.finish() + } + } + mouseAction(event, target, action, id) { + let btn = this.get(id) + let edata = this.trigger('mouse' + action, { target: id, item: btn, object: btn, originalEvent: event }) + if (edata.isCancelled === true || btn.disabled || btn.hidden) return + switch (action) { + case 'Enter': + query(target).addClass('over') + this.tooltipShow(id) + break + case 'Leave': + query(target).removeClass('over down') + this.tooltipHide(id) + break + case 'Down': + query(target).addClass('down') + break + case 'Up': + query(target).removeClass('down') + break + } + edata.finish() + } +} +/** + * Part of w2ui 2.0 library + * - Dependencies: mQuery, w2utils, w2base, w2tooltip, w2menu + * + * == TODO == + * - dbl click should be like it is in grid (with timer not HTML dbl click event) + * - node.style is misleading - should be there to apply color for example + * - node.plus - is not working + * + * == 2.0 changes + * - remove jQuery dependency + * - deprecarted obj.img, node.img + * - CSP - fixed inline events + * - observeResize for the box + * - handleTooltip and handle.tooltip - text/function + * - added onMouseEntter, onMouseLeave events + */ + +class w2sidebar extends w2base { + constructor(options) { + super(options.name) + this.name = null + this.box = null + this.sidebar = null + this.parent = null + this.nodes = [] // Sidebar child nodes + this.menu = [] + this.routeData = {} // data for dynamic routes + this.selected = null // current selected node (readonly) + this.icon = null + this.style = '' + this.topHTML = '' + this.bottomHTML = '' + this.flatButton = false + this.keyboard = true + this.flat = false + this.hasFocus = false + this.levelPadding = 12 + this.skipRefresh = false + this.tabIndex = null // will only be set if > 0 and not null + this.handle = { size: 0, style: '', html: '', tooltip: '' }, + this.onClick = null // Fire when user click on Node Text + this.onDblClick = null // Fire when user dbl clicks + this.onMouseEnter = null // mouse enter/leave over an item + this.onMouseLeave = null + this.onContextMenu = null + this.onMenuClick = null // when context menu item selected + this.onExpand = null // Fire when node expands + this.onCollapse = null // Fire when node collapses + this.onKeydown = null + this.onRender = null + this.onRefresh = null + this.onResize = null + this.onDestroy = null + this.onFocus = null + this.onBlur = null + this.onFlat = null + this.node_template = { + id: null, + text: '', + order: null, + count: null, + icon: null, + nodes: [], + style: '', // additional style for subitems + route: null, + selected: false, + expanded: false, + hidden: false, + disabled: false, + group: false, // if true, it will build as a group + groupShowHide: true, + collapsible: false, + plus: false, // if true, plus will be shown even if there is no sub nodes + // events + onClick: null, + onDblClick: null, + onContextMenu: null, + onExpand: null, + onCollapse: null, + // internal + parent: null, // node object + sidebar: null + } + this.last = { + badge: {} + } + let nodes = options.nodes + delete options.nodes + // mix in options + Object.assign(this, options) + // add item via method to makes sure item_template is applied + if (Array.isArray(nodes)) this.add(nodes) + // need to reassign back to keep it in config + options.nodes = nodes + // render if box specified + if (typeof this.box == 'string') this.box = query(this.box).get(0) + if (this.box) this.render(this.box) + } + add(parent, nodes) { + if (arguments.length == 1) { + // need to be in reverse order + nodes = arguments[0] + parent = this + } + if (typeof parent == 'string') parent = this.get(parent) + if (parent == null || parent == '') parent = this + return this.insert(parent, null, nodes) + } + insert(parent, before, nodes) { + let txt, ind, tmp, node, nd + if (arguments.length == 2 && typeof parent == 'string') { + // need to be in reverse order + nodes = arguments[1] + before = arguments[0] + if (before != null) { + ind = this.get(before) + if (ind == null) { + if (!Array.isArray(nodes)) nodes = [nodes] + if (nodes[0].caption != null && nodes[0].text == null) { + console.log('NOTICE: sidebar node.caption property is deprecated, please use node.text. Node -> ', nodes[0]) + nodes[0].text = nodes[0].caption + } + txt = nodes[0].text + console.log('ERROR: Cannot insert node "'+ txt +'" because cannot find node "'+ before +'" to insert before.') + return null + } + parent = this.get(before).parent + } else { + parent = this + } + } + if (typeof parent == 'string') parent = this.get(parent) + if (parent == null || parent == '') parent = this + if (!Array.isArray(nodes)) nodes = [nodes] + for (let o = 0; o < nodes.length; o++) { + node = nodes[o] + if (node.caption != null && node.text == null) { + console.log('NOTICE: sidebar node.caption property is deprecated, please use node.text') + node.text = node.caption + } + if (typeof node.id == null) { + txt = node.text + console.log('ERROR: Cannot insert node "'+ txt +'" because it has no id.') + continue + } + if (this.get(this, node.id) != null) { + console.log('ERROR: Cannot insert node with id='+ node.id +' (text: '+ node.text + ') because another node with the same id already exists.') + continue + } + tmp = Object.assign({}, this.node_template, node) + tmp.sidebar = this + tmp.parent = parent + nd = tmp.nodes || [] + tmp.nodes = [] // very important to re-init empty nodes array + if (before == null) { // append to the end + parent.nodes.push(tmp) + } else { + ind = this.get(parent, before, true) + if (ind == null) { + console.log('ERROR: Cannot insert node "'+ node.text +'" because cannot find node "'+ before +'" to insert before.') + return null + } + parent.nodes.splice(ind, 0, tmp) + } + if (nd.length > 0) { + this.insert(tmp, null, nd) + } + } + if (!this.skipRefresh) this.refresh(parent.id) + return tmp + } + remove() { // multiple arguments + let effected = 0 + let node + Array.from(arguments).forEach(arg => { + node = this.get(arg) + if (node == null) return + if (this.selected != null && this.selected === node.id) { + this.selected = null + } + let ind = this.get(node.parent, arg, true) + if (ind == null) return + if (node.parent.nodes[ind].selected) node.sidebar.unselect(node.id) + node.parent.nodes.splice(ind, 1) + node.parent.collapsible = node.parent.nodes.length > 0 + effected++ + }) + if (!this.skipRefresh) { + if (effected > 0 && arguments.length == 1) this.refresh(node.parent.id); else this.refresh() + } + return effected + } + set(parent, id, node) { + if (arguments.length == 2) { + // need to be in reverse order + node = id + id = parent + parent = this + } + // searches all nested nodes + if (typeof parent == 'string') parent = this.get(parent) + if (parent.nodes == null) return null + for (let i = 0; i < parent.nodes.length; i++) { + if (parent.nodes[i].id === id) { + // see if quick update is possible + let res = this.update(id, node) + if (Object.keys(res).length != 0) { + // make sure nodes inserted correctly + let nodes = node.nodes + w2utils.extend(parent.nodes[i], node, { nodes: [] }) + if (nodes != null) { + this.add(parent.nodes[i], nodes) + } + if (!this.skipRefresh) this.refresh(id) + } + return true + } else { + let rv = this.set(parent.nodes[i], id, node) + if (rv) return true + } + } + return false + } + get(parent, id, returnIndex) { // can be just called get(id) or get(id, true) + if (arguments.length === 0) { + let all = [] + let tmp = this.find({}) + for (let t = 0; t < tmp.length; t++) { + if (tmp[t].id != null) all.push(tmp[t].id) + } + return all + } else { + if (arguments.length == 1 || (arguments.length == 2 && id === true) ) { + // need to be in reverse order + returnIndex = id + id = parent + parent = this + } + // searches all nested nodes + if (typeof parent == 'string') parent = this.get(parent) + if (parent.nodes == null) return null + for (let i = 0; i < parent.nodes.length; i++) { + if (parent.nodes[i].id == id) { + if (returnIndex === true) return i; else return parent.nodes[i] + } else { + let rv = this.get(parent.nodes[i], id, returnIndex) + if (rv || rv === 0) return rv + } + } + return null + } + } + setCount(id, count, className, style) { + let btn = query(this.box).find(`#node_${w2utils.escapeId(id)} .w2ui-node-count`) + if (btn.length > 0) { + btn.removeClass() + .addClass(`w2ui-node-count ${className || ''}`) + .text(count) + .get(0).style.cssText = style || '' + this.last.badge[id] = { + className: className || '', + style: style || '' + } + let item = this.get(id) + item.count = count + } else { + this.set(id, { count: count }) + this.setCount(...arguments) // to update styles + } + } + find(parent, params, results) { // can be just called find({ selected: true }) + // TODO: rewrite with this.each() + if (arguments.length == 1) { + // need to be in reverse order + params = parent + parent = this + } + if (!results) results = [] + // searches all nested nodes + if (typeof parent == 'string') parent = this.get(parent) + if (parent.nodes == null) return results + for (let i = 0; i < parent.nodes.length; i++) { + let match = true + for (let prop in params) { // params is an object + if (parent.nodes[i][prop] != params[prop]) match = false + } + if (match) results.push(parent.nodes[i]) + if (parent.nodes[i].nodes.length > 0) results = this.find(parent.nodes[i], params, results) + } + return results + } + sort(options, nodes) { + // default options + if (!options || typeof options != 'object') options = {} + if (options.foldersFirst == null) options.foldersFirst = true + if (options.caseSensitive == null) options.caseSensitive = false + if (options.reverse == null) options.reverse = false + if (nodes == null) { + nodes = this.nodes + } + nodes.sort((a, b) => { + // folders first + let isAfolder = (a.nodes && a.nodes.length > 0) + let isBfolder = (b.nodes && b.nodes.length > 0) + // both folder or both not folders + if (options.foldersFirst === false || (!isAfolder && !isBfolder) || (isAfolder && isBfolder)) { + let aText = a.text + let bText = b.text + if (!options.caseSensitive) { + aText = aText.toLowerCase() + bText = bText.toLowerCase() + } + if (a.order != null) aText = a.order + if (b.order != null) bText = b.order + let cmp = w2utils.naturalCompare(aText, bText) + return (cmp === 1 || cmp === -1) & options.reverse ? -cmp : cmp + } + if (isAfolder && !isBfolder) { + return !options.reverse ? -1 : 1 + } + if (!isAfolder && isBfolder) { + return !options.reverse ? 1 : -1 + } + }) + nodes.forEach(node => { + if (node.nodes && node.nodes.length > 0) { + this.sort(options, node.nodes) + } + }) + } + each(fn, nodes) { + if (nodes == null) nodes = this.nodes + nodes.forEach((node) => { + fn.call(this, node) + if (node.nodes && node.nodes.length > 0) { + this.each(fn, node.nodes) + } + }) + } + search(str) { + let count = 0 + let str2 = str.toLowerCase() + this.each((node) => { + if (node.text.toLowerCase().indexOf(str2) === -1) { + node.hidden = true + } else { + count++ + showParents(node) + node.hidden = false + } + }) + this.refresh() + return count + function showParents(node) { + if (node.parent) { + node.parent.hidden = false + showParents(node.parent) + } + } + } + show() { // multiple arguments + let effected = [] + Array.from(arguments).forEach(it => { + let node = this.get(it) + if (node == null || node.hidden === false) return + node.hidden = false + effected.push(node.id) + }) + if (effected.length > 0) { + if (arguments.length == 1) this.refresh(arguments[0]); else this.refresh() + } + return effected + } + hide() { // multiple arguments + let effected = [] + Array.from(arguments).forEach(it => { + let node = this.get(it) + if (node == null || node.hidden === true) return + node.hidden = true + effected.push(node.id) + }) + if (effected.length > 0) { + if (arguments.length == 1) this.refresh(arguments[0]); else this.refresh() + } + return effected + } + enable() { // multiple arguments + let effected = [] + Array.from(arguments).forEach(it => { + let node = this.get(it) + if (node == null || node.disabled === false) return + node.disabled = false + effected.push(node.id) + }) + if (effected.length > 0) { + if (arguments.length == 1) this.refresh(arguments[0]); else this.refresh() + } + return effected + } + disable() { // multiple arguments + let effected = [] + Array.from(arguments).forEach(it => { + let node = this.get(it) + if (node == null || node.disabled === true) return + node.disabled = true + if (node.selected) this.unselect(node.id) + effected.push(node.id) + }) + if (effected.length > 0) { + if (arguments.length == 1) this.refresh(arguments[0]); else this.refresh() + } + return effected + } + select(id) { + let new_node = this.get(id) + if (!new_node) return false + if (this.selected == id && new_node.selected) return false + this.unselect(this.selected) + let $el = query(this.box).find('#node_'+ w2utils.escapeId(id)) + $el.addClass('w2ui-selected') + .find('.w2ui-icon') + .addClass('w2ui-icon-selected') + if ($el.length > 0) { + if (!this.inView(id)) this.scrollIntoView(id) + } + new_node.selected = true + this.selected = id + return true + } + unselect(id) { + // if no arguments provided, unselect selected node + if (arguments.length === 0) { + id = this.selected + } + let current = this.get(id) + if (!current) return false + current.selected = false + query(this.box).find('#node_'+ w2utils.escapeId(id)) + .removeClass('w2ui-selected') + .find('.w2ui-icon').removeClass('w2ui-icon-selected') + if (this.selected == id) this.selected = null + return true + } + toggle(id) { + let nd = this.get(id) + if (nd == null) return false + if (nd.plus) { + this.set(id, { plus: false }) + this.expand(id) + this.refresh(id) + return + } + if (nd.nodes.length === 0) return false + if (!nd.collapsible) return false + if (this.get(id).expanded) return this.collapse(id); else return this.expand(id) + } + collapse(id) { + let self = this + let nd = this.get(id) + if (nd == null) return false + // event before + let edata = this.trigger('collapse', { target: id, object: nd }) + if (edata.isCancelled === true) return + // default action + query(this.box).find('#node_'+ w2utils.escapeId(id) +'_sub').hide() + query(this.box).find('#node_'+ w2utils.escapeId(id) +' .w2ui-expanded') + .removeClass('w2ui-expanded') + .addClass('w2ui-collapsed') + nd.expanded = false + // event after + edata.finish() + setTimeout(() => { self.refresh(id) }, 0) + return true + } + expand(id) { + let self = this + let nd = this.get(id) + // event before + let edata = this.trigger('expand', { target: id, object: nd }) + if (edata.isCancelled === true) return + // default action + query(this.box).find('#node_'+ w2utils.escapeId(id) +'_sub') + .show() + query(this.box).find('#node_'+ w2utils.escapeId(id) +' .w2ui-collapsed') + .removeClass('w2ui-collapsed') + .addClass('w2ui-expanded') + nd.expanded = true + // event after + edata.finish() + self.refresh(id) + return true + } + collapseAll(parent) { + if (parent == null) parent = this + if (typeof parent == 'string') parent = this.get(parent) + if (parent.nodes == null) return false + for (let i = 0; i < parent.nodes.length; i++) { + if (parent.nodes[i].expanded === true) parent.nodes[i].expanded = false + if (parent.nodes[i].nodes && parent.nodes[i].nodes.length > 0) this.collapseAll(parent.nodes[i]) + } + this.refresh(parent.id) + return true + } + expandAll(parent) { + if (parent == null) parent = this + if (typeof parent == 'string') parent = this.get(parent) + if (parent.nodes == null) return false + for (let i = 0; i < parent.nodes.length; i++) { + if (parent.nodes[i].expanded === false) parent.nodes[i].expanded = true + if (parent.nodes[i].nodes && parent.nodes[i].nodes.length > 0) this.expandAll(parent.nodes[i]) + } + this.refresh(parent.id) + } + expandParents(id) { + let node = this.get(id) + if (node == null) return false + if (node.parent) { + if (!node.parent.expanded) { + node.parent.expanded = true + this.refresh(node.parent.id) + } + this.expandParents(node.parent.id) + } + return true + } + click(id, event) { + let obj = this + let nd = this.get(id) + if (nd == null) return + if (nd.disabled || nd.group) return // should click event if already selected + // unselect all previously + query(obj.box).find('.w2ui-node.w2ui-selected').each(el => { + let oldID = query(el).attr('id').replace('node_', '') + let oldNode = obj.get(oldID) + if (oldNode != null) oldNode.selected = false + query(el).removeClass('w2ui-selected').find('.w2ui-icon').removeClass('w2ui-icon-selected') + }) + // select new one + let newNode = query(obj.box).find('#node_'+ w2utils.escapeId(id)) + let oldNode = query(obj.box).find('#node_'+ w2utils.escapeId(obj.selected)) + newNode.addClass('w2ui-selected').find('.w2ui-icon').addClass('w2ui-icon-selected') + // need timeout to allow rendering + setTimeout(() => { + // event before + let edata = obj.trigger('click', { target: id, originalEvent: event, node: nd, object: nd }) + if (edata.isCancelled === true) { + // restore selection + newNode.removeClass('w2ui-selected').find('.w2ui-icon').removeClass('w2ui-icon-selected') + oldNode.addClass('w2ui-selected').find('.w2ui-icon').addClass('w2ui-icon-selected') + return + } + // default action + if (oldNode != null) oldNode.selected = false + obj.get(id).selected = true + obj.selected = id + // route processing + if (typeof nd.route == 'string') { + let route = nd.route !== '' ? String('/'+ nd.route).replace(/\/{2,}/g, '/') : '' + let info = w2utils.parseRoute(route) + if (info.keys.length > 0) { + for (let k = 0; k < info.keys.length; k++) { + if (obj.routeData[info.keys[k].name] == null) continue + route = route.replace((new RegExp(':'+ info.keys[k].name, 'g')), obj.routeData[info.keys[k].name]) + } + } + setTimeout(() => { window.location.hash = route }, 1) + } + // event after + edata.finish() + }, 1) + } + focus(event) { + let self = this + // event before + let edata = this.trigger('focus', { target: this.name, originalEvent: event }) + if (edata.isCancelled === true) return false + // default behaviour + this.hasFocus = true + query(this.box).find('.w2ui-sidebar-body').addClass('w2ui-focus') + setTimeout(() => { + let input = query(self.box).find('#sidebar_'+ self.name + '_focus').get(0) + if (document.activeElement != input) input.focus() + }, 10) + // event after + edata.finish() + } + blur(event) { + // event before + let edata = this.trigger('blur', { target: this.name, originalEvent: event }) + if (edata.isCancelled === true) return false + // default behaviour + this.hasFocus = false + query(this.box).find('.w2ui-sidebar-body').removeClass('w2ui-focus') + // event after + edata.finish() + } + keydown(event) { + let obj = this + let nd = obj.get(obj.selected) + if (obj.keyboard !== true) return + if (!nd) nd = obj.nodes[0] + // trigger event + let edata = obj.trigger('keydown', { target: obj.name, originalEvent: event }) + if (edata.isCancelled === true) return + // default behaviour + if (event.keyCode == 13 || event.keyCode == 32) { // enter or space + if (nd.nodes.length > 0) obj.toggle(obj.selected) + } + if (event.keyCode == 37) { // left + if (nd.nodes.length > 0 && nd.expanded) { + obj.collapse(obj.selected) + } else { + selectNode(nd.parent) + if (!nd.parent.group) obj.collapse(nd.parent.id) + } + } + if (event.keyCode == 39) { // right + if ((nd.nodes.length > 0 || nd.plus) && !nd.expanded) obj.expand(obj.selected) + } + if (event.keyCode == 38) { // up + if (obj.get(obj.selected) == null) { + selectNode(this.nodes[0] || null) + } else { + selectNode(neighbor(nd, prev)) + } + } + if (event.keyCode == 40) { // down + if (obj.get(obj.selected) == null) { + selectNode(this.nodes[0] || null) + } else { + selectNode(neighbor(nd, next)) + } + } + // cancel event if needed + if ([13, 32, 37, 38, 39, 40].includes(event.keyCode)) { + if (event.preventDefault) event.preventDefault() + if (event.stopPropagation) event.stopPropagation() + } + // event after + edata.finish() + function selectNode(node, event) { + if (node != null && !node.hidden && !node.disabled && !node.group) { + obj.click(node.id, event) + if (!obj.inView(node.id)) obj.scrollIntoView(node.id) + } + } + function neighbor(node, neighborFunc) { + node = neighborFunc(node) + while (node != null && (node.hidden || node.disabled)) { + if (node.group) break; else node = neighborFunc(node) + } + return node + } + function next(node, noSubs) { + if (node == null) return null + let parent = node.parent + let ind = obj.get(node.id, true) + let nextNode = null + // jump inside + if (node.expanded && node.nodes.length > 0 && noSubs !== true) { + let t = node.nodes[0] + if (t.hidden || t.disabled || t.group) nextNode = next(t); else nextNode = t + } else { + if (parent && ind + 1 < parent.nodes.length) { + nextNode = parent.nodes[ind + 1] + } else { + nextNode = next(parent, true) // jump to the parent + } + } + if (nextNode != null && (nextNode.hidden || nextNode.disabled || nextNode.group)) nextNode = next(nextNode) + return nextNode + } + function prev(node) { + if (node == null) return null + let parent = node.parent + let ind = obj.get(node.id, true) + let prevNode = (ind > 0) ? lastChild(parent.nodes[ind - 1]) : parent + if (prevNode != null && (prevNode.hidden || prevNode.disabled || prevNode.group)) prevNode = prev(prevNode) + return prevNode + } + function lastChild(node) { + if (node.expanded && node.nodes.length > 0) { + let t = node.nodes[node.nodes.length - 1] + if (t.hidden || t.disabled || t.group) return prev(t); else return lastChild(t) + } + return node + } + } + inView(id) { + let item = query(this.box).find('#node_'+ w2utils.escapeId(id)).get(0) + if (!item) { + return false + } + let div = query(this.box).find('.w2ui-sidebar-body').get(0) + if (item.offsetTop < div.scrollTop || (item.offsetTop + item.clientHeight > div.clientHeight + div.scrollTop)) { + return false + } + return true + } + scrollIntoView(id, instant) { + return new Promise((resolve, reject) => { + if (id == null) id = this.selected + let nd = this.get(id) + if (nd == null) return + let item = query(this.box).find('#node_'+ w2utils.escapeId(id)).get(0) + item.scrollIntoView({ block: 'center', inline: 'center', behavior: instant ? 'atuo' : 'smooth' }) + setTimeout(() => { this.resize(); resolve() }, instant ? 0 : 500) + }) + } + dblClick(id, event) { + let nd = this.get(id) + // event before + let edata = this.trigger('dblClick', { target: id, originalEvent: event, object: nd }) + if (edata.isCancelled === true) return + // default action + this.toggle(id) + // event after + edata.finish() + } + contextMenu(id, event) { + let nd = this.get(id) + if (id != this.selected) this.click(id) + // event before + let edata = this.trigger('contextMenu', { target: id, originalEvent: event, object: nd, allowOnDisabled: false }) + if (edata.isCancelled === true) return + // default action + if (nd.disabled && !edata.allowOnDisabled) return + if (this.menu.length > 0) { + w2menu.show({ + name: this.name + '_menu', + anchor: document.body, + items: this.menu, + originalEvent: event + }) + .select(evt => { + this.menuClick(id, parseInt(evt.detail.index), event) + }) + } + // prevent default context menu + if (event.preventDefault) event.preventDefault() + // event after + edata.finish() + } + menuClick(itemId, index, event) { + // event before + let edata = this.trigger('menuClick', { target: itemId, originalEvent: event, menuIndex: index, menuItem: this.menu[index] }) + if (edata.isCancelled === true) return + // default action + // -- empty + // event after + edata.finish() + } + goFlat() { + // event before + let edata = this.trigger('flat', { goFlat: !this.flat }) + if (edata.isCancelled === true) return + // default action + this.flat = !this.flat + this.refresh() + // event after + edata.finish() + } + render(box) { + let time = Date.now() + let obj = this + if (typeof box == 'string') box = query(box).get(0) + // event before + let edata = this.trigger('render', { target: this.name, box: box ?? this.box }) + if (edata.isCancelled === true) return + // default action + if (box != null) { + // clean previous box + if (query(this.box).find('.w2ui-sidebar-body').length > 0) { + query(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-sidebar') + .html('') + } + this.box = box + } + if (!this.box) return + query(this.box) + .attr('name', this.name) + .addClass('w2ui-reset w2ui-sidebar') + .html(`
    +
    + +
    +
    +
    `) + let rect = query(this.box).get(0).getBoundingClientRect() + query(this.box).find(':scope > div').css({ + width : rect.width + 'px', + height : rect.height + 'px' + }) + query(this.box).get(0).style.cssText += this.style + // focus + let kbd_timer + query(this.box).find('#sidebar_'+ this.name + '_focus') + .on('focus', function(event) { + clearTimeout(kbd_timer) + if (!obj.hasFocus) obj.focus(event) + }) + .on('blur', function(event) { + kbd_timer = setTimeout(() => { + if (obj.hasFocus) { obj.blur(event) } + }, 100) + }) + .on('keydown', function(event) { + if (event.keyCode != 9) { // not tab + w2ui[obj.name].keydown.call(w2ui[obj.name], event) + } + }) + query(this.box).off('mousedown') + .on('mousedown', function(event) { + // set focus to grid + setTimeout(() => { + // if input then do not focus + if (['INPUT', 'TEXTAREA', 'SELECT'].indexOf(event.target.tagName.toUpperCase()) == -1) { + let $input = query(obj.box).find('#sidebar_'+ obj.name + '_focus') + if (document.activeElement != $input.get(0)) { + $input.get(0).focus() + } + } + }, 1) + }) + // observe div resize + this.last.observeResize = new ResizeObserver(() => { this.resize() }) + this.last.observeResize.observe(this.box) + // event after + edata.finish() + // --- + this.refresh() + return Date.now() - time + } + update(id, options) { + // quick function to refresh just this item (not sub nodes) + // - icon, class, style, text, count + let nd = this.get(id) + let level + if (nd) { + let $el = query(this.box).find('#node_'+ w2utils.escapeId(nd.id)) + if (nd.group) { + if (options.text) { + nd.text = options.text + $el.find('.w2ui-group-text').replace(typeof nd.text == 'function' + ? nd.text.call(this, nd) + : ''+ nd.text +'') + delete options.text + } + if (options.class) { + nd.class = options.class + level = $el.data('level') + $el.get(0).className = 'w2ui-node-group w2ui-level-'+ level +(nd.class ? ' ' + nd.class : '') + delete options.class + } + if (options.style) { + nd.style = options.style + $el.get(0).nextElementSibling.style = nd.style +';'+ (!nd.hidden && nd.expanded ? '' : 'display: none;') + delete options.style + } + } else { + if (options.icon) { + let $icon = $el.find('.w2ui-node-image > span') + if ($icon.length > 0) { + nd.icon = options.icon + $icon[0].className = (typeof nd.icon == 'function' ? nd.icon.call(this, nd) : nd.icon) + delete options.icon + } + } + if (options.count) { + nd.count = options.count + $el.find('.w2ui-node-count').html(nd.count) + if ($el.find('.w2ui-node-count').length > 0) delete options.count + } + if (options.class && $el.length > 0) { + nd.class = options.class + level = $el.data('level') + $el[0].className = 'w2ui-node w2ui-level-'+ level + (nd.selected ? ' w2ui-selected' : '') + (nd.disabled ? ' w2ui-disabled' : '') + (nd.class ? ' ' + nd.class : '') + delete options.class + } + if (options.text) { + nd.text = options.text + $el.find('.w2ui-node-text').html(typeof nd.text == 'function' ? nd.text.call(this, nd) : nd.text) + delete options.text + } + if (options.style && $el.length > 0) { + let $txt = $el.find('.w2ui-node-text') + nd.style = options.style + $txt[0].style = nd.style + delete options.style + } + } + } + // return what was not set + return options + } + refresh(id, noBinding) { + if (this.box == null) return + let time = Date.now() + // event before + let edata = this.trigger('refresh', { + target: (id != null ? id : this.name), + nodeId: (id != null ? id : null), + fullRefresh: (id != null ? false : true) + }) + if (edata.isCancelled === true) return + // adjust top and bottom + let flatHTML = '' + if (this.flatButton == true) { + flatHTML = `
    ` + } + if (id == null && (this.topHTML !== '' || flatHTML !== '')) { + query(this.box).find('.w2ui-sidebar-top').html(this.topHTML + flatHTML) + query(this.box).find('.w2ui-sidebar-body') + .css('top', query(this.box).find('.w2ui-sidebar-top').get(0)?.clientHeight + 'px') + query(this.box).find('.w2ui-flat') + .off('click') + .on('click', event => { this.goFlat() }) + } + if (id != null && this.bottomHTML !== '') { + query(this.box).find('.w2ui-sidebar-bottom').html(this.bottomHTML) + query(this.box).find('.w2ui-sidebar-body') + .css('bottom', query(this.box).find('.w2ui-sidebar-bottom').get(0)?.clientHeight + 'px') + } + // default action + query(this.box).find(':scope > div').removeClass('w2ui-sidebar-flat').addClass(this.flat ? 'w2ui-sidebar-flat' : '').css({ + width : query(this.box).get(0)?.clientWidth + 'px', + height: query(this.box).get(0)?.clientHeight + 'px' + }) + // if no parent - reset nodes + if (this.nodes.length > 0 && this.nodes[0].parent == null) { + let tmp = this.nodes + this.nodes = [] + this.add(this, tmp) + } + let obj = this + let node + let nodeSubId + if (id == null) { + node = this + nodeSubId = '.w2ui-sidebar-body' + } else { + node = this.get(id) + if (node == null) return + nodeSubId = '#node_'+ w2utils.escapeId(node.id) + '_sub' + } + let nodeId = '#node_'+ w2utils.escapeId(node.id) + let nodeHTML + if (node !== this) { + nodeHTML = getNodeHTML(node) + query(this.box).find(nodeId).before('') + query(this.box).find(nodeId).remove() + query(this.box).find(nodeSubId).remove() + query(this.box).find('#sidebar_'+ this.name + '_tmp').before(nodeHTML) + query(this.box).find('#sidebar_'+ this.name + '_tmp').remove() + } + // remember scroll position + let div = query(this.box).find(':scope > div').get(0) + let scroll = { + top: div?.scrollTop, + left: div?.scrollLeft + } + // refresh sub nodes + query(this.box).find(nodeSubId).html('') + for (let i = 0; i < node.nodes.length; i++) { + let subNode = node.nodes[i] + nodeHTML = getNodeHTML(subNode) + query(this.box).find(nodeSubId).append(nodeHTML) + if (subNode.nodes.length !== 0) { + this.refresh(subNode.id, true) + } else { + // trigger event + let edata2 = this.trigger('refresh', { target: subNode.id }) + if (edata2.isCancelled === true) return + // event after + edata2.finish() + } + } + // reset scroll + if (div) { + div.scrollTop = scroll.top + div.scrollLeft = scroll.left + } + // bind events + if (!noBinding) { + let els = query(this.box).find(`${nodeId}.w2ui-eaction, ${nodeSubId} .w2ui-eaction`) + w2utils.bindEvents(els, this) + } + // event after + edata.finish() + return Date.now() - time + function getNodeHTML(nd) { + let html = '' + let icon = nd.icon + if (icon == null) icon = obj.icon + // -- find out level + let tmp = nd.parent + let level = 0 + while (tmp && tmp.parent != null) { + // if (tmp.group) level--; + tmp = tmp.parent + level++ + } + if (nd.caption != null && nd.text == null) nd.text = nd.caption + if (nd.caption != null) { + console.log('NOTICE: sidebar node.caption property is deprecated, please use node.text. Node -> ', nd) + nd.text = nd.caption + } + if (Array.isArray(nd.nodes) && nd.nodes.length > 0) nd.collapsible = true + if (nd.group) { + let text = w2utils.lang(typeof nd.text == 'function' ? nd.text.call(obj, nd) : nd.text) + if (String(text).substr(0, 5) != '${text}` + } + html = ` +
    + ${nd.groupShowHide && nd.collapsible + ? `${!nd.hidden && nd.expanded ? w2utils.lang('Hide') : w2utils.lang('Show')}` + : '' + } ${text} +
    +
    +
    ` + if (obj.flat) { + html = ` +
     
    +
    ` + } + } else { + if (nd.selected && !nd.disabled) obj.selected = nd.id + tmp = '' + if (icon) { + tmp = ` +
    + +
    ` + } + let expand = '' + let counts = (nd.count != null + ? `
    + ${nd.count} +
    ` + : '') + if (nd.collapsible === true) { + expand = `
    ` + } + let text = w2utils.lang(typeof nd.text == 'function' ? nd.text.call(obj, nd) : nd.text) + // array with classes + let classes = ['w2ui-node', `w2ui-level-${level}`, 'w2ui-eaction'] + if (nd.selected) classes.push('w2ui-selected') + if (nd.disabled) classes.push('w2ui-disabled') + if (nd.class) classes.push(nd.class) + html = ` +
    + ${obj.handle.html + ? `
    + ${typeof obj.handle.html == 'function' ? obj.handle.html.call(obj, nd) : obj.handle.html} +
    ` + : '' + } +
    + ${expand} ${tmp} ${counts} +
    ${text}
    +
    +
    +
    ` + if (obj.flat) { + html = ` +
    +
    ${tmp}
    +
    +
    ` + } + } + return html + } + } + mouseAction(action, el, id, event, type) { + let node = this.get(id) + let text = w2utils.lang(typeof node.text == 'function' ? node.text.call(this, node) : node.text) + let tooltip = text + (node.count || node.count === 0 ? ' - '+ node.count +'' : '') + let edata = this.trigger('mouse' + action, { target: id, node, tooltip, originalEvent: event }) + if (type == 'tooltip') { + this.tooltip(el, tooltip, id) + } + if (type == 'handle') { + this.handleTooltip(el, id) + } + edata.finish() + } + tooltip(el, text, id) { + let $el = query(el).find('.w2ui-node-data') + if (text !== '') { + w2tooltip.show({ + anchor: $el.get(0), + name: this.name + '_tooltip', + html: text, + position: 'right|left' + }) + } else { + w2tooltip.hide(this.name + '_tooltip') + } + } + handleTooltip(anchor, id) { + let text = this.handle.tooltip + if (typeof text == 'function') { + text = text(id) + } + if (text !== '' && id != null) { + w2tooltip.show({ + anchor: anchor, + name: this.name + '_tooltip', + html: text, + position: 'top|bottom' + }) + } else { + w2tooltip.hide(this.name + '_tooltip') + } + } + showPlus(el, color) { + query(el).find('span:nth-child(1)').css('color', color) + } + resize() { + let time = Date.now() + // event before + let edata = this.trigger('resize', { target: this.name }) + if (edata.isCancelled === true) return + // default action + let rect = query(this.box).get(0).getBoundingClientRect() + query(this.box).css('overflow', 'hidden') // container should have no overflow + query(this.box).find(':scope > div').css({ + width : rect.width + 'px', + height : rect.height + 'px' + }) + // event after + edata.finish() + return Date.now() - time + } + destroy() { + // event before + let edata = this.trigger('destroy', { target: this.name }) + if (edata.isCancelled === true) return + // clean up + if (query(this.box).find('.w2ui-sidebar-body').length > 0) { + query(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-sidebar') + .html('') + } + this.last.observeResize?.disconnect() + delete w2ui[this.name] + // event after + edata.finish() + } + lock(msg, showSpinner) { + let args = Array.from(arguments) + args.unshift(this.box) + w2utils.lock(...args) + } + unlock(speed) { + w2utils.unlock(this.box, speed) + } +} +/** + * Part of w2ui 2.0 library + * - Dependencies: mQuery, w2utils, w2base, w2tooltip + * + * == 2.0 changes + * - CSP - fixed inline events + * - removed jQuery dependency + * - observeResize for the box + * - refactored w2events + * - scrollIntoView - removed callback + * - scroll, scrollIntoView return promise + * - animateInsert, animateClose - returns a promise + * - add, insert return a promise + * - onMouseEnter, onMouseLeave, onMouseDown, onMouseUp + */ + +class w2tabs extends w2base { + constructor(options) { + super(options.name) + this.box = null // DOM Element that holds the element + this.name = null // unique name for w2ui + this.active = null + this.reorder = false + this.flow = 'down' // can be down or up + this.tooltip = 'top|left' // can be top, bottom, left, right + this.tabs = [] + this.routeData = {} // data for dynamic routes + this.last = {} // placeholder for internal variables + this.right = '' + this.style = '' + this.onClick = null + this.onMouseEnter = null // mouse enter and lease + this.onMouseLeave = null + this.onMouseDown = null + this.onMouseUp = null + this.onClose = null + this.onRender = null + this.onRefresh = null + this.onResize = null + this.onDestroy = null + this.tab_template = { + id: null, + text: null, + route: null, + hidden: false, + disabled: false, + closable: false, + tooltip: null, + style: '', + onClick: null, + onRefresh: null, + onClose: null + } + let tabs = options.tabs + delete options.tabs + // mix in options + Object.assign(this, options) + // add item via method to makes sure item_template is applied + if (Array.isArray(tabs)) this.add(tabs) + // need to reassign back to keep it in config + options.tabs = tabs + // render if box specified + if (typeof this.box == 'string') this.box = query(this.box).get(0) + if (this.box) this.render(this.box) + } + add(tab) { + return this.insert(null, tab) + } + insert(id, tabs) { + if (!Array.isArray(tabs)) tabs = [tabs] + // assume it is array + let proms = [] + tabs.forEach(tab => { + // checks + if (tab.id == null) { + console.log(`ERROR: The parameter "id" is required but not supplied. (obj: ${this.name})`) + return + } + if (!w2utils.checkUniqueId(tab.id, this.tabs, 'tabs', this.name)) return + // add tab + let it = Object.assign({}, this.tab_template, tab) + if (id == null) { + this.tabs.push(it) + proms.push(this.animateInsert(null, it)) + } else { + let middle = this.get(id, true) + let before = this.tabs[middle].id + this.tabs.splice(middle, 0, it) + proms.push(this.animateInsert(before, it)) + } + }) + return Promise.all(proms) + } + remove() { + let effected = 0 + Array.from(arguments).forEach(it => { + let tab = this.get(it) + if (!tab) return + effected++ + // remove from array + this.tabs.splice(this.get(tab.id, true), 1) + // remove from screen + query(this.box).find(`#tabs_${this.name}_tab_${w2utils.escapeId(tab.id)}`).remove() + }) + this.resize() + return effected + } + select(id) { + if (this.active == id || this.get(id) == null) return false + this.active = id + this.refresh() + return true + } + set(id, tab) { + let index = this.get(id, true) + if (index == null) return false + w2utils.extend(this.tabs[index], tab) + this.refresh(id) + return true + } + get(id, returnIndex) { + if (arguments.length === 0) { + let all = [] + for (let i1 = 0; i1 < this.tabs.length; i1++) { + if (this.tabs[i1].id != null) { + all.push(this.tabs[i1].id) + } + } + return all + } else { + for (let i2 = 0; i2 < this.tabs.length; i2++) { + if (this.tabs[i2].id == id) { // need to be == since id can be numeric + return (returnIndex === true ? i2 : this.tabs[i2]) + } + } + } + return null + } + show() { + let effected = [] + Array.from(arguments).forEach(it => { + let tab = this.get(it) + if (!tab || tab.hidden === false) return + tab.hidden = false + effected.push(tab.id) + }) + setTimeout(() => { effected.forEach(it => { this.refresh(it); this.resize() }) }, 15) // needs timeout + return effected + } + hide() { + let effected = [] + Array.from(arguments).forEach(it => { + let tab = this.get(it) + if (!tab || tab.hidden === true) return + tab.hidden = true + effected.push(tab.id) + }) + setTimeout(() => { effected.forEach(it => { this.refresh(it); this.resize() }) }, 15) // needs timeout + return effected + } + enable() { + let effected = [] + Array.from(arguments).forEach(it => { + let tab = this.get(it) + if (!tab || tab.disabled === false) return + tab.disabled = false + effected.push(tab.id) + }) + setTimeout(() => { effected.forEach(it => { this.refresh(it) }) }, 15) // needs timeout + return effected + } + disable() { + let effected = [] + Array.from(arguments).forEach(it => { + let tab = this.get(it) + if (!tab || tab.disabled === true) return + tab.disabled = true + effected.push(tab.id) + }) + setTimeout(() => { effected.forEach(it => { this.refresh(it) }) }, 15) // needs timeout + return effected + } + dragMove(event) { + if (!this.last.reordering) return + let self = this + let info = this.last.moving + let tab = this.tabs[info.index] + let next = _find(info.index, 1) + let prev = _find(info.index, -1) + let $el = query(this.box).find('#tabs_'+ this.name + '_tab_'+ w2utils.escapeId(tab.id)) + if (info.divX > 0 && next) { + let $nextEl = query(this.box).find('#tabs_'+ this.name + '_tab_'+ w2utils.escapeId(next.id)) + let width1 = parseInt($el.get(0).clientWidth) + let width2 = parseInt($nextEl.get(0).clientWidth) + if (width1 < width2) { + width1 = Math.floor(width1 / 3) + width2 = width2 - width1 + } else { + width1 = Math.floor(width2 / 3) + width2 = width2 - width1 + } + if (info.divX > width2) { + let index = this.tabs.indexOf(next) + this.tabs.splice(info.index, 0, this.tabs.splice(index, 1)[0]) // reorder in the array + info.$tab.before($nextEl.get(0)) + info.$tab.css('opacity', 0) + Object.assign(this.last.moving, { + index: index, + divX: -width1, + x: event.pageX + width1, + left: info.left + info.divX + width1 + }) + return + } + } + if (info.divX < 0 && prev) { + let $prevEl = query(this.box).find('#tabs_'+ this.name + '_tab_'+ w2utils.escapeId(prev.id)) + let width1 = parseInt($el.get(0).clientWidth) + let width2 = parseInt($prevEl.get(0).clientWidth) + if (width1 < width2) { + width1 = Math.floor(width1 / 3) + width2 = width2 - width1 + } else { + width1 = Math.floor(width2 / 3) + width2 = width2 - width1 + } + if (Math.abs(info.divX) > width2) { + let index = this.tabs.indexOf(prev) + this.tabs.splice(info.index, 0, this.tabs.splice(index, 1)[0]) // reorder in the array + $prevEl.before(info.$tab) + info.$tab.css('opacity', 0) + Object.assign(info, { + index: index, + divX: width1, + x: event.pageX - width1, + left: info.left + info.divX - width1 + }) + return + } + } + function _find(ind, inc) { + ind += inc + let tab = self.tabs[ind] + if (tab && tab.hidden) { + tab = _find(ind, inc) + } + return tab + } + } + mouseAction(action, id, event) { + let tab = this.get(id) + let edata = this.trigger('mouse' + action, { target: id, tab, object: tab, originalEvent: event }) + if (edata.isCancelled === true || tab.disabled || tab.hidden) return + switch (action) { + case 'Enter': + this.tooltipShow(id) + break + case 'Leave': + this.tooltipHide(id) + break + case 'Down': + this.initReorder(id, event) + break + case 'Up': + break + } + edata.finish() + } + tooltipShow(id) { + let item = this.get(id) + let el = query(this.box).find('#tabs_'+ this.name + '_tab_'+ w2utils.escapeId(id)).get(0) + if (this.tooltip == null || item.disabled || this.last.reordering) { + return + } + let pos = this.tooltip + let txt = item.tooltip + if (typeof txt == 'function') txt = txt.call(this, item) + w2tooltip.show({ + anchor: el, + name: this.name + '_tooltip', + html: txt, + position: pos + }) + } + tooltipHide(id) { + if (this.tooltip == null) return + w2tooltip.hide(this.name + '_tooltip') + } + getTabHTML(id) { + let index = this.get(id, true) + let tab = this.tabs[index] + if (tab == null) return false + if (tab.text == null && tab.caption != null) tab.text = tab.caption + if (tab.tooltip == null && tab.hint != null) tab.tooltip = tab.hint // for backward compatibility + if (tab.caption != null) { + console.log('NOTICE: tabs tab.caption property is deprecated, please use tab.text. Tab -> ', tab) + } + if (tab.hint != null) { + console.log('NOTICE: tabs tab.hint property is deprecated, please use tab.tooltip. Tab -> ', tab) + } + let text = tab.text + if (typeof text == 'function') text = text.call(this, tab) + if (text == null) text = '' + let closable = '' + let addStyle = '' + if (tab.hidden) { addStyle += 'display: none;' } + if (tab.disabled) { addStyle += 'opacity: 0.2;' } + if (tab.closable && !tab.disabled) { + closable = `
    +
    ` + } + return ` +
    + ${w2utils.lang(text) + closable} +
    ` + } + refresh(id) { + let time = Date.now() + if (this.flow == 'up') { + query(this.box).addClass('w2ui-tabs-up') + } else { + query(this.box).removeClass('w2ui-tabs-up') + } + // event before + let edata = this.trigger('refresh', { target: (id != null ? id : this.name), object: this.get(id) }) + if (edata.isCancelled === true) return + if (id == null) { + // refresh all + for (let i = 0; i < this.tabs.length; i++) { + this.refresh(this.tabs[i].id) + } + } else { + // create or refresh only one item + let selector = '#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(id) + let $tab = query(this.box).find(selector) + let tabHTML = this.getTabHTML(id) + if ($tab.length === 0) { + query(this.box).find('#tabs_'+ this.name +'_right').before(tabHTML) + } else { + if (query(this.box).find('.tab-animate-insert').length == 0) { + $tab.replace(tabHTML) + } + } + w2utils.bindEvents(query(this.box).find(`${selector}, ${selector} .w2ui-eaction`), this) + } + // right html + query(this.box).find('#tabs_'+ this.name +'_right').html(this.right) + // event after + edata.finish() + // this.resize(); + return Date.now() - time + } + render(box) { + let time = Date.now() + if (typeof box == 'string') box = query(box).get(0) + // event before + let edata = this.trigger('render', { target: this.name, box: box ?? this.box }) + if (edata.isCancelled === true) return + // default action + if (box != null) { + // clean previous box + if (query(this.box).find('#tabs_'+ this.name + '_right').length > 0) { + query(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-tabs') + .html('') + } + this.box = box + } + if (!this.box) return false + // render all buttons + let html =` +
    +
    +
    ${this.right}
    +
    +
    +
    ` + query(this.box) + .attr('name', this.name) + .addClass('w2ui-reset w2ui-tabs') + .html(html) + if (query(this.box).length > 0) { + query(this.box)[0].style.cssText += this.style + } + w2utils.bindEvents(query(this.box).find('.w2ui-eaction'), this) + // observe div resize + this.last.observeResize = new ResizeObserver(() => { this.resize() }) + this.last.observeResize.observe(this.box) + // event after + edata.finish() + this.refresh() + this.resize() + return Date.now() - time + } + initReorder(id, event) { + if (!this.reorder) return + let self = this + let $tab = query(this.box).find('#tabs_' + this.name + '_tab_' + w2utils.escapeId(id)) + let tabIndex = this.get(id, true) + let $ghost = query($tab.get(0).cloneNode(true)) + let edata + $ghost.attr('id', '#tabs_' + this.name + '_tab_ghost') + this.last.moving = { + index: tabIndex, + indexFrom: tabIndex, + $tab: $tab, + $ghost: $ghost, + divX: 0, + left: $tab.get(0).getBoundingClientRect().left, + parentX: query(this.box).get(0).getBoundingClientRect().left, + x: event.pageX, + opacity: $tab.css('opacity') + } + query(document) + .off('.w2uiTabReorder') + .on('mousemove.w2uiTabReorder', function (event) { + if (!self.last.reordering) { + // event before + edata = self.trigger('reorder', { target: self.tabs[tabIndex].id, indexFrom: tabIndex, tab: self.tabs[tabIndex] }) + if (edata.isCancelled === true) return + w2tooltip.hide(this.name + '_tooltip') + self.last.reordering = true + $ghost.addClass('moving') + $ghost.css({ + 'pointer-events': 'none', + 'position': 'absolute', + 'left': $tab.get(0).getBoundingClientRect().left + }) + $tab.css('opacity', 0) + query(self.box).find('.w2ui-scroll-wrapper').append($ghost.get(0)) + query(self.box).find('.w2ui-tab-close').hide() + } + self.last.moving.divX = event.pageX - self.last.moving.x + $ghost.css('left', (self.last.moving.left - self.last.moving.parentX + self.last.moving.divX) + 'px') + self.dragMove(event) + }) + .on('mouseup.w2uiTabReorder', function () { + query(document).off('.w2uiTabReorder') + $ghost.css({ + 'transition': '0.1s', + 'left': self.last.moving.$tab.get(0).getBoundingClientRect().left - self.last.moving.parentX + }) + query(self.box).find('.w2ui-tab-close').show() + setTimeout(() => { + $ghost.remove() + $tab.css({ opacity: self.last.moving.opacity }) + // self.render() + if (self.last.reordering) { + edata.finish({ indexTo: self.last.moving.index }) + } + self.last.reordering = false + }, 100) + }) + } + scroll(direction, instant) { + return new Promise((resolve, reject) => { + let scrollBox = query(this.box).find('.w2ui-scroll-wrapper') + let scrollLeft = scrollBox.get(0).scrollLeft + let right = scrollBox.find('.w2ui-tabs-right').get(0) + let width1 = scrollBox.parent().get(0).getBoundingClientRect().width + let width2 = scrollLeft + parseInt(right.offsetLeft) + parseInt(right.clientWidth ) + switch (direction) { + case 'left': { + let scroll = scrollLeft - width1 + 50 // 35 is width of both button + if (scroll <= 0) scroll = 0 + scrollBox.get(0).scrollTo({ top: 0, left: scroll, behavior: instant ? 'atuo' : 'smooth' }) + break + } + case 'right': { + let scroll = scrollLeft + width1 - 50 // 35 is width of both button + if (scroll >= width2 - width1) scroll = width2 - width1 + scrollBox.get(0).scrollTo({ top: 0, left: scroll, behavior: instant ? 'atuo' : 'smooth' }) + break + } + } + setTimeout(() => { this.resize(); resolve() }, instant ? 0 : 350) + }) + } + scrollIntoView(id, instant) { + return new Promise((resolve, reject) => { + if (id == null) id = this.active + let tab = this.get(id) + if (tab == null) return + let tabEl = query(this.box).find('#tabs_' + this.name + '_tab_' + w2utils.escapeId(id)).get(0) + tabEl.scrollIntoView({ block: 'start', inline: 'center', behavior: instant ? 'atuo' : 'smooth' }) + setTimeout(() => { this.resize(); resolve() }, instant ? 0 : 500) + }) + } + resize() { + let time = Date.now() + if (this.box == null) return + // event before + let edata = this.trigger('resize', { target: this.name }) + if (edata.isCancelled === true) return + // show hide overflow buttons + let box = query(this.box) + box.find('.w2ui-scroll-left, .w2ui-scroll-right').hide() + let scrollBox = box.find('.w2ui-scroll-wrapper').get(0) + let $right = box.find('.w2ui-tabs-right') + let boxWidth = box.get(0).getBoundingClientRect().width + let itemsWidth = ($right.length > 0 ? $right[0].offsetLeft + $right[0].clientWidth : 0) + if (boxWidth < itemsWidth) { + // we have overflown content + if (scrollBox.scrollLeft > 0) { + box.find('.w2ui-scroll-left').show() + } + if (boxWidth < itemsWidth - scrollBox.scrollLeft) { + box.find('.w2ui-scroll-right').show() + } + } + // event after + edata.finish() + return Date.now() - time + } + destroy() { + // event before + let edata = this.trigger('destroy', { target: this.name }) + if (edata.isCancelled === true) return + // clean up + if (query(this.box).find('#tabs_'+ this.name + '_right').length > 0) { + query(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-tabs') + .html('') + } + this.last.observeResize?.disconnect() + delete w2ui[this.name] + // event after + edata.finish() + } + // =================================================== + // -- Internal Event Handlers + click(id, event) { + let tab = this.get(id) + if (tab == null || tab.disabled || this.last.reordering) return false + // event before + let edata = this.trigger('click', { target: id, tab: tab, object: tab, originalEvent: event }) + if (edata.isCancelled === true) return + // default action + query(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.active)).removeClass('active') + this.active = tab.id + query(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.active)).addClass('active') + // route processing + if (typeof tab.route == 'string') { + let route = tab.route !== '' ? String('/'+ tab.route).replace(/\/{2,}/g, '/') : '' + let info = w2utils.parseRoute(route) + if (info.keys.length > 0) { + for (let k = 0; k < info.keys.length; k++) { + if (this.routeData[info.keys[k].name] == null) continue + route = route.replace((new RegExp(':'+ info.keys[k].name, 'g')), this.routeData[info.keys[k].name]) + } + } + setTimeout(() => { window.location.hash = route }, 1) + } + // event after + edata.finish() + } + clickClose(id, event) { + let tab = this.get(id) + if (tab == null || tab.disabled) return false + // event before + let edata = this.trigger('close', { target: id, object: tab, tab, originalEvent: event }) + if (edata.isCancelled === true) return + this.animateClose(id).then(() => { + this.remove(id) + edata.finish() + this.refresh() + }) + if (event) event.stopPropagation() + } + animateClose(id) { + return new Promise((resolve, reject) => { + let $tab = query(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(id)) + let width = parseInt($tab.get(0).clientWidth || 0) + let anim = `
    ` + let $anim = $tab.replace(anim) + setTimeout(() => { $anim.css({ width: '0px' }) }, 1) + setTimeout(() => { + $anim.remove() + this.resize() + resolve() + }, 500) + }) + } + animateInsert(id, tab) { + return new Promise((resolve, reject) => { + let $before = query(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(id)) + let $tab = query.html(this.getTabHTML(tab.id)) + if ($before.length == 0) { + $before = query(this.box).find('#tabs_tabs_right') + $before.before($tab) + this.resize() + } else { + $tab.css({ opacity: 0 }) + // first insert tab on the right to get its proper dimentions + query(this.box).find('#tabs_tabs_right').before($tab.get(0)) + let $tmp = query(this.box).find('#' + $tab.attr('id')) + let width = $tmp.get(0).clientWidth ?? 0 + // insert animation div + let $anim = query.html('
    ') + $before.before($anim) + // hide tab and move it in the right position + $tab.hide() + $anim.before($tab[0]) + setTimeout(() => { $anim.css({ width: width + 'px' }) }, 1) + setTimeout(() => { + $anim.remove() + $tab.css({ opacity: 1 }).show() + this.refresh(tab.id) + this.resize() + resolve() + }, 500) + } + }) + } +} +/** + * Part of w2ui 2.0 library + * - Dependencies: mQuery, w2utils, w2base, w2tabs, w2toolbar + * + * == 2.0 changes + * - CSP - fixed inline events + * - remove jQuery dependency + * - layout.confirm - refactored + * - layout.message - refactored + * - panel.removed + */ + +let w2panels = ['top', 'left', 'main', 'preview', 'right', 'bottom'] +class w2layout extends w2base { + constructor(options) { + super(options.name) + this.box = null // DOM Element that holds the element + this.name = null // unique name for w2ui + this.panels = [] + this.last = {} + this.padding = 1 // panel padding + this.resizer = 4 // resizer width or height + this.style = '' + this.onShow = null + this.onHide = null + this.onResizing = null + this.onResizerClick = null + this.onRender = null + this.onRefresh = null + this.onChange = null + this.onResize = null + this.onDestroy = null + this.panel_template = { + type: null, // left, right, top, bottom + title: '', + size: 100, // width or height depending on panel name + minSize: 20, + maxSize: false, + hidden: false, + resizable: false, + overflow: 'auto', + style: '', + html: '', // can be String or Object with .render(box) method + tabs: null, + toolbar: null, + width: null, // read only + height: null, // read only + show: { + toolbar: false, + tabs: false + }, + removed: null, // function to call when content is overwritten + onRefresh: null, + onShow: null, + onHide: null + } + // mix in options + Object.assign(this, options) + if (!Array.isArray(this.panels)) this.panels = [] + // add defined panels + this.panels.forEach((panel, ind) => { + this.panels[ind] = w2utils.extend({}, this.panel_template, panel) + if (w2utils.isPlainObject(panel.tabs) || Array.isArray(panel.tabs)) initTabs(this, panel.type) + if (w2utils.isPlainObject(panel.toolbar) || Array.isArray(panel.toolbar)) initToolbar(this, panel.type) + }) + // add all other panels + w2panels.forEach(tab => { + if (this.get(tab) != null) return + this.panels.push(w2utils.extend({}, this.panel_template, { type: tab, hidden: (tab !== 'main'), size: 50 })) + }) + // render if box specified + if (typeof this.box == 'string') this.box = query(this.box).get(0) + if (this.box) this.render(this.box) + function initTabs(object, panel, tabs) { + let pan = object.get(panel) + if (pan != null && tabs == null) tabs = pan.tabs + if (pan == null || tabs == null) return false + // instantiate tabs + if (Array.isArray(tabs)) tabs = { tabs: tabs } + let name = object.name + '_' + panel + '_tabs' + if (w2ui[name]) w2ui[name].destroy() // destroy if existed + pan.tabs = new w2tabs(w2utils.extend({}, tabs, { owner: object, name: object.name + '_' + panel + '_tabs' })) + pan.show.tabs = true + return true + } + function initToolbar(object, panel, toolbar) { + let pan = object.get(panel) + if (pan != null && toolbar == null) toolbar = pan.toolbar + if (pan == null || toolbar == null) return false + // instantiate toolbar + if (Array.isArray(toolbar)) toolbar = { items: toolbar } + let name = object.name + '_' + panel + '_toolbar' + if (w2ui[name]) w2ui[name].destroy() // destroy if existed + pan.toolbar = new w2toolbar(w2utils.extend({}, toolbar, { owner: object, name: object.name + '_' + panel + '_toolbar' })) + pan.show.toolbar = true + return true + } + } + html(panel, data, transition) { + let p = this.get(panel) + let promise = { + panel: panel, + html: p.html, + error: false, + cancelled: false, + removed(cb) { + if (typeof cb == 'function') { + p.removed = cb + } + } + } + if (typeof p.removed == 'function') { + p.removed({ panel: panel, html: p.html, html_new: data, transition: transition || 'none' }) + p.removed = null // this is one time call back only + } + // if it is CSS panel + if (panel == 'css') { + query(this.box).find('#layout_'+ this.name +'_panel_css').html('') + promise.status = true + return promise + } + if (p == null) { + console.log('ERROR: incorrect panel name. Panel name can be main, left, right, top, bottom, preview or css') + promise.error = true + return promise + } + if (data == null) { + return promise + } + // event before + let edata = this.trigger('change', { target: panel, panel: p, html_new: data, transition: transition }) + if (edata.isCancelled === true) { + promise.cancelled = true + return promise + } + let pname = '#layout_'+ this.name + '_panel_'+ p.type + let current = query(this.box).find(pname + '> .w2ui-panel-content') + let panelTop = 0 + if (current.length > 0) { + query(this.box).find(pname).get(0).scrollTop = 0 + panelTop = query(current).css('top') + } + if (p.html === '') { + p.html = data + this.refresh(panel) + } else { + p.html = data + if (!p.hidden) { + if (transition != null && transition !== '') { + // apply transition + query(this.box).addClass('animating') + let div1 = query(this.box).find(pname + '> .w2ui-panel-content') + div1.after('
    ') + let div2 = query(this.box).find(pname + '> .w2ui-panel-content.new-panel') + div1.css('top', panelTop) + div2.css('top', panelTop) + if (typeof data == 'object') { + data.box = div2[0] // do not do .render(box); + data.render() + } else { + div2.hide().html(data) + } + w2utils.transition(div1[0], div2[0], transition, () => { + div1.remove() + div2.removeClass('new-panel') + div2.css('overflow', p.overflow) + // make sure only one content left + query(query(this.box).find(pname + '> .w2ui-panel-content').get(1)).remove() + query(this.box).removeClass('animating') + this.refresh(panel) + }) + } else { + this.refresh(panel) + } + } + } + // event after + edata.finish() + return promise + } + message(panel, options) { + let p = this.get(panel) + let box = query(this.box).find('#layout_'+ this.name + '_panel_'+ p.type) + let oldOverflow = box.css('overflow') + box.css('overflow', 'hidden') + let prom = w2utils.message({ + owner: this, + box : box.get(0), + after: '.w2ui-panel-title', + param: panel + }, options) + if (prom) { + prom.self.on('close:after', () => { + box.css('overflow', oldOverflow) + }) + } + return prom + } + confirm(panel, options) { + let p = this.get(panel) + let box = query(this.box).find('#layout_'+ this.name + '_panel_'+ p.type) + let oldOverflow = box.css('overflow') + box.css('overflow', 'hidden') + let prom = w2utils.confirm({ + owner : this, + box : box.get(0), + after : '.w2ui-panel-title', + param : panel + }, options) + if (prom) { + prom.self.on('close:after', () => { + box.css('overflow', oldOverflow) + }) + } + return prom + } + load(panel, url, transition) { + return new Promise((resolve, reject) => { + if ((panel == 'css' || this.get(panel) != null) && url != null) { + fetch(url) + .then(resp => resp.text()) + .then(text => { + this.resize() + resolve(this.html(panel, text, transition)) + }) + } else { + reject() + } + }) + } + sizeTo(panel, size, instant) { + let pan = this.get(panel) + if (pan == null) return false + // resize + query(this.box).find(':scope > div > .w2ui-panel') + .css('transition', (instant !== true ? '.2s' : '0s')) + setTimeout(() => { this.set(panel, { size: size }) }, 1) + // clean + setTimeout(() => { + query(this.box).find(':scope > div > .w2ui-panel').css('transition', '0s') + this.resize() + }, 300) + return true + } + show(panel, immediate) { + // event before + let edata = this.trigger('show', { target: panel, thisect: this.get(panel), immediate: immediate }) + if (edata.isCancelled === true) return + let p = this.get(panel) + if (p == null) return false + p.hidden = false + if (immediate === true) { + query(this.box).find('#layout_'+ this.name +'_panel_'+panel) + .css({ 'opacity': '1' }) + edata.finish() + this.resize() + } else { + // resize + query(this.box).addClass('animating') + query(this.box).find('#layout_'+ this.name +'_panel_'+panel) + .css({ 'opacity': '0' }) + query(this.box).find(':scope > div > .w2ui-panel') + .css('transition', '.2s') + setTimeout(() => { this.resize() }, 1) + // show + setTimeout(() => { + query(this.box).find('#layout_'+ this.name +'_panel_'+ panel).css({ 'opacity': '1' }) + }, 250) + // clean + setTimeout(() => { + query(this.box).find(':scope > div > .w2ui-panel') + .css('transition', '0s') + query(this.box).removeClass('animating') + edata.finish() + this.resize() + }, 300) + } + return true + } + hide(panel, immediate) { + // event before + let edata = this.trigger('hide', { target: panel, object: this.get(panel), immediate: immediate }) + if (edata.isCancelled === true) return + let p = this.get(panel) + if (p == null) return false + p.hidden = true + if (immediate === true) { + query(this.box).find('#layout_'+ this.name +'_panel_'+panel) + .css({ 'opacity': '0' }) + edata.finish() + this.resize() + } else { + // hide + query(this.box).addClass('animating') + query(this.box).find(':scope > div > .w2ui-panel') + .css('transition', '.2s') + query(this.box).find('#layout_'+ this.name +'_panel_'+panel) + .css({ 'opacity': '0' }) + setTimeout(() => { this.resize() }, 1) + // clean + setTimeout(() => { + query(this.box).find(':scope > div > .w2ui-panel') + .css('transition', '0s') + query(this.box).removeClass('animating') + edata.finish() + this.resize() + }, 300) + } + return true + } + toggle(panel, immediate) { + let p = this.get(panel) + if (p == null) return false + if (p.hidden) return this.show(panel, immediate); else return this.hide(panel, immediate) + } + set(panel, options) { + let ind = this.get(panel, true) + if (ind == null) return false + w2utils.extend(this.panels[ind], options) + // refresh only when content changed + if (options.html != null || options.resizable != null) { + this.refresh(panel) + } + // show/hide resizer + this.resize() // resize is needed when panel size is changed + return true + } + get(panel, returnIndex) { + for (let p = 0; p < this.panels.length; p++) { + if (this.panels[p].type == panel) { + if (returnIndex === true) return p; else return this.panels[p] + } + } + return null + } + el(panel) { + let el = query(this.box).find('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-content') + if (el.length != 1) return null + return el[0] + } + hideToolbar(panel) { + let pan = this.get(panel) + if (!pan) return + pan.show.toolbar = false + query(this.box).find('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-toolbar').hide() + this.resize() + } + showToolbar(panel) { + let pan = this.get(panel) + if (!pan) return + pan.show.toolbar = true + query(this.box).find('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-toolbar').show() + this.resize() + } + toggleToolbar(panel) { + let pan = this.get(panel) + if (!pan) return + if (pan.show.toolbar) this.hideToolbar(panel); else this.showToolbar(panel) + } + assignToolbar(panel, toolbar) { + if (typeof toolbar == 'string' && w2ui[toolbar] != null) toolbar = w2ui[toolbar] + let pan = this.get(panel) + pan.toolbar = toolbar + let tmp = query(this.box).find(panel +'> .w2ui-panel-toolbar') + if (pan.toolbar != null) { + if (tmp.find('[name='+ pan.toolbar.name +']').length === 0) { + pan.toolbar.render(tmp.get(0)) + } else if (pan.toolbar != null) { + pan.toolbar.refresh() + } + toolbar.owner = this + this.showToolbar(panel) + this.refresh(panel) + } else { + tmp.html('') + this.hideToolbar(panel) + } + } + hideTabs(panel) { + let pan = this.get(panel) + if (!pan) return + pan.show.tabs = false + query(this.box).find('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-tabs').hide() + this.resize() + } + showTabs(panel) { + let pan = this.get(panel) + if (!pan) return + pan.show.tabs = true + query(this.box).find('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-tabs').show() + this.resize() + } + toggleTabs(panel) { + let pan = this.get(panel) + if (!pan) return + if (pan.show.tabs) this.hideTabs(panel); else this.showTabs(panel) + } + render(box) { + let time = Date.now() + let self = this + if (typeof box == 'string') box = query(box).get(0) + // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + // event before + let edata = this.trigger('render', { target: this.name, box: box ?? this.box }) + if (edata.isCancelled === true) return + // default action + if (box != null) { + // clean previous box + if (query(this.box).find('#layout_'+ this.name +'_panel_main').length > 0) { + query(this.box) + .removeAttr('name') + .removeClass('w2ui-layout') + .html('') + } + this.box = box + } + if (!this.box) return false + // render layout + query(this.box) + .attr('name', this.name) + .addClass('w2ui-layout') + .html('
    ') + if (query(this.box).length > 0) { + query(this.box)[0].style.cssText += this.style + } + // create all panels + for (let p1 = 0; p1 < w2panels.length; p1++) { + let html = '
    '+ + '
    '+ + '
    '+ + '
    '+ + '
    '+ + '
    '+ + '
    ' + query(this.box).find(':scope > div').append(html) + } + query(this.box).find(':scope > div') + .append('
    ') + this.refresh() // if refresh is not called here, the layout will not be available right after initialization + // observe div resize + this.last.observeResize = new ResizeObserver(() => { this.resize() }) + this.last.observeResize.observe(this.box) + // process event + edata.finish() + // re-init events + setTimeout(() => { // needed this timeout to allow browser to render first if there are tabs or toolbar + self.last.events = { resizeStart, mouseMove, mouseUp } + this.resize() + }, 0) + return Date.now() - time + function resizeStart(type, evnt) { + if (!self.box) return + if (!evnt) evnt = window.event + query(document) + .off('mousemove', self.last.events.mouseMove) + .on('mousemove', self.last.events.mouseMove) + query(document) + .off('mouseup', self.last.events.mouseUp) + .on('mouseup', self.last.events.mouseUp) + self.last.resize = { + type : type, + x : evnt.screenX, + y : evnt.screenY, + diff_x : 0, + diff_y : 0, + value : 0 + } + // lock all panels + w2panels.forEach(panel => { + let $tmp = query(self.el(panel)).find('.w2ui-lock') + if ($tmp.length > 0) { + $tmp.data('locked', 'yes') + } else { + self.lock(panel, { opacity: 0 }) + } + }) + let el = query(self.box).find('#layout_'+ self.name +'_resizer_'+ type).get(0) + if (type == 'left' || type == 'right') { + self.last.resize.value = parseInt(el.style.left) + } + if (type == 'top' || type == 'preview' || type == 'bottom') { + self.last.resize.value = parseInt(el.style.top) + } + } + function mouseUp(evnt) { + if (!self.box) return + if (!evnt) evnt = window.event + query(document).off('mousemove', self.last.events.mouseMove) + query(document).off('mouseup', self.last.events.mouseUp) + if (self.last.resize == null) return + // unlock all panels + w2panels.forEach(panel => { + let $tmp = query(self.el(panel)).find('.w2ui-lock') + if ($tmp.data('locked') == 'yes') { + $tmp.removeData('locked') + } else { + self.unlock(panel) + } + }) + // set new size + if (self.last.diff_x !== 0 || self.last.resize.diff_y !== 0) { // only recalculate if changed + let ptop = self.get('top') + let pbottom = self.get('bottom') + let panel = self.get(self.last.resize.type) + let width = w2utils.getSize(query(self.box), 'width') + let height = w2utils.getSize(query(self.box), 'height') + let str = String(panel.size) + let ns, nd + switch (self.last.resize.type) { + case 'top': + ns = parseInt(panel.sizeCalculated) + self.last.resize.diff_y + nd = 0 + break + case 'bottom': + ns = parseInt(panel.sizeCalculated) - self.last.resize.diff_y + nd = 0 + break + case 'preview': + ns = parseInt(panel.sizeCalculated) - self.last.resize.diff_y + nd = (ptop && !ptop.hidden ? ptop.sizeCalculated : 0) + + (pbottom && !pbottom.hidden ? pbottom.sizeCalculated : 0) + break + case 'left': + ns = parseInt(panel.sizeCalculated) + self.last.resize.diff_x + nd = 0 + break + case 'right': + ns = parseInt(panel.sizeCalculated) - self.last.resize.diff_x + nd = 0 + break + } + // set size + if (str.substr(str.length-1) == '%') { + panel.size = Math.floor(ns * 100 / (panel.type == 'left' || panel.type == 'right' ? width : height - nd) * 100) / 100 + '%' + } else { + if (String(panel.size).substr(0, 1) == '-') { + panel.size = parseInt(panel.size) - panel.sizeCalculated + ns + } else { + panel.size = ns + } + } + self.resize() + } + query(self.box) + .find('#layout_'+ self.name + '_resizer_'+ self.last.resize.type) + .removeClass('active') + delete self.last.resize + } + function mouseMove(evnt) { + if (!self.box) return + if (!evnt) evnt = window.event + if (self.last.resize == null) return + let panel = self.get(self.last.resize.type) + // event before + let tmp = self.last.resize + let edata = self.trigger('resizing', { target: self.name, object: panel, originalEvent: evnt, + panel: tmp ? tmp.type : 'all', diff_x: tmp ? tmp.diff_x : 0, diff_y: tmp ? tmp.diff_y : 0 }) + if (edata.isCancelled === true) return + let p = query(self.box).find('#layout_'+ self.name + '_resizer_'+ tmp.type) + let resize_x = (evnt.screenX - tmp.x) + let resize_y = (evnt.screenY - tmp.y) + let mainPanel = self.get('main') + if (!p.hasClass('active')) p.addClass('active') + switch (tmp.type) { + case 'left': + if (panel.minSize - resize_x > panel.width) { + resize_x = panel.minSize - panel.width + } + if (panel.maxSize && (panel.width + resize_x > panel.maxSize)) { + resize_x = panel.maxSize - panel.width + } + if (mainPanel.minSize + resize_x > mainPanel.width) { + resize_x = mainPanel.width - mainPanel.minSize + } + break + case 'right': + if (panel.minSize + resize_x > panel.width) { + resize_x = panel.width - panel.minSize + } + if (panel.maxSize && (panel.width - resize_x > panel.maxSize)) { + resize_x = panel.width - panel.maxSize + } + if (mainPanel.minSize - resize_x > mainPanel.width) { + resize_x = mainPanel.minSize - mainPanel.width + } + break + case 'top': + if (panel.minSize - resize_y > panel.height) { + resize_y = panel.minSize - panel.height + } + if (panel.maxSize && (panel.height + resize_y > panel.maxSize)) { + resize_y = panel.maxSize - panel.height + } + if (mainPanel.minSize + resize_y > mainPanel.height) { + resize_y = mainPanel.height - mainPanel.minSize + } + break + case 'preview': + case 'bottom': + if (panel.minSize + resize_y > panel.height) { + resize_y = panel.height - panel.minSize + } + if (panel.maxSize && (panel.height - resize_y > panel.maxSize)) { + resize_y = panel.height - panel.maxSize + } + if (mainPanel.minSize - resize_y > mainPanel.height) { + resize_y = mainPanel.minSize - mainPanel.height + } + break + } + tmp.diff_x = resize_x + tmp.diff_y = resize_y + switch (tmp.type) { + case 'top': + case 'preview': + case 'bottom': + tmp.diff_x = 0 + if (p.length > 0) p[0].style.top = (tmp.value + tmp.diff_y) + 'px' + break + case 'left': + case 'right': + tmp.diff_y = 0 + if (p.length > 0) p[0].style.left = (tmp.value + tmp.diff_x) + 'px' + break + } + // event after + edata.finish() + } + } + refresh(panel) { + let self = this + // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + if (panel == null) panel = null + let time = Date.now() + // event before + let edata = self.trigger('refresh', { target: (panel != null ? panel : self.name), object: self.get(panel) }) + if (edata.isCancelled === true) return + // self.unlock(panel); + if (typeof panel == 'string') { + let p = self.get(panel) + if (p == null) return + let pname = '#layout_'+ self.name + '_panel_'+ p.type + let rname = '#layout_'+ self.name +'_resizer_'+ p.type + // apply properties to the panel + query(self.box).find(pname).css({ display: p.hidden ? 'none' : 'block' }) + if (p.resizable) { + query(self.box).find(rname).show() + } else { + query(self.box).find(rname).hide() + } + // insert content + if (typeof p.html == 'object' && typeof p.html.render === 'function') { + p.html.box = query(self.box).find(pname +'> .w2ui-panel-content')[0] + setTimeout(() => { + // need to remove unnecessary classes + if (query(self.box).find(pname +'> .w2ui-panel-content').length > 0) { + query(self.box).find(pname +'> .w2ui-panel-content') + .removeClass() + .removeAttr('name') + .addClass('w2ui-panel-content') + .css('overflow', p.overflow)[0].style.cssText += ';' + p.style + } + if (p.html && typeof p.html.render == 'function') { + p.html.render() // do not do .render(box); + } + }, 1) + } else { + // need to remove unnecessary classes + if (query(self.box).find(pname +'> .w2ui-panel-content').length > 0) { + query(self.box).find(pname +'> .w2ui-panel-content') + .removeClass() + .removeAttr('name') + .addClass('w2ui-panel-content') + .html(p.html) + .css('overflow', p.overflow)[0].style.cssText += ';' + p.style + } + } + // if there are tabs and/or toolbar - render it + let tmp = query(self.box).find(pname +'> .w2ui-panel-tabs') + if (p.show.tabs) { + if (tmp.find('[name='+ p.tabs.name +']').length === 0 && p.tabs != null) { + p.tabs.render(tmp.get(0)) + } else { + p.tabs.refresh() + } + } else { + tmp.html('').removeClass('w2ui-tabs').hide() + } + tmp = query(self.box).find(pname +'> .w2ui-panel-toolbar') + if (p.show.toolbar) { + if (tmp.find('[name='+ p.toolbar.name +']').length === 0 && p.toolbar != null) { + p.toolbar.render(tmp.get(0)) + } else { + p.toolbar.refresh() + } + } else { + tmp.html('').removeClass('w2ui-toolbar').hide() + } + // show title + tmp = query(self.box).find(pname +'> .w2ui-panel-title') + if (p.title) { + tmp.html(p.title).show() + } else { + tmp.html('').hide() + } + } else { + if (query(self.box).find('#layout_'+ self.name +'_panel_main').length === 0) { + self.render() + return + } + self.resize() + // refresh all of them + for (let p1 = 0; p1 < this.panels.length; p1++) { self.refresh(this.panels[p1].type) } + } + edata.finish() + return Date.now() - time + } + resize() { + // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + if (!this.box) return false + let time = Date.now() + // event before + let tmp = this.last.resize + let edata = this.trigger('resize', { target: this.name, + panel: tmp ? tmp.type : 'all', diff_x: tmp ? tmp.diff_x : 0, diff_y: tmp ? tmp.diff_y : 0 }) + if (edata.isCancelled === true) return + if (this.padding < 0) this.padding = 0 + // layout itself + // width includes border and padding, we need to exclude that so panels + // are sized correctly + let width = w2utils.getSize(query(this.box), 'width') + let height = w2utils.getSize(query(this.box), 'height') + let self = this + // panels + let pmain = this.get('main') + let pprev = this.get('preview') + let pleft = this.get('left') + let pright = this.get('right') + let ptop = this.get('top') + let pbottom = this.get('bottom') + let sprev = (pprev != null && pprev.hidden !== true ? true : false) + let sleft = (pleft != null && pleft.hidden !== true ? true : false) + let sright = (pright != null && pright.hidden !== true ? true : false) + let stop = (ptop != null && ptop.hidden !== true ? true : false) + let sbottom = (pbottom != null && pbottom.hidden !== true ? true : false) + let l, t, w, h + // calculate % + for (let p = 0; p < w2panels.length; p++) { + if (w2panels[p] === 'main') continue + tmp = this.get(w2panels[p]) + if (!tmp) continue + let str = String(tmp.size || 0) + if (str.substr(str.length-1) == '%') { + let tmph = height + if (tmp.type == 'preview') { + tmph = tmph - + (ptop && !ptop.hidden ? ptop.sizeCalculated : 0) - + (pbottom && !pbottom.hidden ? pbottom.sizeCalculated : 0) + } + tmp.sizeCalculated = parseInt((tmp.type == 'left' || tmp.type == 'right' ? width : tmph) * parseFloat(tmp.size) / 100) + } else { + tmp.sizeCalculated = parseInt(tmp.size) + } + tmp.sizeCalculated = Math.max(tmp.sizeCalculated, parseInt(tmp.minSize)) + } + // negative size + if (String(pright.size).substr(0, 1) == '-') { + if (sleft && String(pleft.size).substr(0, 1) == '-') { + console.log('ERROR: you cannot have both left panel.size and right panel.size be negative.') + } else { + pright.sizeCalculated = width - (sleft ? pleft.sizeCalculated : 0) + parseInt(pright.size) + } + } + if (String(pleft.size).substr(0, 1) == '-') { + if (sright && String(pright.size).substr(0, 1) == '-') { + console.log('ERROR: you cannot have both left panel.size and right panel.size be negative.') + } else { + pleft.sizeCalculated = width - (sright ? pright.sizeCalculated : 0) + parseInt(pleft.size) + } + } + // top if any + if (ptop != null && ptop.hidden !== true) { + l = 0 + t = 0 + w = width + h = ptop.sizeCalculated + query(this.box).find('#layout_'+ this.name +'_panel_top') + .css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px' + }) + ptop.width = w + ptop.height = h + // resizer + if (ptop.resizable) { + t = ptop.sizeCalculated - (this.padding === 0 ? this.resizer : 0) + h = (this.resizer > this.padding ? this.resizer : this.padding) + query(this.box).find('#layout_'+ this.name +'_resizer_top') + .css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px', + 'cursor': 'ns-resize' + }) + .off('mousedown') + .on('mousedown', function(event) { + event.preventDefault() + // event before + let edata = self.trigger('resizerClick', { target: 'top', originalEvent: event }) + if (edata.isCancelled === true) return + // default action + w2ui[self.name].last.events.resizeStart('top', event) + // event after + edata.finish() + return false + }) + } + } else { + query(this.box).find('#layout_'+ this.name +'_panel_top').hide() + query(this.box).find('#layout_'+ this.name +'_resizer_top').hide() + } + // left if any + if (pleft != null && pleft.hidden !== true) { + l = 0 + t = 0 + (stop ? ptop.sizeCalculated + this.padding : 0) + w = pleft.sizeCalculated + h = height - (stop ? ptop.sizeCalculated + this.padding : 0) - + (sbottom ? pbottom.sizeCalculated + this.padding : 0) + query(this.box).find('#layout_'+ this.name +'_panel_left') + .css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px' + }) + pleft.width = w + pleft.height = h + // resizer + if (pleft.resizable) { + l = pleft.sizeCalculated - (this.padding === 0 ? this.resizer : 0) + w = (this.resizer > this.padding ? this.resizer : this.padding) + query(this.box).find('#layout_'+ this.name +'_resizer_left') + .css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px', + 'cursor': 'ew-resize' + }) + .off('mousedown') + .on('mousedown', function(event) { + event.preventDefault() + // event before + let edata = self.trigger('resizerClick', { target: 'left', originalEvent: event }) + if (edata.isCancelled === true) return + // default action + w2ui[self.name].last.events.resizeStart('left', event) + // event after + edata.finish() + return false + }) + } + } else { + query(this.box).find('#layout_'+ this.name +'_panel_left').hide() + query(this.box).find('#layout_'+ this.name +'_resizer_left').hide() + } + // right if any + if (pright != null && pright.hidden !== true) { + l = width - pright.sizeCalculated + t = 0 + (stop ? ptop.sizeCalculated + this.padding : 0) + w = pright.sizeCalculated + h = height - (stop ? ptop.sizeCalculated + this.padding : 0) - + (sbottom ? pbottom.sizeCalculated + this.padding : 0) + query(this.box).find('#layout_'+ this.name +'_panel_right') + .css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px' + }) + pright.width = w + pright.height = h + // resizer + if (pright.resizable) { + l = l - this.padding + w = (this.resizer > this.padding ? this.resizer : this.padding) + query(this.box).find('#layout_'+ this.name +'_resizer_right') + .css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px', + 'cursor': 'ew-resize' + }) + .off('mousedown') + .on('mousedown', function(event) { + event.preventDefault() + // event before + let edata = self.trigger('resizerClick', { target: 'right', originalEvent: event }) + if (edata.isCancelled === true) return + // default action + w2ui[self.name].last.events.resizeStart('right', event) + // event after + edata.finish() + return false + }) + } + } else { + query(this.box).find('#layout_'+ this.name +'_panel_right').hide() + query(this.box).find('#layout_'+ this.name +'_resizer_right').hide() + } + // bottom if any + if (pbottom != null && pbottom.hidden !== true) { + l = 0 + t = height - pbottom.sizeCalculated + w = width + h = pbottom.sizeCalculated + query(this.box).find('#layout_'+ this.name +'_panel_bottom') + .css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px' + }) + pbottom.width = w + pbottom.height = h + // resizer + if (pbottom.resizable) { + t = t - (this.padding === 0 ? 0 : this.padding) + h = (this.resizer > this.padding ? this.resizer : this.padding) + query(this.box).find('#layout_'+ this.name +'_resizer_bottom') + .css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px', + 'cursor': 'ns-resize' + }) + .off('mousedown') + .on('mousedown', function(event) { + event.preventDefault() + // event before + let edata = self.trigger('resizerClick', { target: 'bottom', originalEvent: event }) + if (edata.isCancelled === true) return + // default action + w2ui[self.name].last.events.resizeStart('bottom', event) + // event after + edata.finish() + return false + }) + } + } else { + query(this.box).find('#layout_'+ this.name +'_panel_bottom').hide() + query(this.box).find('#layout_'+ this.name +'_resizer_bottom').hide() + } + // main - always there + l = 0 + (sleft ? pleft.sizeCalculated + this.padding : 0) + t = 0 + (stop ? ptop.sizeCalculated + this.padding : 0) + w = width - (sleft ? pleft.sizeCalculated + this.padding : 0) - + (sright ? pright.sizeCalculated + this.padding: 0) + h = height - (stop ? ptop.sizeCalculated + this.padding : 0) - + (sbottom ? pbottom.sizeCalculated + this.padding : 0) - + (sprev ? pprev.sizeCalculated + this.padding : 0) + query(this.box) + .find('#layout_'+ this.name +'_panel_main') + .css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px' + }) + pmain.width = w + pmain.height = h + // preview if any + if (pprev != null && pprev.hidden !== true) { + l = 0 + (sleft ? pleft.sizeCalculated + this.padding : 0) + t = height - (sbottom ? pbottom.sizeCalculated + this.padding : 0) - pprev.sizeCalculated + w = width - (sleft ? pleft.sizeCalculated + this.padding : 0) - + (sright ? pright.sizeCalculated + this.padding : 0) + h = pprev.sizeCalculated + query(this.box).find('#layout_'+ this.name +'_panel_preview') + .css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px' + }) + pprev.width = w + pprev.height = h + // resizer + if (pprev.resizable) { + t = t - (this.padding === 0 ? 0 : this.padding) + h = (this.resizer > this.padding ? this.resizer : this.padding) + query(this.box).find('#layout_'+ this.name +'_resizer_preview') + .css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px', + 'cursor': 'ns-resize' + }) + .off('mousedown') + .on('mousedown', function(event) { + event.preventDefault() + // event before + let edata = self.trigger('resizerClick', { target: 'preview', originalEvent: event }) + if (edata.isCancelled === true) return + // default action + w2ui[self.name].last.events.resizeStart('preview', event) + // event after + edata.finish() + return false + }) + } + } else { + query(this.box).find('#layout_'+ this.name +'_panel_preview').hide() + query(this.box).find('#layout_'+ this.name +'_resizer_preview').hide() + } + // display tabs and toolbar if needed + for (let p1 = 0; p1 < w2panels.length; p1++) { + let pan = this.get(w2panels[p1]) + let tmp2 = '#layout_'+ this.name +'_panel_'+ w2panels[p1] +' > .w2ui-panel-' + let tabHeight = 0 + if (pan) { + if (pan.title) { + let el = query(this.box).find(tmp2 + 'title').css({ top: tabHeight + 'px', display: 'block' }) + tabHeight += w2utils.getSize(el, 'height') + } + if (pan.show.tabs) { + let el = query(this.box).find(tmp2 + 'tabs').css({ top: tabHeight + 'px', display: 'block' }) + tabHeight += w2utils.getSize(el, 'height') + } + if (pan.show.toolbar) { + let el = query(this.box).find(tmp2 + 'toolbar').css({ top: tabHeight + 'px', display: 'block' }) + tabHeight += w2utils.getSize(el, 'height') + } + } + query(this.box).find(tmp2 + 'content').css({ display: 'block' }).css({ top: tabHeight + 'px' }) + } + edata.finish() + return Date.now() - time + } + destroy() { + // event before + let edata = this.trigger('destroy', { target: this.name }) + if (edata.isCancelled === true) return + if (w2ui[this.name] == null) return false + // clean up + if (query(this.box).find('#layout_'+ this.name +'_panel_main').length > 0) { + query(this.box) + .removeAttr('name') + .removeClass('w2ui-layout') + .html('') + } + this.last.observeResize?.disconnect() + delete w2ui[this.name] + // event after + edata.finish() + if (this.last.events && this.last.events.resize) { + query(window).off('resize', this.last.events.resize) + } + return true + } + lock(panel, msg, showSpinner) { + if (w2panels.indexOf(panel) == -1) { + console.log('ERROR: First parameter needs to be the a valid panel name.') + return + } + let args = Array.from(arguments) + args[0] = '#layout_'+ this.name + '_panel_' + panel + w2utils.lock(...args) + } + unlock(panel, speed) { + if (w2panels.indexOf(panel) == -1) { + console.log('ERROR: First parameter needs to be the a valid panel name.') + return + } + let nm = '#layout_'+ this.name + '_panel_' + panel + w2utils.unlock(nm, speed) + } +} +/** + * Part of w2ui 2.0 library + * - Dependencies: jQuery, w2utils, w2base, w2toolbar, w2field + * + * == TODO == + * - problem with .set() and arrays, array get extended too, but should be replaced + * - allow functions in routeData (also add routeData to list/enum) + * - send parsed URL to the event if there is routeData + * - add selectType: 'none' so that no selection can be make but with mouse + * - focus/blur for selectType = cell not display grayed out selection + * - allow enum in inline edit (see https://github.com/vitmalina/w2ui/issues/911#issuecomment-107341193) + * - remote source, but localSort/localSearch + * - promise for request, load, save, etc. + * - onloadmore event (so it will be easy to implement remote data source with local sort) + * - status() - clears on next select, etc. Should not if it is off + * + * == DEMOS To create == + * - batch for disabled buttons + * - natural sort + * - resize on max content + * + * == 2.0 changes + * - toolbarInput - deprecated, toolbarSearch stays + * - searchSuggest + * - searchSave, searchSelected, savedSearches, defaultSearches, useLocalStorage, searchFieldTooltip + * - cache, cacheSave + * - onSearchSave, onSearchRemove, onSearchSelect + * - show.searchLogic + * - show.searchSave + * - refreshSearch + * - initAllFields -> searchInitInput + * - textSearch - deprecated in favor of defaultOperator + * - grid.confirm - refactored + * - grid.message - refactored + * - search.type == 'text' can have 'in' and 'not in' operators, then it will switch to enum + * - grid.find(..., displayedOnly) + * - column.render(..., this) - added + * - observeResize for the box + * - remove edit.type == 'select' + * - editDone(...) + * - liveSearch + * - deprecated onUnselect event + * - requestComplete(data, action, callBack, resolve, reject) - new argument list + * - msgAJAXError -> msgHTTPError + * - aded msgServerError + * - deleted grid.method + * - added mouseEnter/mouseLeave + * - grid.show.columnReorder -> grid.reorderRows + * - updagte docs search.label (not search.text) + */ + +class w2grid extends w2base { + constructor(options) { + super(options.name) + this.name = null + this.box = null // HTML element that hold this element + this.columns = [] // { field, text, size, attr, render, hidden, gridMinWidth, editable } + this.columnGroups = [] // { span: int, text: 'string', main: true/false, style: 'string' } + this.records = [] // { recid: int(required), field1: 'value1', ... fieldN: 'valueN', style: 'string', changes: object } + this.summary = [] // array of summary records, same structure as records array + this.searches = [] // { type, label, field, attr, text, hidden } + this.toolbar = {} // if not empty object; then it is toolbar object + this.ranges = [] + this.contextMenu = [] + this.searchMap = {} // re-map search fields + this.searchData = [] + this.sortMap = {} // re-map sort fields + this.sortData = [] + this.savedSearches = [] + this.defaultSearches = [] + this.total = 0 // server total + this.recid = null // field from records to be used as recid + // internal + this.last = { + field : '', // last search field, e.g. 'all' + label : '', // last search field label, e.g. 'All Fields' + logic : 'AND', // last search logic, e.g. 'AND' or 'OR' + search : '', // last search text + searchIds : [], // last search IDs + selection : { // last selection details + indexes : [], + columns : {} + }, + saved_sel : null, // last result of selectionSave() + multi : false, // last multi flag, true when searching for multiple fields + scrollTop : 0, // last scrollTop position + scrollLeft : 0, // last scrollLeft position + colStart : 0, // for column virtual scrolling + colEnd : 0, // for column virtual scrolling + fetch: { + action : '', // last fetch command, e.g. 'load' + offset : null, // last fetch offset, integer + start : 0, // timestamp of start of last fetch request + response : 0, // time it took to complete the last fetch request in seconds + options : null, + controller: null, + loaded : false, // data is loaded from the server + hasMore : false // flag to indicate if there are more items to pull from the server + }, + pull_more : false, + pull_refresh : true, + range_start : null, // last range start cell + range_end : null, // last range end cell + sel_ind : null, // last selected cell index + sel_col : null, // last selected column + sel_type : null, // last selection type, e.g. 'click' or 'key' + sel_recid : null, // last selected record id + idCache : {}, // object, id cache for get() + move : null, // object, move details + cancelClick : null, // boolean flag to indicate if the click event should be ignored, set during mouseMove() + inEditMode : false, // flag to indicate if we're currently in edit mode during inline editing + _edit : null, // object with details on the last edited cell, { value, index, column, recid } + kbd_timer : null, // last id of blur() timer + marker_timer : null, // last id of markSearch() timer + click_time : null, // timestamp of last click + click_recid : null, // last clicked record id + bubbleEl : null, // last bubble element + colResizing : false, // flag to indicate that a column is currently being resized + tmp : null, // object with last column resizing details + copy_event : null, // last copy event + userSelect : '', // last user select type, e.g. 'text' + columnDrag : false, // false or an object with a remove() method + state : null, // last grid state + show_extra : 0, // last show extra for virtual scrolling + toolbar_height: 0, // height of grid's toolbar + } + this.header = '' + this.url = '' + this.limit = 100 + this.offset = 0 // how many records to skip (for infinite scroll) when pulling from server + this.postData = {} + this.routeData = {} + this.httpHeaders = {} + this.show = { + header : false, + toolbar : false, + footer : false, + columnMenu : true, + columnHeaders : true, + lineNumbers : false, + expandColumn : false, + selectColumn : false, + emptyRecords : true, + toolbarReload : true, + toolbarColumns : false, + toolbarSearch : true, + toolbarAdd : false, + toolbarEdit : false, + toolbarDelete : false, + toolbarSave : false, + searchAll : true, + searchLogic : true, + searchHiddenMsg : false, + searchSave : true, + statusRange : true, + statusBuffered : false, + statusRecordID : true, + statusSelection : true, + statusResponse : true, + statusSort : false, + statusSearch : false, + recordTitles : false, + selectionBorder : true, + skipRecords : true, + saveRestoreState: true + } + this.stateId = null // Custom state name for stateSave, stateRestore and stateReset + this.hasFocus = false + this.autoLoad = true // for infinite scroll + this.fixedBody = true // if false; then grid grows with data + this.recordHeight = 32 + this.lineNumberWidth = 34 + this.keyboard = true + this.selectType = 'row' // can be row|cell + this.liveSearch = false // if true, it will auto search if typed in search_all + this.multiSearch = true + this.multiSelect = true + this.multiSort = true + this.reorderColumns = false + this.reorderRows = false + this.showExtraOnSearch = 0 // show extra records before and after on search + this.markSearch = true + this.columnTooltip = 'top|bottom' // can be top, bottom, left, right + this.disableCVS = false // disable Column Virtual Scroll + this.nestedFields = true // use field name containing dots as separator to look into object + this.vs_start = 150 + this.vs_extra = 5 + this.style = '' + this.tabIndex = null + this.dataType = null // if defined, then overwrites w2utils.settings.dataType + this.parser = null + this.advanceOnEdit = true // automatically begin editing the next cell after submitting an inline edit? + this.useLocalStorage = true + // default values for the column + this.colTemplate = { + text : '', // column text (can be a function) + field : '', // field name to map the column to a record + size : null, // size of column in px or % + min : 20, // minimum width of column in px + max : null, // maximum width of column in px + gridMinWidth : null, // minimum width of the grid when column is visible + sizeCorrected : null, // read only, corrected size (see explanation below) + sizeCalculated : null, // read only, size in px (see explanation below) + sizeOriginal : null, // size as defined + sizeType : null, // px or % + hidden : false, // indicates if column is hidden + sortable : false, // indicates if column is sortable + sortMode : null, // sort mode ('default'|'natural'|'i18n') or custom compare function + searchable : false, // bool/string: int,float,date,... or an object to create search field + resizable : true, // indicates if column is resizable + hideable : true, // indicates if column can be hidden + autoResize : null, // indicates if column can be auto-resized by double clicking on the resizer + attr : '', // string that will be inside the tag + style : '', // additional style for the td tag + render : null, // string or render function + title : null, // string or function for the title property for the column cells + tooltip : null, // string for the title property for the column header + editable : {}, // editable object (see explanation below) + frozen : false, // indicates if the column is fixed to the left + info : null, // info bubble, can be bool/object + clipboardCopy : false, // if true (or string or function), it will display clipboard copy icon + } + // these column properties will be saved in stateSave() + this.stateColProps = { + text : false, + field : true, + size : true, + min : false, + max : false, + gridMinWidth : false, + sizeCorrected : false, + sizeCalculated : true, + sizeOriginal : true, + sizeType : true, + hidden : true, + sortable : false, + sortMode : true, + searchable : false, + resizable : false, + hideable : false, + autoResize : false, + attr : false, + style : false, + render : false, + title : false, + tooltip : false, + editable : false, + frozen : true, + info : false, + clipboardCopy : false + } + this.msgDelete = 'Are you sure you want to delete ${count} ${records}?' + this.msgNotJSON = 'Returned data is not in valid JSON format.' + this.msgHTTPError = 'HTTP error. See console for more details.' + this.msgServerError= 'Server error' + this.msgRefresh = 'Refreshing...' + this.msgNeedReload = 'Your remote data source record count has changed, reloading from the first record.' + this.msgEmpty = '' // if not blank, then it is message when server returns no records + this.buttons = { + 'reload' : { type: 'button', id: 'w2ui-reload', icon: 'w2ui-icon-reload', tooltip: 'Reload data in the list' }, + 'columns' : { type: 'menu-check', id: 'w2ui-column-on-off', icon: 'w2ui-icon-columns', tooltip: 'Show/hide columns', + overlay: { align: 'none' } + }, + 'search' : { type: 'html', id: 'w2ui-search', + html: '' + }, + 'add' : { type: 'button', id: 'w2ui-add', text: 'Add New', tooltip: 'Add new record', icon: 'w2ui-icon-plus' }, + 'edit' : { type: 'button', id: 'w2ui-edit', text: 'Edit', tooltip: 'Edit selected record', icon: 'w2ui-icon-pencil', batch: 1, disabled: true }, + 'delete' : { type: 'button', id: 'w2ui-delete', text: 'Delete', tooltip: 'Delete selected records', icon: 'w2ui-icon-cross', batch: true, disabled: true }, + 'save' : { type: 'button', id: 'w2ui-save', text: 'Save', tooltip: 'Save changed records', icon: 'w2ui-icon-check' } + } + this.operators = { // for search fields + 'text' : ['is', 'begins', 'contains', 'ends'], // could have "in" and "not in" + 'number' : ['=', 'between', '>', '<', '>=', '<='], + 'date' : ['is', { oper: 'less', text: 'before'}, { oper: 'more', text: 'since' }, 'between'], + 'list' : ['is'], + 'hex' : ['is', 'between'], + 'color' : ['is', 'begins', 'contains', 'ends'], + 'enum' : ['in', 'not in'] + // -- all possible + // "text" : ['is', 'begins', 'contains', 'ends'], + // "number" : ['is', 'between', 'less:less than', 'more:more than', 'null:is null', 'not null:is not null'], + // "list" : ['is', 'null:is null', 'not null:is not null'], + // "enum" : ['in', 'not in', 'null:is null', 'not null:is not null'] + } + this.defaultOperator = { + 'text' : 'begins', + 'number' : '=', + 'date' : 'is', + 'list' : 'is', + 'enum' : 'in', + 'hex' : 'begins', + 'color' : 'begins' + } + // map search field type to operator + this.operatorsMap = { + 'text' : 'text', + 'int' : 'number', + 'float' : 'number', + 'money' : 'number', + 'currency' : 'number', + 'percent' : 'number', + 'hex' : 'hex', + 'alphanumeric' : 'text', + 'color' : 'color', + 'date' : 'date', + 'time' : 'date', + 'datetime' : 'date', + 'list' : 'list', + 'combo' : 'text', + 'enum' : 'enum', + 'file' : 'enum', + 'select' : 'list', + 'radio' : 'list', + 'checkbox' : 'list', + 'toggle' : 'list' + } + // events + this.onAdd = null + this.onEdit = null + this.onRequest = null // called on any server event + this.onLoad = null + this.onDelete = null + this.onSave = null + this.onSelect = null + this.onClick = null + this.onDblClick = null + this.onContextMenu = null + this.onContextMenuClick = null // when context menu item selected + this.onColumnClick = null + this.onColumnDblClick = null + this.onColumnContextMenu = null + this.onColumnResize = null + this.onColumnAutoResize = null + this.onSort = null + this.onSearch = null + this.onSearchOpen = null + this.onChange = null // called when editable record is changed + this.onRestore = null // called when editable record is restored + this.onExpand = null + this.onCollapse = null + this.onError = null + this.onKeydown = null + this.onToolbar = null // all events from toolbar + this.onColumnOnOff = null + this.onCopy = null + this.onPaste = null + this.onSelectionExtend = null + this.onEditField = null + this.onRender = null + this.onRefresh = null + this.onReload = null + this.onResize = null + this.onDestroy = null + this.onStateSave = null + this.onStateRestore = null + this.onFocus = null + this.onBlur = null + this.onReorderRow = null + this.onSearchSave = null + this.onSearchRemove = null + this.onSearchSelect = null + this.onColumnSelect = null + this.onColumnDragStart = null + this.onColumnDragEnd = null + this.onResizerDblClick = null + this.onMouseEnter = null // mouse enter over record event + this.onMouseLeave = null + // need deep merge, should be extend, not objectAssign + w2utils.extend(this, options) + // check if there are records without recid + if (Array.isArray(this.records)) { + let remove = [] // remove from records as they are summary + this.records.forEach((rec, ind) => { + if (rec[this.recid] != null) { + rec.recid = rec[this.recid] + } + if (rec.recid == null) { + console.log('ERROR: Cannot add records without recid. (obj: '+ this.name +')') + } + if (rec.w2ui?.summary === true) { + this.summary.push(rec) + remove.push(ind) // cannot remove here as it will mess up array walk thru + } + }) + remove.sort() + for (let t = remove.length-1; t >= 0; t--) { + this.records.splice(remove[t], 1) + } + } + // add searches + if (Array.isArray(this.columns)) { + this.columns.forEach((col, ind) => { + col = w2utils.extend({}, this.colTemplate, col) + this.columns[ind] = col + let search = col.searchable + if (search == null || search === false || this.getSearch(col.field) != null) return + if (w2utils.isPlainObject(search)) { + this.addSearch(w2utils.extend({ field: col.field, label: col.text, type: 'text' }, search)) + } else { + let stype = col.searchable + let attr = '' + if (col.searchable === true) { + stype = 'text' + attr = 'size="20"' + } + this.addSearch({ field: col.field, label: col.text, type: stype, attr: attr }) + } + }) + } + // add icon to default searches if not defined + if (Array.isArray(this.defaultSearches)) { + this.defaultSearches.forEach((search, ind) => { + search.id = 'default-'+ ind + search.icon ??= 'w2ui-icon-search' + }) + } + // check if there are saved searches in localStorage + let data = this.cache('searches') + if (Array.isArray(data)) { + data.forEach(search => { + this.savedSearches.push({ + id: search.id ?? 'none', + text: search.text ?? 'none', + icon: 'w2ui-icon-search', + remove: true, + logic: search.logic ?? 'AND', + data: search.data ?? [] + }) + }) + } + // render if box specified + if (typeof this.box == 'string') this.box = query(this.box).get(0) + if (this.box) this.render(this.box) + } + add(record, first) { + if (!Array.isArray(record)) record = [record] + let added = 0 + for (let i = 0; i < record.length; i++) { + let rec = record[i] + if (rec[this.recid] != null) { + rec.recid = rec[this.recid] + } + if (rec.recid == null) { + console.log('ERROR: Cannot add record without recid. (obj: '+ this.name +')') + continue + } + if (rec.w2ui?.summary === true) { + if (first) this.summary.unshift(rec); else this.summary.push(rec) + } else { + if (first) this.records.unshift(rec); else this.records.push(rec) + } + added++ + } + let url = this.url?.get ?? this.url + if (!url) { + this.total = this.records.length + this.localSort(false, true) + this.localSearch() + // do not call this.refresh(), this is unnecessary, heavy, and messes with the toolbar. + // this.refreshBody() + // this.resizeRecords() + this.refresh() + } else { + this.refresh() // ?? should it be reload? + } + return added + } + find(obj, returnIndex, displayedOnly) { + if (obj == null) obj = {} + let recs = [] + let hasDots = false + // check if property is nested - needed for speed + for (let o in obj) if (String(o).indexOf('.') != -1) hasDots = true + // look for an item + let start = displayedOnly ? this.last.range_start : 0 + let end = displayedOnly ? this.last.range_end + 1: this.records.length + if (end > this.records.length) end = this.records.length + for (let i = start; i < end; i++) { + let match = true + for (let o in obj) { + let val = this.records[i][o] + if (hasDots && String(o).indexOf('.') != -1) val = this.parseField(this.records[i], o) + if (obj[o] == 'not-null') { + if (val == null || val === '') match = false + } else { + if (obj[o] != val) match = false + } + } + if (match && returnIndex !== true) recs.push(this.records[i].recid) + if (match && returnIndex === true) recs.push(i) + } + return recs + } + set(recid, record, noRefresh) { // does not delete existing, but overrides on top of it + if ((typeof recid == 'object') && (recid !== null)) { + noRefresh = record + record = recid + recid = null + } + // update all records + if (recid == null) { + for (let i = 0; i < this.records.length; i++) { + w2utils.extend(this.records[i], record) // recid is the whole record + } + if (noRefresh !== true) this.refresh() + } else { // find record to update + let ind = this.get(recid, true) + if (ind == null) return false + let isSummary = (this.records[ind] && this.records[ind].recid == recid ? false : true) + if (isSummary) { + w2utils.extend(this.summary[ind], record) + } else { + w2utils.extend(this.records[ind], record) + } + if (noRefresh !== true) this.refreshRow(recid, ind) // refresh only that record + } + return true + } + get(recid, returnIndex) { + // search records + if (Array.isArray(recid)) { + let recs = [] + for (let i = 0; i < recid.length; i++) { + let v = this.get(recid[i], returnIndex) + if (v !== null) + recs.push(v) + } + return recs + } else { + // get() must be fast, implements a cache to bypass loop over all records + // most of the time. + let idCache = this.last.idCache + if (!idCache) { + this.last.idCache = idCache = {} + } + let i = idCache[recid] + if (typeof(i) === 'number') { + if (i >= 0 && i < this.records.length && this.records[i].recid == recid) { + if (returnIndex === true) return i; else return this.records[i] + } + // summary indexes are stored as negative numbers, try them now. + i = ~i + if (i >= 0 && i < this.summary.length && this.summary[i].recid == recid) { + if (returnIndex === true) return i; else return this.summary[i] + } + // wrong index returned, clear cache + this.last.idCache = idCache = {} + } + for (let i = 0; i < this.records.length; i++) { + if (this.records[i].recid == recid) { + idCache[recid] = i + if (returnIndex === true) return i; else return this.records[i] + } + } + // search summary + for (let i = 0; i < this.summary.length; i++) { + if (this.summary[i].recid == recid) { + idCache[recid] = ~i + if (returnIndex === true) return i; else return this.summary[i] + } + } + return null + } + } + getFirst(offset) { + if (this.records.length == 0) return null + let rec = this.records[0] + let tmp = this.last.searchIds + if (this.searchData.length > 0) { + if (Array.isArray(tmp) && tmp.length > 0) { + rec = this.records[tmp[offset || 0]] + } else { + rec = null + } + } + return rec + } + remove() { + let removed = 0 + for (let a = 0; a < arguments.length; a++) { + for (let r = this.records.length-1; r >= 0; r--) { + if (this.records[r].recid == arguments[a]) { this.records.splice(r, 1); removed++ } + } + for (let r = this.summary.length-1; r >= 0; r--) { + if (this.summary[r].recid == arguments[a]) { this.summary.splice(r, 1); removed++ } + } + } + let url = this.url?.get ?? this.url + if (!url) { + this.localSort(false, true) + this.localSearch() + } + this.refresh() + return removed + } + addColumn(before, columns) { + let added = 0 + if (arguments.length == 1) { + columns = before + before = this.columns.length + } else { + if (typeof before == 'string') before = this.getColumn(before, true) + if (before == null) before = this.columns.length + } + if (!Array.isArray(columns)) columns = [columns] + for (let i = 0; i < columns.length; i++) { + let col = w2utils.extend({}, this.colTemplate, columns[i]) + this.columns.splice(before, 0, col) + // if column is searchable, add search field + if (columns[i].searchable) { + let stype = columns[i].searchable + let attr = '' + if (columns[i].searchable === true) { stype = 'text'; attr = 'size="20"' } + this.addSearch({ field: columns[i].field, label: columns[i].text, type: stype, attr: attr }) + } + before++ + added++ + } + this.refresh() + return added + } + removeColumn() { + let removed = 0 + for (let a = 0; a < arguments.length; a++) { + for (let r = this.columns.length-1; r >= 0; r--) { + if (this.columns[r].field == arguments[a]) { + if (this.columns[r].searchable) this.removeSearch(arguments[a]) + this.columns.splice(r, 1) + removed++ + } + } + } + this.refresh() + return removed + } + getColumn(field, returnIndex) { + // no arguments - return fields of all columns + if (arguments.length === 0) { + let ret = [] + for (let i = 0; i < this.columns.length; i++) ret.push(this.columns[i].field) + return ret + } + // find column + for (let i = 0; i < this.columns.length; i++) { + if (this.columns[i].field == field) { + if (returnIndex === true) return i; else return this.columns[i] + } + } + return null + } + updateColumn(fields, updates) { + let effected = 0 + fields = (Array.isArray(fields) ? fields : [fields]) + fields.forEach((colName) => { + this.columns.forEach((col) => { + if (col.field == colName) { + let _updates = w2utils.clone(updates) + Object.keys(_updates).forEach((key) => { + // if it is a function + if (typeof _updates[key] == 'function') { + _updates[key] = _updates[key](col) + } + if (col[key] != _updates[key]) effected++ + }) + w2utils.extend(col, _updates) + } + }) + }) + if (effected > 0) { + this.refresh() // need full refresh due to colgroups not reassigning properly + } + return effected + } + toggleColumn() { + return this.updateColumn(Array.from(arguments), { hidden(col) { return !col.hidden } }) + } + showColumn() { + return this.updateColumn(Array.from(arguments), { hidden: false }) + } + hideColumn() { + return this.updateColumn(Array.from(arguments), { hidden: true }) + } + addSearch(before, search) { + let added = 0 + if (arguments.length == 1) { + search = before + before = this.searches.length + } else { + if (typeof before == 'string') before = this.getSearch(before, true) + if (before == null) before = this.searches.length + } + if (!Array.isArray(search)) search = [search] + for (let i = 0; i < search.length; i++) { + this.searches.splice(before, 0, search[i]) + before++ + added++ + } + this.searchClose() + return added + } + removeSearch() { + let removed = 0 + for (let a = 0; a < arguments.length; a++) { + for (let r = this.searches.length-1; r >= 0; r--) { + if (this.searches[r].field == arguments[a]) { this.searches.splice(r, 1); removed++ } + } + } + this.searchClose() + return removed + } + getSearch(field, returnIndex) { + // no arguments - return fields of all searches + if (arguments.length === 0) { + let ret = [] + for (let i = 0; i < this.searches.length; i++) ret.push(this.searches[i].field) + return ret + } + // find search + for (let i = 0; i < this.searches.length; i++) { + if (this.searches[i].field == field) { + if (returnIndex === true) return i; else return this.searches[i] + } + } + return null + } + toggleSearch() { + let effected = 0 + for (let a = 0; a < arguments.length; a++) { + for (let r = this.searches.length-1; r >= 0; r--) { + if (this.searches[r].field == arguments[a]) { + this.searches[r].hidden = !this.searches[r].hidden + effected++ + } + } + } + this.searchClose() + return effected + } + showSearch() { + let shown = 0 + for (let a = 0; a < arguments.length; a++) { + for (let r = this.searches.length-1; r >= 0; r--) { + if (this.searches[r].field == arguments[a] && this.searches[r].hidden !== false) { + this.searches[r].hidden = false + shown++ + } + } + } + this.searchClose() + return shown + } + hideSearch() { + let hidden = 0 + for (let a = 0; a < arguments.length; a++) { + for (let r = this.searches.length-1; r >= 0; r--) { + if (this.searches[r].field == arguments[a] && this.searches[r].hidden !== true) { + this.searches[r].hidden = true + hidden++ + } + } + } + this.searchClose() + return hidden + } + getSearchData(field) { + for (let i = 0; i < this.searchData.length; i++) { + if (this.searchData[i].field == field) return this.searchData[i] + } + return null + } + localSort(silent, noResetRefresh) { + let obj = this + let url = this.url?.get ?? this.url + if (url) { + console.log('ERROR: grid.localSort can only be used on local data source, grid.url should be empty.') + return + } + if (Object.keys(this.sortData).length === 0) return + let time = Date.now() + // process date fields + this.selectionSave() + this.prepareData() + if (!noResetRefresh) { + this.reset() + } + // process sortData + for (let i = 0; i < this.sortData.length; i++) { + let column = this.getColumn(this.sortData[i].field) + if (!column) return // TODO: ability to sort columns when they are not part of colums array + if (typeof column.render == 'string') { + if (['date', 'age'].indexOf(column.render.split(':')[0]) != -1) { + this.sortData[i].field_ = column.field + '_' + } + if (['time'].indexOf(column.render.split(':')[0]) != -1) { + this.sortData[i].field_ = column.field + '_' + } + } + } + // prepare paths and process sort + preparePaths() + this.records.sort((a, b) => { + return compareRecordPaths(a, b) + }) + cleanupPaths() + this.selectionRestore(noResetRefresh) + time = Date.now() - time + if (silent !== true && this.show.statusSort) { + setTimeout(() => { + this.status(w2utils.lang('Sorting took ${count} seconds', { count: time/1000 })) + }, 10) + } + return time + // grab paths before sorting for efficiency and because calling obj.get() + // while sorting 'obj.records' is unsafe, at least on webkit + function preparePaths() { + for (let i = 0; i < obj.records.length; i++) { + let rec = obj.records[i] + if (rec.w2ui?.parent_recid != null) { + rec.w2ui._path = getRecordPath(rec) + } + } + } + // cleanup and release memory allocated by preparePaths() + function cleanupPaths() { + for (let i = 0; i < obj.records.length; i++) { + let rec = obj.records[i] + if (rec.w2ui?.parent_recid != null) { + rec.w2ui._path = null + } + } + } + // compare two paths, from root of tree to given records + function compareRecordPaths(a, b) { + if ((!a.w2ui || a.w2ui.parent_recid == null) && (!b.w2ui || b.w2ui.parent_recid == null)) { + return compareRecords(a, b) // no tree, fast path + } + let pa = getRecordPath(a) + let pb = getRecordPath(b) + for (let i = 0; i < Math.min(pa.length, pb.length); i++) { + let diff = compareRecords(pa[i], pb[i]) + if (diff !== 0) return diff // different subpath + } + if (pa.length > pb.length) return 1 + if (pa.length < pb.length) return -1 + console.log('ERROR: two paths should not be equal.') + return 0 + } + // return an array of all records from root to and including 'rec' + function getRecordPath(rec) { + if (!rec.w2ui || rec.w2ui.parent_recid == null) return [rec] + if (rec.w2ui._path) + return rec.w2ui._path + // during actual sort, we should never reach this point + let subrec = obj.get(rec.w2ui.parent_recid) + if (!subrec) { + console.log('ERROR: no parent record: ' + rec.w2ui.parent_recid) + return [rec] + } + return (getRecordPath(subrec).concat(rec)) + } + // compare two records according to sortData and finally recid + function compareRecords(a, b) { + if (a === b) return 0 // optimize, same object + for (let i = 0; i < obj.sortData.length; i++) { + let fld = obj.sortData[i].field + let sortFld = (obj.sortData[i].field_) ? obj.sortData[i].field_ : fld + let aa = a[sortFld] + let bb = b[sortFld] + if (String(fld).indexOf('.') != -1) { + aa = obj.parseField(a, sortFld) + bb = obj.parseField(b, sortFld) + } + let col = obj.getColumn(fld) + if (col && Object.keys(col.editable).length > 0) { // for drop editable fields and drop downs + if (w2utils.isPlainObject(aa) && aa.text) aa = aa.text + if (w2utils.isPlainObject(bb) && bb.text) bb = bb.text + } + let ret = compareCells(aa, bb, i, obj.sortData[i].direction, col.sortMode || 'default') + if (ret !== 0) return ret + } + // break tie for similar records, + // required to have consistent ordering for tree paths + let ret = compareCells(a.recid, b.recid, -1, 'asc') + return ret + } + // compare two values, aa and bb, producing consistent ordering + function compareCells(aa, bb, i, direction, sortMode) { + // if both objects are strictly equal, we're done + if (aa === bb) + return 0 + // all nulls, empty and undefined on bottom + if ((aa == null || aa === '') && (bb != null && bb !== '')) + return 1 + if ((aa != null && aa !== '') && (bb == null || bb === '')) + return -1 + let dir = (direction.toLowerCase() === 'asc') ? 1 : -1 + // for different kind of objects, sort by object type + if (typeof aa != typeof bb) + return (typeof aa > typeof bb) ? dir : -dir + // for different kind of classes, sort by classes + if (aa.constructor.name != bb.constructor.name) + return (aa.constructor.name > bb.constructor.name) ? dir : -dir + // if we're dealing with non-null objects, call valueOf(). + // this mean that Date() or custom objects will compare properly. + if (aa && typeof aa == 'object') + aa = aa.valueOf() + if (bb && typeof bb == 'object') + bb = bb.valueOf() + // if we're still dealing with non-null objects that have + // a useful Object => String conversion, convert to string. + let defaultToString = {}.toString + if (aa && typeof aa == 'object' && aa.toString != defaultToString) + aa = String(aa) + if (bb && typeof bb == 'object' && bb.toString != defaultToString) + bb = String(bb) + // do case-insensitive string comparison + if (typeof aa == 'string') + aa = aa.toLowerCase().trim() + if (typeof bb == 'string') + bb = bb.toLowerCase().trim() + switch (sortMode) { + case 'natural': + sortMode = w2utils.naturalCompare + break + case 'i18n': + sortMode = w2utils.i18nCompare + break + } + if (typeof sortMode == 'function') { + return sortMode(aa,bb) * dir + } + // compare both objects + if (aa > bb) + return dir + if (aa < bb) + return -dir + return 0 + } + } + localSearch(silent) { + let obj = this + let url = this.url?.get ?? this.url + if (url) { + console.log('ERROR: grid.localSearch can only be used on local data source, grid.url should be empty.') + return + } + let time = Date.now() + let defaultToString = {}.toString + let duplicateMap = {} + this.total = this.records.length + // mark all records as shown + this.last.searchIds = [] + // prepare date/time fields + this.prepareData() + // hide records that did not match + if (this.searchData.length > 0 && !url) { + this.total = 0 + for (let i = 0; i < this.records.length; i++) { + let rec = this.records[i] + let match = searchRecord(rec) + if (match) { + if (rec?.w2ui) addParent(rec.w2ui.parent_recid) + if (this.showExtraOnSearch > 0) { + let before = this.showExtraOnSearch + let after = this.showExtraOnSearch + if (i < before) before = i + if (i + after > this.records.length) after = this.records.length - i + if (before > 0) { + for (let j = i - before; j < i; j++) { + if (this.last.searchIds.indexOf(j) < 0) + this.last.searchIds.push(j) + } + } + if (this.last.searchIds.indexOf(i) < 0) this.last.searchIds.push(i) + if (after > 0) { + for (let j = (i + 1) ; j <= (i + after) ; j++) { + if (this.last.searchIds.indexOf(j) < 0) this.last.searchIds.push(j) + } + } + } else { + this.last.searchIds.push(i) + } + } + } + this.total = this.last.searchIds.length + } + time = Date.now() - time + if (silent !== true && this.show.statusSearch) { + setTimeout(() => { + this.status(w2utils.lang('Search took ${count} seconds', { count: time/1000 })) + }, 10) + } + return time + // check if a record (or one of its closed children) matches the search data + function searchRecord(rec) { + let fl = 0, val1, val2, val3, tmp + let orEqual = false + for (let j = 0; j < obj.searchData.length; j++) { + let sdata = obj.searchData[j] + let search = obj.getSearch(sdata.field) + if (sdata == null) continue + if (search == null) search = { field: sdata.field, type: sdata.type } + let val1b = obj.parseField(rec, search.field) + val1 = (val1b !== null && val1b !== undefined && + (typeof val1b != 'object' || val1b.toString != defaultToString)) ? + String(val1b).toLowerCase() : '' // do not match a bogus string + if (sdata.value != null) { + if (!Array.isArray(sdata.value)) { + val2 = String(sdata.value).toLowerCase() + } else { + val2 = sdata.value[0] + val3 = sdata.value[1] + } + } + switch (sdata.operator) { + case '=': + case 'is': + if (obj.parseField(rec, search.field) == sdata.value) fl++ // do not hide record + else if (search.type == 'date') { + tmp = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)) + val1 = w2utils.formatDate(tmp, 'yyyy-mm-dd') + val2 = w2utils.formatDate(w2utils.isDate(val2, w2utils.settings.dateFormat, true), 'yyyy-mm-dd') + if (val1 == val2) fl++ + } + else if (search.type == 'time') { + tmp = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)) + val1 = w2utils.formatTime(tmp, 'hh24:mi') + val2 = w2utils.formatTime(val2, 'hh24:mi') + if (val1 == val2) fl++ + } + else if (search.type == 'datetime') { + tmp = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)) + val1 = w2utils.formatDateTime(tmp, 'yyyy-mm-dd|hh24:mm:ss') + val2 = w2utils.formatDateTime(w2utils.isDateTime(val2, w2utils.settings.datetimeFormat, true), 'yyyy-mm-dd|hh24:mm:ss') + if (val1 == val2) fl++ + } + break + case 'between': + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(search.type) != -1) { + if (parseFloat(obj.parseField(rec, search.field)) >= parseFloat(val2) && parseFloat(obj.parseField(rec, search.field)) <= parseFloat(val3)) fl++ + } + else if (search.type == 'date') { + tmp = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)) + val1 = w2utils.isDate(tmp, w2utils.settings.dateFormat, true) + val2 = w2utils.isDate(val2, w2utils.settings.dateFormat, true) + val3 = w2utils.isDate(val3, w2utils.settings.dateFormat, true) + if (val3 != null) val3 = new Date(val3.getTime() + 86400000) // 1 day + if (val1 >= val2 && val1 < val3) fl++ + } + else if (search.type == 'time') { + val1 = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)) + val2 = w2utils.isTime(val2, true) + val3 = w2utils.isTime(val3, true) + val2 = (new Date()).setHours(val2.hours, val2.minutes, val2.seconds ? val2.seconds : 0, 0) + val3 = (new Date()).setHours(val3.hours, val3.minutes, val3.seconds ? val3.seconds : 0, 0) + if (val1 >= val2 && val1 < val3) fl++ + } + else if (search.type == 'datetime') { + val1 = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)) + val2 = w2utils.isDateTime(val2, w2utils.settings.datetimeFormat, true) + val3 = w2utils.isDateTime(val3, w2utils.settings.datetimeFormat, true) + if (val3) val3 = new Date(val3.getTime() + 86400000) // 1 day + if (val1 >= val2 && val1 < val3) fl++ + } + break + case '<=': + orEqual = true + case '<': + case 'less': + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(search.type) != -1) { + val1 = parseFloat(obj.parseField(rec, search.field)) + val2 = parseFloat(sdata.value) + if (val1 < val2 || (orEqual && val1 === val2)) fl++ + } + else if (search.type == 'date') { + tmp = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)) + val1 = w2utils.isDate(tmp, w2utils.settings.dateFormat, true) + val2 = w2utils.isDate(val2, w2utils.settings.dateFormat, true) + if (val1 < val2 || (orEqual && val1 === val2)) fl++ + } + else if (search.type == 'time') { + tmp = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)) + val1 = w2utils.formatTime(tmp, 'hh24:mi') + val2 = w2utils.formatTime(val2, 'hh24:mi') + if (val1 < val2 || (orEqual && val1 === val2)) fl++ + } + else if (search.type == 'datetime') { + tmp = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)) + val1 = w2utils.formatDateTime(tmp, 'yyyy-mm-dd|hh24:mm:ss') + val2 = w2utils.formatDateTime(w2utils.isDateTime(val2, w2utils.settings.datetimeFormat, true), 'yyyy-mm-dd|hh24:mm:ss') + if (val1.length == val2.length && (val1 < val2 || (orEqual && val1 === val2))) fl++ + } + break + case '>=': + orEqual = true + case '>': + case 'more': + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(search.type) != -1) { + val1 = parseFloat(obj.parseField(rec, search.field)) + val2 = parseFloat(sdata.value) + if (val1 > val2 || (orEqual && val1 === val2)) fl++ + } + else if (search.type == 'date') { + tmp = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)) + val1 = w2utils.isDate(tmp, w2utils.settings.dateFormat, true) + val2 = w2utils.isDate(val2, w2utils.settings.dateFormat, true) + if (val1 > val2 || (orEqual && val1 === val2)) fl++ + } + else if (search.type == 'time') { + tmp = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)) + val1 = w2utils.formatTime(tmp, 'hh24:mi') + val2 = w2utils.formatTime(val2, 'hh24:mi') + if (val1 > val2 || (orEqual && val1 === val2)) fl++ + } + else if (search.type == 'datetime') { + tmp = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)) + val1 = w2utils.formatDateTime(tmp, 'yyyy-mm-dd|hh24:mm:ss') + val2 = w2utils.formatDateTime(w2utils.isDateTime(val2, w2utils.settings.datetimeFormat, true), 'yyyy-mm-dd|hh24:mm:ss') + if (val1.length == val2.length && (val1 > val2 || (orEqual && val1 === val2))) fl++ + } + break + case 'in': + tmp = sdata.value + if (sdata.svalue) tmp = sdata.svalue + if ((tmp.indexOf(w2utils.isFloat(val1b) ? parseFloat(val1b) : val1b) !== -1) || tmp.indexOf(val1) !== -1) fl++ + break + case 'not in': + tmp = sdata.value + if (sdata.svalue) tmp = sdata.svalue + if (!((tmp.indexOf(w2utils.isFloat(val1b) ? parseFloat(val1b) : val1b) !== -1) || tmp.indexOf(val1) !== -1)) fl++ + break + case 'begins': + case 'begins with': // need for back compatibility + if (val1.indexOf(val2) === 0) fl++ // do not hide record + break + case 'contains': + if (val1.indexOf(val2) >= 0) fl++ // do not hide record + break + case 'null': + if (obj.parseField(rec, search.field) == null) fl++ // do not hide record + break + case 'not null': + if (obj.parseField(rec, search.field) != null) fl++ // do not hide record + break + case 'ends': + case 'ends with': // need for back compatibility + let lastIndex = val1.lastIndexOf(val2) + if (lastIndex !== -1 && lastIndex == val1.length - val2.length) fl++ // do not hide record + break + } + } + if ((obj.last.logic == 'OR' && fl !== 0) || + (obj.last.logic == 'AND' && fl == obj.searchData.length)) + return true + if (rec.w2ui?.children && rec.w2ui?.expanded !== true) { + // there are closed children, search them too. + for (let r = 0; r < rec.w2ui.children.length; r++) { + let subRec = rec.w2ui.children[r] + if (searchRecord(subRec)) + return true + } + } + return false + } + // add parents nodes recursively + function addParent(recid) { + let i = obj.get(recid, true) + if (i == null || recid == null || duplicateMap[recid] || obj.last.searchIds.includes(i)) { + return + } + duplicateMap[recid] = true + let rec = obj.records[i] + if (rec?.w2ui) { + addParent(rec.w2ui.parent_recid) + } + obj.last.searchIds.push(i) + } + } + getRangeData(range, extra) { + let rec1 = this.get(range[0].recid, true) + let rec2 = this.get(range[1].recid, true) + let col1 = range[0].column + let col2 = range[1].column + let res = [] + if (col1 == col2) { // one row + for (let r = rec1; r <= rec2; r++) { + let record = this.records[r] + let dt = record[this.columns[col1].field] || null + if (extra !== true) { + res.push(dt) + } else { + res.push({ data: dt, column: col1, index: r, record: record }) + } + } + } else if (rec1 == rec2) { // one line + let record = this.records[rec1] + for (let i = col1; i <= col2; i++) { + let dt = record[this.columns[i].field] || null + if (extra !== true) { + res.push(dt) + } else { + res.push({ data: dt, column: i, index: rec1, record: record }) + } + } + } else { + for (let r = rec1; r <= rec2; r++) { + let record = this.records[r] + res.push([]) + for (let i = col1; i <= col2; i++) { + let dt = record[this.columns[i].field] + if (extra !== true) { + res[res.length-1].push(dt) + } else { + res[res.length-1].push({ data: dt, column: i, index: r, record: record }) + } + } + } + } + return res + } + addRange(ranges) { + let added = 0, first, last + if (this.selectType == 'row') return added + if (!Array.isArray(ranges)) ranges = [ranges] + // if it is selection + for (let i = 0; i < ranges.length; i++) { + if (typeof ranges[i] != 'object') ranges[i] = { name: 'selection' } + if (ranges[i].name == 'selection') { + if (this.show.selectionBorder === false) continue + let sel = this.getSelection() + if (sel.length === 0) { + this.removeRange('selection') + continue + } else { + first = sel[0] + last = sel[sel.length-1] + } + } else { // other range + first = ranges[i].range[0] + last = ranges[i].range[1] + } + if (first) { + let rg = { + name: ranges[i].name, + range: [{ recid: first.recid, column: first.column }, { recid: last.recid, column: last.column }], + style: ranges[i].style || '' + } + // add range + let ind = false + for (let j = 0; j < this.ranges.length; j++) if (this.ranges[j].name == ranges[i].name) { ind = j; break } + if (ind !== false) { + this.ranges[ind] = rg + } else { + this.ranges.push(rg) + } + added++ + } + } + this.refreshRanges() + return added + } + removeRange() { + let removed = 0 + for (let a = 0; a < arguments.length; a++) { + let name = arguments[a] + query(this.box).find('#grid_'+ this.name +'_'+ name).remove() + query(this.box).find('#grid_'+ this.name +'_f'+ name).remove() + for (let r = this.ranges.length-1; r >= 0; r--) { + if (this.ranges[r].name == name) { + this.ranges.splice(r, 1) + removed++ + } + } + } + return removed + } + refreshRanges() { + if (this.ranges.length === 0) return + let self = this + let range + let time = Date.now() + let rec1 = query(this.box).find(`#grid_${this.name}_frecords`) + let rec2 = query(this.box).find(`#grid_${this.name}_records`) + for (let i = 0; i < this.ranges.length; i++) { + let rg = this.ranges[i] + let first = rg.range[0] + let last = rg.range[1] + if (first.index == null) first.index = this.get(first.recid, true) + if (last.index == null) last.index = this.get(last.recid, true) + let td1 = query(this.box).find('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(first.recid) + ' td[col="'+ first.column +'"]') + let td2 = query(this.box).find('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(last.recid) + ' td[col="'+ last.column +'"]') + let td1f = query(this.box).find('#grid_'+ this.name +'_frec_'+ w2utils.escapeId(first.recid) + ' td[col="'+ first.column +'"]') + let td2f = query(this.box).find('#grid_'+ this.name +'_frec_'+ w2utils.escapeId(last.recid) + ' td[col="'+ last.column +'"]') + let _lastColumn = last.column + // adjustment due to column virtual scroll + if (first.column < this.last.colStart && last.column > this.last.colStart) { + td1 = query(this.box).find('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(first.recid) + ' td[col="start"]') + } + if (first.column < this.last.colEnd && last.column > this.last.colEnd) { + td2 = query(this.box).find('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(last.recid) + ' td[col="end"]') + _lastColumn = '"end"' + } + // if virtual scrolling kicked in + let index_top = parseInt(query(this.box).find('#grid_'+ this.name +'_rec_top').next().attr('index')) + let index_bottom = parseInt(query(this.box).find('#grid_'+ this.name +'_rec_bottom').prev().attr('index')) + let index_ftop = parseInt(query(this.box).find('#grid_'+ this.name +'_frec_top').next().attr('index')) + let index_fbottom = parseInt(query(this.box).find('#grid_'+ this.name +'_frec_bottom').prev().attr('index')) + if (td1.length === 0 && first.index < index_top && last.index > index_top) { + td1 = query(this.box).find('#grid_'+ this.name +'_rec_top').next().find('td[col="'+ first.column +'"]') + } + if (td2.length === 0 && last.index > index_bottom && first.index < index_bottom) { + td2 = query(this.box).find('#grid_'+ this.name +'_rec_bottom').prev().find('td[col="'+ _lastColumn +'"]') + } + if (td1f.length === 0 && first.index < index_ftop && last.index > index_ftop) { // frozen + td1f = query(this.box).find('#grid_'+ this.name +'_frec_top').next().find('td[col="'+ first.column +'"]') + } + if (td2f.length === 0 && last.index > index_fbottom && first.index < index_fbottom) { // frozen + td2f = query(this.box).find('#grid_'+ this.name +'_frec_bottom').prev().find('td[col="'+ last.column +'"]') + } + // do not show selection cell if it is editable + let edit = query(this.box).find('#grid_'+ this.name + '_editable') + let tmp = edit.find('.w2ui-input') + let tmp1 = tmp.attr('recid') + let tmp2 = tmp.attr('column') + if (rg.name == 'selection' && rg.range[0].recid == tmp1 && rg.range[0].column == tmp2) continue + // frozen regular columns range + range = query(this.box).find('#grid_'+ this.name +'_f'+ rg.name) + if (td1f.length > 0 || td2f.length > 0) { + if (range.length === 0) { + rec1.append('
    '+ + (rg.name == 'selection' ? '
    ' : '')+ + '
    ') + range = query(this.box).find('#grid_'+ this.name +'_f'+ rg.name) + } else { + range.attr('style', rg.style) + range.find('.w2ui-selection-resizer').show() + } + if (td2f.length === 0) { + td2f = query(this.box).find('#grid_'+ this.name +'_frec_'+ w2utils.escapeId(last.recid) +' td:last-child') + if (td2f.length === 0) td2f = query(this.box).find('#grid_'+ this.name +'_frec_bottom td:first-child') + range.css('border-right', '0px') + range.find('.w2ui-selection-resizer').hide() + } + if (first.recid != null && last.recid != null && td1f.length > 0 && td2f.length > 0) { + let style = getComputedStyle(td2f[0]) + let top1 = (td1f.prop('offsetTop') - td1f.prop('scrollTop')) + let left1 = (td1f.prop('offsetLeft') + td1f.prop('scrollLeft')) + let top2 = (td2f.prop('offsetTop') - td2f.prop('scrollTop')) + let left2 = (td2f.prop('offsetLeft') + td2f.prop('scrollLeft')) + range.show().css({ + top : (top1 > 0 ? top1 : 0) + 'px', + left : (left1 > 0 ? left1 : 0) + 'px', + width : (left2 - left1 + parseFloat(style.width) + 2) + 'px', + height : (top2 - top1 + parseFloat(style.height) + 1) + 'px' + }) + } else { + range.hide() + } + } else { + range.hide() + } + // regular columns range + range = query(this.box).find('#grid_'+ this.name +'_'+ rg.name) + if (td1.length > 0 || td2.length > 0) { + if (range.length === 0) { + rec2.append('
    '+ + (rg.name == 'selection' ? '
    ' : '')+ + '
    ') + range = query(this.box).find('#grid_'+ this.name +'_'+ rg.name) + } else { + range.attr('style', rg.style) + } + if (td1.length === 0) { + td1 = query(this.box).find('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(first.recid) +' td:first-child') + if (td1.length === 0) td1 = query(this.box).find('#grid_'+ this.name +'_rec_top td:first-child') + } + if (td2f.length !== 0) { + range.css('border-left', '0px') + } + if (first.recid != null && last.recid != null && td1.length > 0 && td2.length > 0) { + let style = getComputedStyle(td2[0]) + let top1 = (td1.prop('offsetTop') - td1.prop('scrollTop')) + let left1 = (td1.prop('offsetLeft') + td1.prop('scrollLeft')) + let top2 = (td2.prop('offsetTop') - td2.prop('scrollTop')) + let left2 = (td2.prop('offsetLeft') + td2.prop('scrollLeft')) + range.show().css({ + top : (top1 > 0 ? top1 : 0) + 'px', + left : (left1 > 0 ? left1 : 0) + 'px', + width : (left2 - left1 + parseFloat(style.width) + 2) + 'px', + height : (top2 - top1 + parseFloat(style.height) + 1) + 'px' + }) + } else { + range.hide() + } + } else { + range.hide() + } + } + // add resizer events + query(this.box).find('.w2ui-selection-resizer') + .off('.resizer') + .on('mousedown.resizer', mouseStart) + .on('dblclick.resizer', (event) => { + let edata = this.trigger('resizerDblClick', { target: this.name, originalEvent: event }) + if (edata.isCancelled === true) return + edata.finish() + }) + let edata = { target: this.name, originalRange: null, newRange: null } + return Date.now() - time + function mouseStart(event) { + let sel = self.getSelection() + self.last.move = { + type : 'expand', + x : event.screenX, + y : event.screenY, + divX : 0, + divY : 0, + recid : sel[0].recid, + column : sel[0].column, + originalRange : [w2utils.clone(sel[0]), w2utils.clone(sel[sel.length-1]) ], + newRange : [w2utils.clone(sel[0]), w2utils.clone(sel[sel.length-1]) ] + } + query('body') + .off('.w2ui-' + self.name) + .on('mousemove.w2ui-' + self.name, mouseMove) + .on('mouseup.w2ui-' + self.name, mouseStop) + // do not blur grid + event.preventDefault() + } + function mouseMove(event) { + let mv = self.last.move + if (!mv || mv.type != 'expand') return + mv.divX = (event.screenX - mv.x) + mv.divY = (event.screenY - mv.y) + // find new cell + let recid, column + let tmp = event.target + if (tmp.tagName.toUpperCase() != 'TD') tmp = query(tmp).closest('td')[0] + if (query(tmp).attr('col') != null) column = parseInt(query(tmp).attr('col')) + if (column == null) { + return + } + tmp = query(tmp).closest('tr')[0] + recid = self.records[query(tmp).attr('index')].recid + // new range + if (mv.newRange[1].recid == recid && mv.newRange[1].column == column) return + let prevNewRange = w2utils.clone(mv.newRange) + mv.newRange = [{ recid: mv.recid, column: mv.column }, { recid: recid, column: column }] + // event before + if (edata.detail) { + edata.detail.newRange = w2utils.clone(mv.newRange) + edata.detail.originalRange = w2utils.clone(mv.originalRange) + } + edata = self.trigger('selectionExtend', edata) + if (edata.isCancelled === true) { + mv.newRange = prevNewRange + edata.detail.newRange = prevNewRange + return + } else { + // default behavior + self.removeRange('grid-selection-expand') + self.addRange({ + name : 'grid-selection-expand', + range : mv.newRange, + style : 'background-color: rgba(100,100,100,0.1); border: 2px dotted rgba(100,100,100,0.5);' + }) + } + } + function mouseStop(event) { + // default behavior + self.removeRange('grid-selection-expand') + delete self.last.move + query('body').off('.w2ui-' + self.name) + // event after + if (edata.finish) edata.finish() + } + } + select() { + if (arguments.length === 0) return 0 + let selected = 0 + let sel = this.last.selection + if (!this.multiSelect) this.selectNone(true) + // if too many arguments > 150k, then it errors off + let args = Array.from(arguments) + if (Array.isArray(args[0])) args = args[0] + // event before + let tmp = { target: this.name } + if (args.length == 1) { + tmp.multiple = false + if (w2utils.isPlainObject(args[0])) { + tmp.clicked = { + recid: args[0].recid, + column: args[0].column + } + } else { + tmp.recid = args[0] + } + } else { + tmp.multiple = true + tmp.clicked = { recids: args } + } + let edata = this.trigger('select', tmp) + if (edata.isCancelled === true) return 0 + // default action + if (this.selectType == 'row') { + for (let a = 0; a < args.length; a++) { + let recid = typeof args[a] == 'object' ? args[a].recid : args[a] + let index = this.get(recid, true) + if (index == null) continue + let recEl1 = null + let recEl2 = null + if (this.searchData.length !== 0 || (index + 1 >= this.last.range_start && index + 1 <= this.last.range_end)) { + recEl1 = query(this.box).find('#grid_'+ this.name +'_frec_'+ w2utils.escapeId(recid)) + recEl2 = query(this.box).find('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)) + } + if (this.selectType == 'row') { + if (sel.indexes.indexOf(index) != -1) continue + sel.indexes.push(index) + if (recEl1 && recEl2) { + recEl1.addClass('w2ui-selected').find('.w2ui-col-number').addClass('w2ui-row-selected') + recEl2.addClass('w2ui-selected').find('.w2ui-col-number').addClass('w2ui-row-selected') + recEl1.find('.w2ui-grid-select-check').prop('checked', true) + } + selected++ + } + } + } else { + // normalize for performance + let new_sel = {} + for (let a = 0; a < args.length; a++) { + let recid = typeof args[a] == 'object' ? args[a].recid : args[a] + let column = typeof args[a] == 'object' ? args[a].column : null + new_sel[recid] = new_sel[recid] || [] + if (Array.isArray(column)) { + new_sel[recid] = column + } else if (w2utils.isInt(column)) { + new_sel[recid].push(column) + } else { + for (let i = 0; i < this.columns.length; i++) { if (this.columns[i].hidden) continue; new_sel[recid].push(parseInt(i)) } + } + } + // add all + let col_sel = [] + for (let recid in new_sel) { + let index = this.get(recid, true) + if (index == null) continue + let recEl1 = null + let recEl2 = null + if (index + 1 >= this.last.range_start && index + 1 <= this.last.range_end) { + recEl1 = query(this.box).find('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)) + recEl2 = query(this.box).find('#grid_'+ this.name +'_frec_'+ w2utils.escapeId(recid)) + } + let s = sel.columns[index] || [] + // default action + if (sel.indexes.indexOf(index) == -1) { + sel.indexes.push(index) + } + // only only those that are new + for (let t = 0; t < new_sel[recid].length; t++) { + if (s.indexOf(new_sel[recid][t]) == -1) s.push(new_sel[recid][t]) + } + s.sort((a, b) => { return a-b }) // sort function must be for numerical sort + for (let t = 0; t < new_sel[recid].length; t++) { + let col = new_sel[recid][t] + if (col_sel.indexOf(col) == -1) col_sel.push(col) + if (recEl1) { + recEl1.find('#grid_'+ this.name +'_data_'+ index +'_'+ col).addClass('w2ui-selected') + recEl1.find('.w2ui-col-number').addClass('w2ui-row-selected') + recEl1.find('.w2ui-grid-select-check').prop('checked', true) + } + if (recEl2) { + recEl2.find('#grid_'+ this.name +'_data_'+ index +'_'+ col).addClass('w2ui-selected') + recEl2.find('.w2ui-col-number').addClass('w2ui-row-selected') + recEl2.find('.w2ui-grid-select-check').prop('checked', true) + } + selected++ + } + // save back to selection object + sel.columns[index] = s + } + // select columns (need here for speed) + for (let c = 0; c < col_sel.length; c++) { + query(this.box).find('#grid_'+ this.name +'_column_'+ col_sel[c] +' .w2ui-col-header').addClass('w2ui-col-selected') + } + } + // need to sort new selection for speed + sel.indexes.sort((a, b) => { return a-b }) + // all selected? + let areAllSelected = (this.records.length > 0 && sel.indexes.length == this.records.length), + areAllSearchedSelected = (sel.indexes.length > 0 && this.searchData.length !== 0 && sel.indexes.length == this.last.searchIds.length) + if (areAllSelected || areAllSearchedSelected) { + query(this.box).find('#grid_'+ this.name +'_check_all').prop('checked', true) + } else { + query(this.box).find('#grid_'+ this.name +'_check_all').prop('checked', false) + } + this.status() + this.addRange('selection') + this.updateToolbar(sel, areAllSelected) + // event after + edata.finish() + return selected + } + unselect() { + let unselected = 0 + let sel = this.last.selection + // if too many arguments > 150k, then it errors off + let args = Array.from(arguments) + if (Array.isArray(args[0])) args = args[0] + // event before + let tmp = { target: this.name } + if (args.length == 1) { + tmp.multiple = false + if (w2utils.isPlainObject(args[0])) { + tmp.clicked = { + recid: args[0].recid, + column: args[0].column + } + } else { + tmp.clicked = { recid: args[0] } + } + } else { + tmp.multiple = true + tmp.recids = args + } + let edata = this.trigger('select', tmp) + if (edata.isCancelled === true) return 0 + for (let a = 0; a < args.length; a++) { + let recid = typeof args[a] == 'object' ? args[a].recid : args[a] + let record = this.get(recid) + if (record == null) continue + let index = this.get(record.recid, true) + let recEl1 = query(this.box).find('#grid_'+ this.name +'_frec_'+ w2utils.escapeId(recid)) + let recEl2 = query(this.box).find('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)) + if (this.selectType == 'row') { + if (sel.indexes.indexOf(index) == -1) continue + // default action + sel.indexes.splice(sel.indexes.indexOf(index), 1) + recEl1.removeClass('w2ui-selected w2ui-inactive').find('.w2ui-col-number').removeClass('w2ui-row-selected') + recEl2.removeClass('w2ui-selected w2ui-inactive').find('.w2ui-col-number').removeClass('w2ui-row-selected') + if (recEl1.length != 0) { + recEl1[0].style.cssText = 'height: '+ this.recordHeight +'px; ' + recEl1.attr('custom_style') + recEl2[0].style.cssText = 'height: '+ this.recordHeight +'px; ' + recEl2.attr('custom_style') + } + recEl1.find('.w2ui-grid-select-check').prop('checked', false) + unselected++ + } else { + let col = args[a].column + if (!w2utils.isInt(col)) { // unselect all columns + let cols = [] + for (let i = 0; i < this.columns.length; i++) { if (this.columns[i].hidden) continue; cols.push({ recid: recid, column: i }) } + return this.unselect(cols) + } + let s = sel.columns[index] + if (!Array.isArray(s) || s.indexOf(col) == -1) continue + // default action + s.splice(s.indexOf(col), 1) + query(this.box).find(`#grid_${this.name}_rec_${w2utils.escapeId(recid)} > td[col="${col}"]`).removeClass('w2ui-selected w2ui-inactive') + query(this.box).find(`#grid_${this.name}_frec_${w2utils.escapeId(recid)} > td[col="${col}"]`).removeClass('w2ui-selected w2ui-inactive') + // check if any row/column still selected + let isColSelected = false + let isRowSelected = false + let tmp = this.getSelection() + for (let i = 0; i < tmp.length; i++) { + if (tmp[i].column == col) isColSelected = true + if (tmp[i].recid == recid) isRowSelected = true + } + if (!isColSelected) { + query(this.box).find(`.w2ui-grid-columns td[col="${col}"] .w2ui-col-header, .w2ui-grid-fcolumns td[col="${col}"] .w2ui-col-header`).removeClass('w2ui-col-selected') + } + if (!isRowSelected) { + query(this.box).find('#grid_'+ this.name +'_frec_'+ w2utils.escapeId(recid)).find('.w2ui-col-number').removeClass('w2ui-row-selected') + } + unselected++ + if (s.length === 0) { + delete sel.columns[index] + sel.indexes.splice(sel.indexes.indexOf(index), 1) + recEl1.find('.w2ui-grid-select-check').prop('checked', false) + } + } + } + // all selected? + let areAllSelected = (this.records.length > 0 && sel.indexes.length == this.records.length), + areAllSearchedSelected = (sel.indexes.length > 0 && this.searchData.length !== 0 && sel.indexes.length == this.last.searchIds.length) + if (areAllSelected || areAllSearchedSelected) { + query(this.box).find('#grid_'+ this.name +'_check_all').prop('checked', true) + } else { + query(this.box).find('#grid_'+ this.name +'_check_all').prop('checked', false) + } + // show number of selected + this.status() + this.addRange('selection') + this.updateToolbar(sel, areAllSelected) + // event after + edata.finish() + return unselected + } + selectAll() { + let time = Date.now() + if (this.multiSelect === false) return + // default action + let url = this.url?.get ?? this.url + let sel = w2utils.clone(this.last.selection) + let cols = [] + for (let i = 0; i < this.columns.length; i++) cols.push(i) + // if local data source and searched + sel.indexes = [] + if (!url && this.searchData.length !== 0) { + // local search applied + for (let i = 0; i < this.last.searchIds.length; i++) { + sel.indexes.push(this.last.searchIds[i]) + if (this.selectType != 'row') sel.columns[this.last.searchIds[i]] = cols.slice() // .slice makes copy of the array + } + } else { + let buffered = this.records.length + if (this.searchData.length != 0 && !url) buffered = this.last.searchIds.length + for (let i = 0; i < buffered; i++) { + sel.indexes.push(i) + if (this.selectType != 'row') sel.columns[i] = cols.slice() // .slice makes copy of the array + } + } + // event before + let edata = this.trigger('select', { target: this.name, multiple: true, all: true, clicked: sel }) + if (edata.isCancelled === true) return + this.last.selection = sel + // add selected class + if (this.selectType == 'row') { + query(this.box).find('.w2ui-grid-records tr:not(.w2ui-empty-record)') + .addClass('w2ui-selected').find('.w2ui-col-number').addClass('w2ui-row-selected') + query(this.box).find('.w2ui-grid-frecords tr:not(.w2ui-empty-record)') + .addClass('w2ui-selected').find('.w2ui-col-number').addClass('w2ui-row-selected') + query(this.box).find('input.w2ui-grid-select-check').prop('checked', true) + } else { + query(this.box).find('.w2ui-grid-columns td .w2ui-col-header, .w2ui-grid-fcolumns td .w2ui-col-header').addClass('w2ui-col-selected') + query(this.box).find('.w2ui-grid-records tr .w2ui-col-number').addClass('w2ui-row-selected') + query(this.box).find('.w2ui-grid-records tr:not(.w2ui-empty-record)') + .find('.w2ui-grid-data:not(.w2ui-col-select)').addClass('w2ui-selected') + query(this.box).find('.w2ui-grid-frecords tr .w2ui-col-number').addClass('w2ui-row-selected') + query(this.box).find('.w2ui-grid-frecords tr:not(.w2ui-empty-record)') + .find('.w2ui-grid-data:not(.w2ui-col-select)').addClass('w2ui-selected') + query(this.box).find('input.w2ui-grid-select-check').prop('checked', true) + } + // enable/disable toolbar buttons + sel = this.getSelection(true) + this.addRange('selection') + query(this.box).find('#grid_'+ this.name +'_check_all').prop('checked', true) + this.status() + this.updateToolbar({ indexes: sel }, true) + // event after + edata.finish() + return Date.now() - time + } + selectNone(skipEvent) { + let time = Date.now() + // event before + let edata + if (!skipEvent) { + edata = this.trigger('select', { target: this.name, clicked: [] }) + if (edata.isCancelled === true) return + } + // default action + let sel = this.last.selection + // remove selected class + if (this.selectType == 'row') { + query(this.box).find('.w2ui-grid-records tr.w2ui-selected').removeClass('w2ui-selected w2ui-inactive') + .find('.w2ui-col-number').removeClass('w2ui-row-selected') + query(this.box).find('.w2ui-grid-frecords tr.w2ui-selected').removeClass('w2ui-selected w2ui-inactive') + .find('.w2ui-col-number').removeClass('w2ui-row-selected') + query(this.box).find('input.w2ui-grid-select-check').prop('checked', false) + } else { + query(this.box).find('.w2ui-grid-columns td .w2ui-col-header, .w2ui-grid-fcolumns td .w2ui-col-header').removeClass('w2ui-col-selected') + query(this.box).find('.w2ui-grid-records tr .w2ui-col-number').removeClass('w2ui-row-selected') + query(this.box).find('.w2ui-grid-frecords tr .w2ui-col-number').removeClass('w2ui-row-selected') + query(this.box).find('.w2ui-grid-data.w2ui-selected').removeClass('w2ui-selected w2ui-inactive') + query(this.box).find('input.w2ui-grid-select-check').prop('checked', false) + } + sel.indexes = [] + sel.columns = {} + this.removeRange('selection') + query(this.box).find('#grid_'+ this.name +'_check_all').prop('checked', false) + this.status() + this.updateToolbar(sel, false) + // event after + if (!skipEvent) { + edata.finish() + } + return Date.now() - time + } + updateToolbar(sel) { + let obj = this + let cnt = sel && sel.indexes ? sel.indexes.length : 0 + this.toolbar.items.forEach((item) => { + _checkItem(item, '') + if (Array.isArray(item.items)) { + item.items.forEach((it) => { + _checkItem(it, item.id + ':') + }) + } + }) + // enable/disable toolbar search button + if (this.show.toolbarSave) { + if (this.getChanges().length > 0) { + this.toolbar.enable('w2ui-save') + } else { + this.toolbar.disable('w2ui-save') + } + } + function _checkItem(item, prefix) { + if (item.batch != null) { + let enabled = false + if (item.batch === true) { + if (cnt > 0) enabled = true + } else if (typeof item.batch == 'number') { + if (cnt === item.batch) enabled = true + } else if (typeof item.batch == 'function') { + enabled = item.batch({ cnt, sel }) + } + if (enabled) { + obj.toolbar.enable(prefix + item.id) + } else { + obj.toolbar.disable(prefix + item.id) + } + } + } + } + getSelection(returnIndex) { + let ret = [] + let sel = this.last.selection + if (this.selectType == 'row') { + for (let i = 0; i < sel.indexes.length; i++) { + if (!this.records[sel.indexes[i]]) continue + if (returnIndex === true) ret.push(sel.indexes[i]); else ret.push(this.records[sel.indexes[i]].recid) + } + return ret + } else { + for (let i = 0; i < sel.indexes.length; i++) { + let cols = sel.columns[sel.indexes[i]] + if (!this.records[sel.indexes[i]]) continue + for (let j = 0; j < cols.length; j++) { + ret.push({ recid: this.records[sel.indexes[i]].recid, index: parseInt(sel.indexes[i]), column: cols[j] }) + } + } + return ret + } + } + search(field, value) { + let url = this.url?.get ?? this.url + let searchData = [] + let last_multi = this.last.multi + let last_logic = this.last.logic + let last_field = this.last.field + let last_search = this.last.search + let hasHiddenSearches = false + let overlay = query(`#w2overlay-${this.name}-search-overlay`) + // add hidden searches + for (let i = 0; i < this.searches.length; i++) { + if (!this.searches[i].hidden || this.searches[i].value == null) continue + searchData.push({ + field : this.searches[i].field, + operator : this.searches[i].operator || 'is', + type : this.searches[i].type, + value : this.searches[i].value || '' + }) + hasHiddenSearches = true + } + if (arguments.length === 0 && overlay.length === 0) { + if (this.multiSearch) { + field = this.searchData + value = this.last.logic + } else { + field = this.last.field + value = this.last.search + } + } + // 1: search() - advanced search (reads from popup) + if (arguments.length === 0 && overlay.length !== 0) { + this.focus() // otherwise search drop down covers searches + last_logic = overlay.find(`#grid_${this.name}_logic`).val() + last_search = '' + // advanced search + for (let i = 0; i < this.searches.length; i++) { + let search = this.searches[i] + let operator = overlay.find('#grid_'+ this.name + '_operator_'+ i).val() + let field1 = overlay.find('#grid_'+ this.name + '_field_'+ i) + let field2 = overlay.find('#grid_'+ this.name + '_field2_'+ i) + let value1 = field1.val() + let value2 = field2.val() + let svalue = null + let text = null + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(search.type) != -1) { + let fld1 = field1[0]._w2field + let fld2 = field2[0]._w2field + if (fld1) value1 = fld1.clean(value1) + if (fld2) value2 = fld2.clean(value2) + } + if (['list', 'enum'].indexOf(search.type) != -1 || ['in', 'not in'].indexOf(operator) != -1) { + value1 = field1[0]._w2field.selected || {} + if (Array.isArray(value1)) { + svalue = [] + for (let j = 0; j < value1.length; j++) { + svalue.push(w2utils.isFloat(value1[j].id) ? parseFloat(value1[j].id) : String(value1[j].id).toLowerCase()) + delete value1[j].hidden + } + if (Object.keys(value1).length === 0) value1 = '' + } else { + text = value1.text || '' + value1 = value1.id || '' + } + } + if ((value1 !== '' && value1 != null) || (value2 != null && value2 !== '')) { + let tmp = { + field : search.field, + type : search.type, + operator : operator + } + if (operator == 'between') { + w2utils.extend(tmp, { value: [value1, value2] }) + } else if (operator == 'in' && typeof value1 == 'string') { + w2utils.extend(tmp, { value: value1.split(',') }) + } else if (operator == 'not in' && typeof value1 == 'string') { + w2utils.extend(tmp, { value: value1.split(',') }) + } else { + w2utils.extend(tmp, { value: value1 }) + } + if (svalue) w2utils.extend(tmp, { svalue: svalue }) + if (text) w2utils.extend(tmp, { text: text }) + // convert date to unix time + try { + if (search.type == 'date' && operator == 'between') { + tmp.value[0] = value1 // w2utils.isDate(value1, w2utils.settings.dateFormat, true).getTime(); + tmp.value[1] = value2 // w2utils.isDate(value2, w2utils.settings.dateFormat, true).getTime(); + } + if (search.type == 'date' && operator == 'is') { + tmp.value = value1 // w2utils.isDate(value1, w2utils.settings.dateFormat, true).getTime(); + } + } catch (e) { + } + searchData.push(tmp) + last_multi = true // if only hidden searches, then do not set + } + } + } + // 2: search(field, value) - regular search + if (typeof field == 'string') { + // if only one argument - search all + if (arguments.length == 1) { + value = field + field = 'all' + } + last_field = field + last_search = value + last_multi = false + last_logic = (hasHiddenSearches ? 'AND' : 'OR') + // loop through all searches and see if it applies + if (value != null) { + if (field.toLowerCase() == 'all') { + // if there are search fields loop thru them + if (this.searches.length > 0) { + for (let i = 0; i < this.searches.length; i++) { + let search = this.searches[i] + if (search.type == 'text' || (search.type == 'alphanumeric' && w2utils.isAlphaNumeric(value)) + || (search.type == 'int' && w2utils.isInt(value)) || (search.type == 'float' && w2utils.isFloat(value)) + || (search.type == 'percent' && w2utils.isFloat(value)) || ((search.type == 'hex' || search.type == 'color') && w2utils.isHex(value)) + || (search.type == 'currency' && w2utils.isMoney(value)) || (search.type == 'money' && w2utils.isMoney(value)) + || (search.type == 'date' && w2utils.isDate(value)) || (search.type == 'time' && w2utils.isTime(value)) + || (search.type == 'datetime' && w2utils.isDateTime(value)) || (search.type == 'datetime' && w2utils.isDate(value)) + || (search.type == 'enum' && w2utils.isAlphaNumeric(value)) || (search.type == 'list' && w2utils.isAlphaNumeric(value)) + ) { + let def = this.defaultOperator[this.operatorsMap[search.type]] + let tmp = { + field : search.field, + type : search.type, + operator : (search.operator != null ? search.operator : def), + value : value + } + if (String(value).trim() != '') searchData.push(tmp) + } + // range in global search box + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(search.type) != -1 && String(value).trim().split('-').length == 2) { + let t = String(value).trim().split('-') + let tmp = { + field : search.field, + type : search.type, + operator : (search.operator != null ? search.operator : 'between'), + value : [t[0], t[1]] + } + searchData.push(tmp) + } + // lists fields + if (['list', 'enum'].indexOf(search.type) != -1) { + let new_values = [] + if (search.options == null) search.options = {} + if (!Array.isArray(search.options.items)) search.options.items = [] + for (let j = 0; j < search.options.items; j++) { + let tmp = search.options.items[j] + try { + let re = new RegExp(value, 'i') + if (re.test(tmp)) new_values.push(j) + if (tmp.text && re.test(tmp.text)) new_values.push(tmp.id) + } catch (e) {} + } + if (new_values.length > 0) { + let tmp = { + field : search.field, + type : search.type, + operator : (search.operator != null ? search.operator : 'in'), + value : new_values + } + searchData.push(tmp) + } + } + } + } else { + // no search fields, loop thru columns + for (let i = 0; i < this.columns.length; i++) { + let tmp = { + field : this.columns[i].field, + type : 'text', + operator : this.defaultOperator.text, + value : value + } + searchData.push(tmp) + } + } + } else { + let el = overlay.find('#grid_'+ this.name +'_search_all') + let search = this.getSearch(field) + if (search == null) search = { field: field, type: 'text' } + if (search.field == field) this.last.label = search.label + if (value !== '') { + let op = this.defaultOperator[this.operatorsMap[search.type]] + let val = value + if (['date', 'time', 'datetime'].indexOf(search.type) != -1) op = 'is' + if (['list', 'enum'].indexOf(search.type) != -1) { + op = 'is' + let tmp = el._w2field.get() + if (tmp && Object.keys(tmp).length > 0) val = tmp.id; else val = '' + } + if (search.type == 'int' && value !== '') { + op = 'is' + if (String(value).indexOf('-') != -1) { + let tmp = value.split('-') + if (tmp.length == 2) { + op = 'between' + val = [parseInt(tmp[0]), parseInt(tmp[1])] + } + } + if (String(value).indexOf(',') != -1) { + let tmp = value.split(',') + op = 'in' + val = [] + for (let i = 0; i < tmp.length; i++) val.push(tmp[i]) + } + } + if (search.operator != null) op = search.operator + let tmp = { + field : search.field, + type : search.type, + operator : op, + value : val + } + searchData.push(tmp) + } + } + } + } + // 3: search([{ field, value, [operator,] [type] }, { field, value, [operator,] [type] } ], logic) - submit whole structure + if (Array.isArray(field)) { + let logic = 'AND' + if (typeof value == 'string') { + logic = value.toUpperCase() + if (logic != 'OR' && logic != 'AND') logic = 'AND' + } + last_search = '' + last_multi = true + last_logic = logic + for (let i = 0; i < field.length; i++) { + let data = field[i] + if (typeof data.value == 'number' && data.operator == null) data.operator = this.defaultOperator.number + if (typeof data.value == 'string' && data.operator == null) data.operator = this.defaultOperator.text + if (Array.isArray(data.value) && data.operator == null) data.operator = this.defaultOperator.enum + if (w2utils.isDate(data.value) && data.operator == null) data.operator = this.defaultOperator.date + // merge current field and search if any + searchData.push(data) + } + } + // event before + let edata = this.trigger('search', { + target: this.name, + multi: (arguments.length === 0 ? true : false), + searchField: (field ? field : 'multi'), + searchValue: (field ? value : 'multi'), + searchData: searchData, + searchLogic: last_logic + }) + if (edata.isCancelled === true) return + // default action + this.searchData = edata.detail.searchData + this.last.field = last_field + this.last.search = last_search + this.last.multi = last_multi + this.last.logic = edata.detail.searchLogic + this.last.scrollTop = 0 + this.last.scrollLeft = 0 + this.last.selection.indexes = [] + this.last.selection.columns = {} + // -- clear all search field + this.searchClose() + // apply search + if (url) { + this.last.fetch.offset = 0 + this.reload() + } else { + // local search + this.localSearch() + this.refresh() + } + // event after + edata.finish() + } + // open advanced search popover + searchOpen() { + if (!this.box) return + if (this.searches.length === 0) return + // event before + let edata = this.trigger('searchOpen', { target: this.name }) + if (edata.isCancelled === true) { + return + } + let $btn = query(this.toolbar.box).find('.w2ui-grid-search-input .w2ui-search-drop') + $btn.addClass('checked') + // show search + w2tooltip.show({ + name: this.name + '-search-overlay', + anchor: query(this.box).find('#grid_'+ this.name +'_search_all').get(0), + position: 'bottom|top', + html: this.getSearchesHTML(), + align: 'left', + arrowSize: 12, + class: 'w2ui-grid-search-advanced', + hideOn: ['doc-click'] + }) + .then(event => { + this.initSearches() + this.last.search_opened = true + let overlay = query(`#w2overlay-${this.name}-search-overlay`) + overlay + .data('gridName', this.name) + .off('.grid-search') + .on('click.grid-search', () => { + // hide any tooltip opened by searches + overlay.find('input, select').each(el => { + let names = query(el).data('tooltipName') + if (names) names.forEach(name => { + w2tooltip.hide(name) + }) + }) + }) + w2utils.bindEvents(overlay.find('select, input, button'), this) + // init first field + let sfields = query(`#w2overlay-${this.name}-search-overlay *[rel=search]`) + if (sfields.length > 0) sfields[0].focus() + // event after + edata.finish() + }) + .hide(event => { + $btn.removeClass('checked') + this.last.search_opened = false + }) + } + searchClose() { + w2tooltip.hide(this.name + '-search-overlay') + } + // if clicked on a field in the search strip + searchFieldTooltip(ind, sd_ind, el) { + let sf = this.searches[ind] + let sd = this.searchData[sd_ind] + let oper = sd.operator + if (oper == 'more' && sd.type == 'date') oper = 'since' + if (oper == 'less' && sd.type == 'date') oper = 'before' + let options = '' + let val = sd.value + if (Array.isArray(sd.value)) { // && Array.isArray(sf.options.items)) { + sd.value.forEach(opt => { + options += `${opt.text || opt}` + }) + if (sd.type == 'date') { + options = '' + sd.value.forEach(opt => { + options += `${w2utils.formatDate(opt)}` + }) + } + } else { + if (sd.type == 'date') { + val = w2utils.formatDateTime(val) + } + } + w2tooltip.hide(this.name + '-search-props') + w2tooltip.show({ + name: this.name + '-search-props', + anchor: el, + class: 'w2ui-white', + hideOn: 'doc-click', + html: ` +
    + ${sf.label} + ${w2utils.lang(oper)} + ${Array.isArray(sd.value) + ? `${options}` + : `${val}` + } +
    + +
    +
    ` + }).then(event => { + query(event.detail.overlay.box).find('#remove').on('click', () => { + this.searchData.splice(`${sd_ind}`, 1) + this.reload() + this.localSearch() + w2tooltip.hide(this.name + '-search-props') + }) + }) + } + // drop down with save searches + searchSuggest(imediate, forceHide, input) { + clearTimeout(this.last.kbd_timer) + clearTimeout(this.last.overlay_timer) + this.searchShowFields(true) + this.searchClose() + if (forceHide === true) { + w2tooltip.hide(this.name + '-search-suggest') + return + } + if (query(`#w2overlay-${this.name}-search-suggest`).length > 0) { + // already shown + return + } + if (!imediate) { + this.last.overlay_timer = setTimeout(() => { this.searchSuggest(true) }, 100) + return + } + let el = query(this.box).find(`#grid_${this.name}_search_all`).get(0) + let searches = [ + ...this.defaultSearches ?? [], + ...this.defaultSearches?.length > 0 && this.savedSearches?.length > 0 ? ['--'] : [], + ...this.savedSearches ?? [] + ] + if (Array.isArray(searches) && searches.length > 0) { + w2menu.show({ + name: this.name + '-search-suggest', + anchor: el, + align: 'both', + items: searches, + hideOn: ['doc-click', 'sleect', 'remove'], + render(item) { + let ret = item.text + if (item.isDefault) ret = `${ret}` + return ret + } + }) + .select(event => { + let edata = this.trigger('searchSelect', { + target: this.name, + index: event.detail.index, + item: event.detail.item + }) + if (edata.isCancelled === true) { + event.preventDefault() + return + } + event.detail.overlay.hide() + this.last.logic = event.detail.item.logic || 'AND' + this.last.search = '' + this.last.label = '[Multiple Fields]' + this.searchData = w2utils.clone(event.detail.item.data) + this.searchSelected = w2utils.clone(event.detail.item, { exclude: ['icon', 'remove'] }) + this.reload() + edata.finish() + }) + .remove(event => { + let item = event.detail.item + let edata = this.trigger('searchRemove', { target: this.name, index: event.detail.index, item }) + if (edata.isCancelled === true) { + event.preventDefault() + return + } + event.detail.overlay.hide() + this.confirm(w2utils.lang('Do you want to delete search "${item}"?', { item: item.text })) + .yes(evt => { + // remove from searches + let search = this.savedSearches.findIndex((s) => s.id == item.id ? true : false) + if (search !== -1) { + this.savedSearches.splice(search, 1) + } + this.cacheSave('searches', this.savedSearches.map(s => w2utils.clone(s, { exclude: ['remove', 'icon'] }))) + evt.detail.self.close() + // evt after + edata.finish() + }) + .no(evt => { + evt.detail.self.close() + }) + }) + } + } + searchSave() { + let value = '' + if (this.searchSelected) { + value = this.searchSelected.text + } + let ind = this.savedSearches.findIndex(s => { return s.id == this.searchSelected?.id ? true : false }) + // event before + let edata = this.trigger('searchSave', { target: this.name, saveLocalStorage: true }) + if (edata.isCancelled === true) return + this.message({ + width: 350, + height: 150, + body: ``, + buttons: ` + + + ` + }).open(async (event) => { + query(event.detail.box).find('input, button').eq(0).val(value) + await event.complete + query(event.detail.box).find('#grid-search-cancel').on('click', () => { + this.message() + }) + query(event.detail.box).find('#grid-search-save').on('click', () => { + let name = query(event.detail.box).find('.w2ui-message .search-name').val() + // save in savedSearches + if (this.searchSelected && ind != -1) { + Object.assign(this.savedSearches[ind], { + id: name, + text: name, + logic: this.last.logic, + data: w2utils.clone(this.searchData) + }) + } else { + this.savedSearches.push({ + id: name, + text: name, + icon: 'w2ui-icon-search', + remove: true, + logic: this.last.logic, + data: this.searchData + }) + } + // save local storage + this.cacheSave('searches', this.savedSearches.map(s => w2utils.clone(s, { exclude: ['remove', 'icon'] }))) + this.message() + // update on screen + if (this.searchSelected) { + this.searchSelected.text = name + query(this.box).find(`#grid_${this.name}_search_name .name-text`).html(name) + } else { + this.searchSelected = { + text: name, + logic: this.last.logic, + data: w2utils.clone(this.searchData) + } + query(event.detail.box).find(`#grid_${this.name}_search_all`).val(' ').prop('readOnly', true) + query(event.detail.box).find(`#grid_${this.name}_search_name`).show().find('.name-text').html(name) + } + edata.finish({ name }) + }) + query(event.detail.box).find('input, button') + .off('.message') + .on('keydown.message', evt => { + let val = String(query(event.detail.box).find('.w2ui-message-body input').val()).trim() + if (evt.keyCode == 13 && val != '') { + query(event.detail.box).find('#grid-search-save').trigger('click') // enter + } + if (evt.keyCode == 27) { // escape + this.message() + } + }) + .eq(0) + .on('input.message', evt => { + let $save = query(event.detail.box).closest('.w2ui-message').find('#grid-search-save') + if (String(query(event.detail.box).val()).trim() === '') { + $save.prop('disabled', true) + } else { + $save.prop('disabled', false) + } + }) + .get(0) + .focus() + }) + } + cache(type) { + if (w2utils.hasLocalStorage && this.useLocalStorage) { + try { + let data = JSON.parse(localStorage.w2ui || '{}') + data[(this.stateId || this.name)] ??= {} + return data[(this.stateId || this.name)][type] + } catch (e) { + } + } + return null + } + cacheSave(type, value) { + if (w2utils.hasLocalStorage && this.useLocalStorage) { + try { + let data = JSON.parse(localStorage.w2ui || '{}') + data[(this.stateId || this.name)] ??= {} + data[(this.stateId || this.name)][type] = value + localStorage.w2ui = JSON.stringify(data) + return true + } catch (e) { + delete localStorage.w2ui + } + } + return false + } + searchReset(noReload) { + let searchData = [] + let hasHiddenSearches = false + // add hidden searches + for (let i = 0; i < this.searches.length; i++) { + if (!this.searches[i].hidden || this.searches[i].value == null) continue + searchData.push({ + field : this.searches[i].field, + operator : this.searches[i].operator || 'is', + type : this.searches[i].type, + value : this.searches[i].value || '' + }) + hasHiddenSearches = true + } + // event before + let edata = this.trigger('search', { reset: true, target: this.name, searchData: searchData }) + if (edata.isCancelled === true) return + // default action + let input = query(this.box).find('#grid_'+ this.name +'_search_all') + this.searchData = edata.detail.searchData + this.searchSelected = null + this.last.search = '' + this.last.logic = (hasHiddenSearches ? 'AND' : 'OR') + // --- do not reset to All Fields (I think) + input.next().hide() // advanced search button + if (this.searches.length > 0) { + if (!this.multiSearch || !this.show.searchAll) { + let tmp = 0 + while (tmp < this.searches.length && (this.searches[tmp].hidden || this.searches[tmp].simple === false)) tmp++ + if (tmp >= this.searches.length) { + // all searches are hidden + this.last.field = '' + this.last.label = '' + } else { + this.last.field = this.searches[tmp].field + this.last.label = this.searches[tmp].label + } + } else { + this.last.field = 'all' + this.last.label = 'All Fields' + input.next().show() // advanced search button + } + } + this.last.multi = false + this.last.fetch.offset = 0 + // reset scrolling position + this.last.scrollTop = 0 + this.last.scrollLeft = 0 + this.last.selection.indexes = [] + this.last.selection.columns = {} + // -- clear all search field + this.searchClose() + let all = input.val('').get(0) + if (all?._w2field) { all._w2field.reset() } + // apply search + if (!noReload) this.reload() + // event after + edata.finish() + } + searchShowFields(forceHide) { + if (forceHide === true) { + w2tooltip.hide(this.name + '-search-fields') + return + } + let items = [] + for (let s = -1; s < this.searches.length; s++) { + let search = this.searches[s] + let sField = (search ? search.field : null) + let column = this.getColumn(sField) + let disabled = false + let tooltip = null + if (this.show.searchHiddenMsg == true && s != -1 + && (column == null || (column.hidden === true && column.hideable !== false))) { + disabled = true + tooltip = w2utils.lang(`This column ${column == null ? 'does not exist' : 'is hidden'}`) + } + if (s == -1) { // -1 is All Fields search + if (!this.multiSearch || !this.show.searchAll) continue + search = { field: 'all', label: 'All Fields' } + } else { + if (column != null && column.hideable === false) continue + if (search.hidden === true) { + tooltip = w2utils.lang('This column is hidden') + // don't show hidden (not simple) searches + if (search.simple === false) continue + } + } + if (search.label == null && search.caption != null) { + console.log('NOTICE: grid search.caption property is deprecated, please use search.label. Search ->', search) + search.label = search.caption + } + items.push({ + id: search.field, + text: w2utils.lang(search.label), + search, + tooltip, + disabled, + checked: (search.field == this.last.field) + }) + } + w2menu.show({ + type: 'radio', + name: this.name + '-search-fields', + anchor: query(this.box).find('#grid_'+ this.name +'_search_name').parent().find('.w2ui-search-down').get(0), + items, + align: 'none', + hideOn: ['doc-click', 'select'] + }) + .select(event => { + this.searchInitInput(event.detail.item.search.field) + }) + } + searchInitInput(field, value) { + let search + let el = query(this.box).find('#grid_'+ this.name +'_search_all') + if (field == 'all') { + search = { field: 'all', label: w2utils.lang('All Fields') } + } else { + search = this.getSearch(field) + if (search == null) return + } + // update field + if (this.last.search != '') { + this.last.label = search.label + this.search(search.field, this.last.search) + } else { + this.last.field = search.field + this.last.label = search.label + } + el.attr('placeholder', w2utils.lang('Search') + ' ' + w2utils.lang(search.label || search.caption || search.field, true)) + } + // clears records and related params + clear(noRefresh) { + this.total = 0 + this.records = [] + this.summary = [] + this.last.fetch.offset = 0 // need this for reload button to work on remote data set + this.last.idCache = {} // optimization to free memory + this.last.selection = { indexes: [], columns: {} } + this.reset(true) + // refresh + if (!noRefresh) this.refresh() + } + // clears scroll position, selection, ranges + reset(noRefresh) { + // position + this.last.scrollTop = 0 + this.last.scrollLeft = 0 + this.last.range_start = null + this.last.range_end = null + // additional + query(this.box).find(`#grid_${this.name}_records`).prop('scrollTop', 0) + // refresh + if (!noRefresh) this.refresh() + } + skip(offset, callBack) { + let url = this.url?.get ?? this.url + if (url) { + this.offset = parseInt(offset) + if (this.offset > this.total) this.offset = this.total - this.limit + if (this.offset < 0 || !w2utils.isInt(this.offset)) this.offset = 0 + this.clear(true) + this.reload(callBack) + } else { + console.log('ERROR: grid.skip() can only be called when you have remote data source.') + } + } + load(url, callBack) { + if (url == null) { + console.log('ERROR: You need to provide url argument when calling .load() method of "'+ this.name +'" object.') + return new Promise((resolve, reject) => { reject() }) + } + // default action + this.clear(true) + return this.request('load', {}, url, callBack) + } + reload(callBack) { + let grid = this + let url = this.url?.get ?? this.url + grid.selectionSave() + if (url) { + // need to remember selection (not just last.selection object) + return this.load(url, () => { + grid.selectionRestore() + if (typeof callBack == 'function') callBack() + }) + } else { + this.reset(true) + this.localSearch() + this.selectionRestore() + if (typeof callBack == 'function') callBack({ status: 'success' }) + return new Promise(resolve => { resolve() }) + } + } + request(action, postData, url, callBack) { + let self = this + let resolve, reject + let requestProm = new Promise((res, rej) => { resolve = res; reject = rej }) + if (postData == null) postData = {} + if (!url) url = this.url + if (!url) return new Promise((resolve, reject) => { reject() }) + // build parameters list + if (!w2utils.isInt(this.offset)) this.offset = 0 + if (!w2utils.isInt(this.last.fetch.offset)) this.last.fetch.offset = 0 + // add list params + let edata + let params = { + limit: this.limit, + offset: parseInt(this.offset) + parseInt(this.last.fetch.offset), + searchLogic: this.last.logic, + search: this.searchData.map((search) => { + let _search = w2utils.clone(search) + if (this.searchMap && this.searchMap[_search.field]) _search.field = this.searchMap[_search.field] + return _search + }), + sort: this.sortData.map((sort) => { + let _sort = w2utils.clone(sort) + if (this.sortMap && this.sortMap[_sort.field]) _sort.field = this.sortMap[_sort.field] + return _sort + }) + } + if (this.searchData.length === 0) { + delete params.search + delete params.searchLogic + } + if (this.sortData.length === 0) { + delete params.sort + } + // append other params + w2utils.extend(params, this.postData) + w2utils.extend(params, postData) + // other actions + if (action == 'delete' || action == 'save') { + delete params.limit + delete params.offset + params.action = action + if (action == 'delete') { + params[this.recid || 'recid'] = this.getSelection() + } + } + // event before + if (action == 'load') { + edata = this.trigger('request', { target: this.name, url, postData: params, httpMethod: 'GET', + httpHeaders: this.httpHeaders }) + if (edata.isCancelled === true) return new Promise((resolve, reject) => { reject() }) + } else { + edata = { detail: { + url, + postData: params, + httpMethod: action == 'save' ? 'PUT' : 'DELETE', + httpHeaders: this.httpHeaders + }} + } + // call server to get data + if (this.last.fetch.offset === 0) { + this.lock(w2utils.lang(this.msgRefresh), true) + } + if (this.last.fetch.controller) try { this.last.fetch.controller.abort() } catch (e) {} + // URL + url = edata.detail.url + switch (action) { + case 'save': + if (url?.save) url = url.save + break + case 'delete': + if (url?.remove) url = url.remove + break + default: + url = url?.get ?? url + } + // process url with routeData + if (Object.keys(this.routeData).length > 0) { + let info = w2utils.parseRoute(url) + if (info.keys.length > 0) { + for (let k = 0; k < info.keys.length; k++) { + if (this.routeData[info.keys[k].name] == null) continue + url = url.replace((new RegExp(':'+ info.keys[k].name, 'g')), this.routeData[info.keys[k].name]) + } + } + } + url = new URL(url, location) + // ajax options + let fetchOptions = w2utils.prepareParams(url, { + method: edata.detail.httpMethod, + headers: edata.detail.httpHeaders, + body: edata.detail.postData + }, this.dataType) + Object.assign(this.last.fetch, { + action: action, + options: fetchOptions, + controller: new AbortController(), + start: Date.now(), + loaded: false + }) + fetchOptions.signal = this.last.fetch.controller.signal + fetch(url, fetchOptions) + .catch(processError) + .then(resp => { + if (resp == null) return // request aborted + if (resp?.status != 200) { + processError(resp ?? {}) + return + } + self.unlock() + resp.json() + .catch(processError) + .then(data => { + this.requestComplete(data, action, callBack, resolve, reject) + }) + }) + if (action == 'load') { + // event after + edata.finish() + } + return requestProm + function processError(response) { + if (response?.name === 'AbortError') { + // request was aborted by the grid + return + } + self.unlock() + // trigger event + let edata2 = self.trigger('error', { response, lastFetch: self.last.fetch }) + if (edata2.isCancelled === true) return + // default behavior + if (response.status && response.status != 200) { + self.error(response.status + ': ' + response.statusText) + } else { + console.log('ERROR: Server communication failed.', + '\n EXPECTED:', { total: 5, records: [{ recid: 1, field: 'value' }] }, + '\n OR:', { error: true, message: 'error message' }) + self.requestComplete({ error: true, message: w2utils.lang(this.msgHTTPError), response }, action, callBack, resolve, reject) + } + // event after + edata2.finish() + } + } + requestComplete(data, action, callBack, resolve, reject) { + let error = data.error ?? false + if (data.error == null && data.status === 'error') error = true + this.last.fetch.response = (Date.now() - this.last.fetch.start) / 1000 + setTimeout(() => { + if (this.show.statusResponse) { + this.status(w2utils.lang('Server Response ${count} seconds', { count: this.last.fetch.response })) + } + }, 10) + this.last.pull_more = false + this.last.pull_refresh = true + // event before + let event_name = 'load' + if (this.last.fetch.action == 'save') event_name = 'save' + if (this.last.fetch.action == 'delete') event_name = 'delete' + let edata = this.trigger(event_name, { target: this.name, error, data, lastFetch: this.last.fetch }) + if (edata.isCancelled === true) { + reject() + return + } + // parse server response + if (!error) { + // default action + if (typeof this.parser == 'function') { + data = this.parser(data) + if (typeof data != 'object') { + console.log('ERROR: Your parser did not return proper object') + } + } else { + if (data == null) { + data = { + error: true, + message: w2utils.lang(this.msgNotJSON), + } + } else if (Array.isArray(data)) { + // if it is plain array, assume these are records + data = { + error, + records: data, + total: data.length + } + } + } + if (action == 'load') { + if (data.total == null) data.total = -1 + if (data.records == null) { + data.records = [] + } + if (data.records.length == this.limit) { + let loaded = this.records.length + data.records.length + this.last.fetch.hasMore = (loaded == this.total ? false : true) + } else { + this.last.fetch.hasMore = false + this.total = this.offset + this.last.fetch.offset + data.records.length + } + if (!this.last.fetch.hasMore) { + // if no more records, then hide spinner + query(this.box).find('#grid_'+ this.name +'_rec_more, #grid_'+ this.name +'_frec_more').hide() + } + if (this.last.fetch.offset === 0) { + this.records = [] + this.summary = [] + } else { + if (data.total != -1 && parseInt(data.total) != parseInt(this.total)) { + let grid = this + this.message(w2utils.lang(this.msgNeedReload)) + .ok(() => { + delete grid.last.fetch.offset + grid.reload() + }) + return new Promise(resolve => { resolve() }) + } + } + if (w2utils.isInt(data.total)) this.total = parseInt(data.total) + // records + if (data.records) { + data.records.forEach(rec => { + if (this.recid) { + rec.recid = this.parseField(rec, this.recid) + } + if (rec.recid == null) { + rec.recid = 'recid-' + this.records.length + } + if (rec.w2ui?.summary === true) { + this.summary.push(rec) + } else { + this.records.push(rec) + } + }) + } + // summary records (if any) + if (data.summary) { + this.summary = [] // reset summary with each call + data.summary.forEach(rec => { + if (this.recid) { + rec.recid = this.parseField(rec, this.recid) + } + if (rec.recid == null) { + rec.recid = 'recid-' + this.summary.length + } + this.summary.push(rec) + }) + } + } else if (action == 'delete') { + this.reset() // unselect old selections + return this.reload() + } + } else { + this.error(w2utils.lang(data.message ?? this.msgServerError)) + reject(data) + } + // event after + let url = this.url?.get ?? this.url + if (!url) { + this.localSort() + this.localSearch() + } + this.total = parseInt(this.total) + // do not refresh if loading on infinite scroll + if (this.last.fetch.offset === 0) { + this.refresh() + } else { + this.scroll() + this.resize() + } + // call back + if (typeof callBack == 'function') callBack(data) // need to be before event:after + resolve(data) + // after event + edata.finish() + this.last.fetch.loaded = true + } + error(msg) { + // let the management of the error outside of the grid + let edata = this.trigger('error', { target: this.name, message: msg }) + if (edata.isCancelled === true) { + return + } + this.message(msg) + // event after + edata.finish() + } + getChanges(recordsBase) { + let changes = [] + if (typeof recordsBase == 'undefined') { + recordsBase = this.records + } + for (let r = 0; r < recordsBase.length; r++) { + let rec = recordsBase[r] + if (rec?.w2ui) { + if (rec.w2ui.changes != null) { + let obj = {} + obj[this.recid || 'recid'] = rec.recid + changes.push(w2utils.extend(obj, rec.w2ui.changes)) + } + // recursively look for changes in non-expanded children + if (rec.w2ui.expanded !== true && rec.w2ui.children && rec.w2ui.children.length) { + changes.push(...this.getChanges(rec.w2ui.children)) + } + } + } + return changes + } + mergeChanges() { + let changes = this.getChanges() + for (let c = 0; c < changes.length; c++) { + let record = this.get(changes[c][this.recid || 'recid']) + for (let s in changes[c]) { + if (s == 'recid' || (this.recid && s == this.recid)) continue // do not allow to change recid + if (typeof changes[c][s] === 'object') changes[c][s] = changes[c][s].text + try { + _setValue(record, s, changes[c][s]) + } catch (e) { + console.log('ERROR: Cannot merge. ', e.message || '', e) + } + if (record.w2ui) delete record.w2ui.changes + } + } + this.refresh() + function _setValue(obj, field, value) { + let fld = field.split('.') + if (fld.length == 1) { + obj[field] = value + } else { + obj = obj[fld[0]] + fld.shift() + _setValue(obj, fld.join('.'), value) + } + } + } + save(callBack) { + let changes = this.getChanges() + let url = this.url?.save ?? this.url + // event before + let edata = this.trigger('save', { target: this.name, changes: changes }) + if (edata.isCancelled === true) return + if (url) { + this.request('save', { 'changes' : edata.detail.changes }, null, + (data) => { + if (!data.error) { + // only merge changes, if save was successful + this.mergeChanges() + } + // event after + edata.finish() + // call back + if (typeof callBack == 'function') callBack(data) + } + ) + } else { + this.mergeChanges() + // event after + edata.finish() + } + } + editField(recid, column, value, event) { + let self = this + if (this.last.inEditMode === true) { + // This is triggerign when user types fast + if (event && event.keyCode == 13) { + let { index, column, value } = this.last._edit + this.editChange({ type: 'custom', value }, index, column, event) + this.editDone(index, column, event) + } else { + // when 2 chars entered fast (spreadsheet) + let input = query(this.box).find('div.w2ui-edit-box .w2ui-input') + if (input.length > 0) { + if (input.get(0).tagName == 'DIV') { + input.text(input.text() + value) + w2utils.setCursorPosition(input.get(0), input.text().length) + } else { + input.val(input.val() + value) + w2utils.setCursorPosition(input.get(0), input.val().length) + } + } + } + return + } + let index = this.get(recid, true) + let edit = this.getCellEditable(index, column) + if (!edit || ['checkbox', 'check'].includes(edit.type)) return + let rec = this.records[index] + let col = this.columns[column] + let prefix = (col.frozen === true ? '_f' : '_') + if (['enum', 'file'].indexOf(edit.type) != -1) { + console.log('ERROR: input types "enum" and "file" are not supported in inline editing.') + return + } + // event before + let edata = this.trigger('editField', { target: this.name, recid, column, value, index, originalEvent: event }) + if (edata.isCancelled === true) return + value = edata.detail.value + // default behaviour + this.last.inEditMode = true + this.last.editColumn = column + this.last._edit = { value: value, index: index, column: column, recid: recid } + this.selectNone(true) // no need to trigger select event + this.select({ recid: recid, column: column }) + // create input element + let tr = query(this.box).find('#grid_'+ this.name + prefix +'rec_' + w2utils.escapeId(recid)) + let div = tr.find('[col="'+ column +'"] > div') // TD -> DIV + this.last._edit.tr = tr + this.last._edit.div = div + // clear previous if any (spreadsheet) + query(this.box).find('div.w2ui-edit-box').remove() + // for spreadsheet - insert into selection + if (this.selectType != 'row') { + query(this.box).find('#grid_'+ this.name + prefix + 'selection') + .attr('id', 'grid_'+ this.name + '_editable') + .removeClass('w2ui-selection') + .addClass('w2ui-edit-box') + .prepend('
    ') + .find('.w2ui-selection-resizer') + .remove() + div = query(this.box).find('#grid_'+ this.name + '_editable > div:first-child') + } + edit.attr = edit.attr ?? '' + edit.text = edit.text ?? '' + edit.style = edit.style ?? '' + edit.items = edit.items ?? [] + let val = (rec.w2ui?.changes?.[col.field] != null + ? w2utils.stripTags(rec.w2ui.changes[col.field]) + : w2utils.stripTags(self.parseField(rec, col.field))) + if (val == null) val = '' + let prevValue = (typeof val != 'object' ? val : '') + if (edata.detail.prevValue != null) prevValue = edata.detail.prevValue + if (value != null) val = value + let addStyle = (col.style != null ? col.style + ';' : '') + if (typeof col.render == 'string' + && ['number', 'int', 'float', 'money', 'percent', 'size'].includes(col.render.split(':')[0])) { + addStyle += 'text-align: right;' + } + // normalize items, if not yet normlized + if (edit.items.length > 0 && !w2utils.isPlainObject(edit.items[0])) { + edit.items = w2utils.normMenu(edit.items) + } + let input + let dropTypes = ['date', 'time', 'datetime', 'color', 'list', 'combo'] + let styles = getComputedStyle(tr.find('[col="'+ column +'"] > div').get(0)) + let font = `font-family: ${styles['font-family']}; font-size: ${styles['font-size']};` + switch (edit.type) { + case 'div': { + div.addClass('w2ui-editable') + .html(w2utils.stripSpaces(`
    +
    ${edit.text}`)) + input = div.find('div.w2ui-input').get(0) + input.innerText = (typeof val != 'object' ? val : '') + if (value != null) { + w2utils.setCursorPosition(input, input.innerText.length) + } else { + w2utils.setCursorPosition(input, 0, input.innerText.length) + } + break + } + default: { + div.addClass('w2ui-editable') + .html(w2utils.stripSpaces(`${edit.text}`)) + input = div.find('input').get(0) + // issue #499 + if (edit.type == 'number') { + val = w2utils.formatNumber(val) + } + if (edit.type == 'date') { + val = w2utils.formatDate(w2utils.isDate(val, edit.format, true) || new Date(), edit.format) + } + input.value = (typeof val != 'object' ? val : '') + // init w2field, attached to input._w2field + let doHide = (event) => { + let escKey = this.last._edit?.escKey + // check if any element is selected in drop down + let selected = false + let name = query(input).data('tooltipName') + if (name && w2tooltip.get(name[0])?.selected != null) { + selected = true + } + // trigger change on new value if selected from overlay + if (this.last.inEditMode && !escKey && dropTypes.includes(edit.type) // drop down types + && (event.detail.overlay.anchor?.id == this.last._edit.input?.id || edit.type == 'list')) { + this.editChange() + this.editDone(undefined, undefined, { keyCode: selected ? 13 : 0 }) // advance on select + } + } + new w2field(w2utils.extend({}, edit, { + el: input, + selected: val, + onSelect: doHide, + onHide: doHide + })) + if (value == null && input) { + // if no new value, then select content + input.select() + } + } + } + Object.assign(this.last._edit, { input, edit }) + query(input) + .off('.w2ui-editable') + .on('blur.w2ui-editable', (event) => { + if (this.last.inEditMode) { + let type = this.last._edit.edit.type + let name = query(input).data('tooltipName') // if popup is open + if (dropTypes.includes(type) && name) { + // drop downs finish edit when popover is closed + return + } + this.editChange(input, index, column, event) + this.editDone() + } + }) + .on('mousedown.w2ui-editable', (event) => { + event.stopPropagation() + }) + .on('click.w2ui-editable', (event) => { + expand.call(input, event) + }) + .on('paste.w2ui-editable', (event) => { + // clean paste to be plain text + event.preventDefault() + let text = event.clipboardData.getData('text/plain') + document.execCommand('insertHTML', false, text) + }) + .on('keyup.w2ui-editable', (event) => { + expand.call(input, event) + }) + .on('keydown.w2ui-editable', (event) => { + switch (event.keyCode) { + case 8: // backspace; + if (edit.type == 'list' && !input._w2field) { // cancel backspace when deleting element + event.preventDefault() + } + break + case 9: + case 13: + event.preventDefault() + break + case 27: // esc button exits edit mode, but if in a popup, it will also close the popup, hence + // if tooltip is open - hide it + let name = query(input).data('tooltipName') + if (name && name.length > 0) { + this.last._edit.escKey = true + w2tooltip.hide(name[0]) + event.preventDefault() + } + event.stopPropagation() + break + } + // need timeout so, this handler is executed after key is processed by browser + setTimeout(() => { + switch (event.keyCode) { + case 9: { // tab + let next = event.shiftKey + ? self.prevCell(index, column, true) + : self.nextCell(index, column, true) + if (next != null) { + let recid = self.records[next.index].recid + this.editChange(input, index, column, event) + this.editDone(index, column, event) + if (self.selectType != 'row') { + self.selectNone(true) // no need to trigger select event + self.select({ recid, column: next.colIndex }) + } else { + self.editField(recid, next.colIndex, null, event) + } + if (event.preventDefault) event.preventDefault() + } + break + } + case 13: { // enter + // check if any element is selected in drop down + let selected = false + let name = query(input).data('tooltipName') + if (name && w2tooltip.get(name[0]).selected != null) { + selected = true + } + // if tooltip is not open or no element is selected + if (!name || !selected) { + this.editChange(input, index, column, event) + this.editDone(index, column, event) + } + break + } + case 27: { // escape + this.last._edit.escKey = false + let old = self.parseField(rec, col.field) + if (rec.w2ui?.changes?.[col.field] != null) old = rec.w2ui.changes[col.field] + if (input._prevValue != null) old = input._prevValue + if (input.tagName == 'DIV') { + input.innerText = old != null ? old : '' + } else { + input.value = old != null ? old : '' + } + this.editDone(index, column, event) + setTimeout(() => { self.select({ recid: recid, column: column }) }, 1) + break + } + } + // if input too small - expand + expand(input) + }, 1) + }) + // save previous value + if (input) input._prevValue = prevValue + // focus and select + if (edit.type != 'list') { + setTimeout(() => { + if (!this.last.inEditMode) return + if (input) { + input.focus() + clearTimeout(this.last.kbd_timer) // keep focus + input.resize = expand + expand(input) + } + }, 50) + } + // event after + edata.finish({ input }) + return + function expand(input) { + try { + let styles = getComputedStyle(input) + let val = (input.tagName.toUpperCase() == 'DIV' ? input.innerText : input.value) + let editBox = query(self.box).find('#grid_'+ self.name + '_editable').get(0) + let style = `font-family: ${styles['font-family']}; font-size: ${styles['font-size']}; white-space: no-wrap;` + let width = w2utils.getStrWidth(val, style) + if (width + 20 > editBox.clientWidth) { + query(editBox).css('width', width + 20 + 'px') + } + } catch (e) { + } + } + } + editChange(input, index, column, event) { + // if params are not specified + input = input ?? this.last._edit.input + index = index ?? this.last._edit.index + column = column ?? this.last._edit.column + event = event ?? {} + // all other fields + let summary = index < 0 + index = index < 0 ? -index - 1 : index + let records = summary ? this.summary : this.records + let rec = records[index] + let col = this.columns[column] + let new_val = (input?.tagName == 'DIV' ? input.innerText : input.value) + let fld = input._w2field + if (fld) { + if (fld.type == 'list') { + new_val = fld.selected + } + if (Object.keys(new_val).length === 0 || new_val == null) new_val = '' + if (!w2utils.isPlainObject(new_val)) new_val = fld.clean(new_val) + } + if (input.type == 'checkbox') { + if (rec.w2ui?.editable === false) input.checked = !input.checked + new_val = input.checked + } + let old_val = this.parseField(rec, col.field) + let prev_val = (rec.w2ui?.changes && rec.w2ui.changes.hasOwnProperty(col.field) ? rec.w2ui.changes[col.field]: old_val) + // change/restore event + let edata = { + target: this.name, input, + recid: rec.recid, index, column, + originalEvent: event, + value: { + new: new_val, + previous: prev_val, + original: old_val, + } + } + if (event.target?._prevValue != null) edata.value.previous = event.target._prevValue + let count = 0 // just in case to avoid infinite loop + while (count < 20) { + count++ + new_val = edata.value.new + if ((typeof new_val != 'object' && String(old_val) != String(new_val)) || + (typeof new_val == 'object' && new_val && new_val.id != old_val + && (typeof old_val != 'object' || old_val == null || new_val.id != old_val.id))) { + // change event + edata = this.trigger('change', edata) + if (edata.isCancelled !== true) { + if (new_val !== edata.detail.value.new) { + // re-evaluate the type of change to be made + continue + } + // default action + if ((edata.detail.value.new === '' || edata.detail.value.new == null) && (prev_val === '' || prev_val == null)) { + // value did not change, was empty is empty + } else { + rec.w2ui = rec.w2ui ?? {} + rec.w2ui.changes = rec.w2ui.changes ?? {} + rec.w2ui.changes[col.field] = edata.detail.value.new + } + // event after + edata.finish() + } + } else { + // restore event + edata = this.trigger('restore', edata) + if (edata.isCancelled !== true) { + if (new_val !== edata.detail.value.new) { + // re-evaluate the type of change to be made + continue + } + // default action + if (rec.w2ui?.changes) { + delete rec.w2ui.changes[col.field] + if (Object.keys(rec.w2ui.changes).length === 0) { + delete rec.w2ui.changes + } + } + // event after + edata.finish() + } + } + break + } + } + editDone(index, column, event) { + // if params are not specified + index = index ?? this.last._edit.index + column = column ?? this.last._edit.column + event = event ?? {} + // removal of input happens when TR is redrawn + if (this.advanceOnEdit && event.keyCode == 13) { + let next = event.shiftKey ? this.prevRow(index, column, 1) : this.nextRow(index, column, 1) + if (next == null) next = index // keep the same + setTimeout(() => { + if (this.selectType != 'row') { + this.selectNone(true) // no need to trigger select event + this.select({ recid: this.records[next].recid, column: column }) + } else { + this.editField(this.records[next].recid, column, null, event) + } + }, 1) + } + let summary = index < 0 + let cell = query(this.last._edit.tr).find('[col="'+ column +'"]') + let rec = this.records[index] + let col = this.columns[column] + // need to set before remove, as remove will trigger blur + this.last.inEditMode = false + this.last._edit = null + // remove - by updating cell data + if (!summary) { + if (rec.w2ui?.changes?.[col.field] != null) { + cell.addClass('w2ui-changed') + } else { + cell.removeClass('w2ui-changed') + } + cell.replace(this.getCellHTML(index, column, summary)) + } + // remove - spreadsheet + query(this.box).find('div.w2ui-edit-box').remove() + // update toolbar buttons + this.updateToolbar() + // keep grid in focus if needed + setTimeout(() => { + let input = query(this.box).find(`#grid_${this.name}_focus`).get(0) + if (document.activeElement !== input && !this.last.inEditMode) { + input.focus() + } + }, 10) + } + 'delete'(force) { + // event before + let edata = this.trigger('delete', { target: this.name, force: force }) + if (force) this.message() // close message + if (edata.isCancelled === true) return + force = edata.detail.force + // default action + let recs = this.getSelection() + if (recs.length === 0) return + if (this.msgDelete != '' && !force) { + this.confirm({ + text: w2utils.lang(this.msgDelete, { + count: recs.length, + records: w2utils.lang( recs.length == 1 ? 'record' : 'records') + }), + width: 380, + height: 170, + yes_text: w2utils.lang('Delete'), + yes_class: 'w2ui-btn-red', + no_text: w2utils.lang('Cancel'), + }) + .yes(event => { + event.detail.self.close() + this.delete(true) + }) + .no(event => { + event.detail.self.close() + }) + return + } + // call delete script + let url = (typeof this.url != 'object' ? this.url : this.url.remove) + if (url) { + this.request('delete') + } else { + if (typeof recs[0] != 'object') { + this.selectNone() + this.remove.apply(this, recs) + } else { + // clear cells + for (let r = 0; r < recs.length; r++) { + let fld = this.columns[recs[r].column].field + let ind = this.get(recs[r].recid, true) + let rec = this.records[ind] + if (ind != null && fld != 'recid') { + this.records[ind][fld] = '' + if (rec.w2ui?.changes) delete rec.w2ui.changes[fld] + // -- style should not be deleted + // if (rec.style != null && w2utils.isPlainObject(rec.style) && rec.style[recs[r].column]) { + // delete rec.style[recs[r].column]; + // } + } + } + this.update() + } + } + // event after + edata.finish() + } + click(recid, event) { + let time = Date.now() + let column = null + if (this.last.cancelClick == true || (event && event.altKey)) return + if ((typeof recid == 'object') && (recid !== null)) { + column = recid.column + recid = recid.recid + } + if (event == null) event = {} + // check for double click + if (time - parseInt(this.last.click_time) < 350 && this.last.click_recid == recid && event.type == 'click') { + this.dblClick(recid, event) + return + } + // hide bubble + if (this.last.bubbleEl) { + this.last.bubbleEl = null + } + this.last.click_time = time + let last_recid = this.last.click_recid + this.last.click_recid = recid + // column user clicked on + if (column == null && event.target) { + let trg = event.target + if (trg.tagName != 'TD') trg = query(trg).closest('td')[0] + if (query(trg).attr('col') != null) column = parseInt(query(trg).attr('col')) + } + // event before + let edata = this.trigger('click', { target: this.name, recid, column, originalEvent: event }) + if (edata.isCancelled === true) return + // default action + let sel = this.getSelection() + query(this.box).find('#grid_'+ this.name +'_check_all').prop('checked', false) + let ind = this.get(recid, true) + let selectColumns = [] + this.last.sel_ind = ind + this.last.sel_col = column + this.last.sel_recid = recid + this.last.sel_type = 'click' + // multi select with shift key + let start, end, t1, t2 + if (event.shiftKey && sel.length > 0 && this.multiSelect) { + if (sel[0].recid) { + start = this.get(sel[0].recid, true) + end = this.get(recid, true) + if (column > sel[0].column) { + t1 = sel[0].column + t2 = column + } else { + t1 = column + t2 = sel[0].column + } + for (let c = t1; c <= t2; c++) selectColumns.push(c) + } else { + start = this.get(last_recid, true) + end = this.get(recid, true) + } + let sel_add = [] + if (start > end) { let tmp = start; start = end; end = tmp } + let url = this.url?.get ? this.url.get : this.url + for (let i = start; i <= end; i++) { + if (this.searchData.length > 0 && !url && !this.last.searchIds.includes(i)) continue + if (this.selectType == 'row') { + sel_add.push(this.records[i].recid) + } else { + for (let sc = 0; sc < selectColumns.length; sc++) { + sel_add.push({ recid: this.records[i].recid, column: selectColumns[sc] }) + } + } + //sel.push(this.records[i].recid); + } + this.select(sel_add) + } else { + let last = this.last.selection + let flag = (last.indexes.indexOf(ind) != -1 ? true : false) + let fselect = false + // if clicked on the checkbox + if (query(event.target).closest('td').hasClass('w2ui-col-select')) fselect = true + // clear other if necessary + if (((!event.ctrlKey && !event.shiftKey && !event.metaKey && !fselect) || !this.multiSelect) && !this.showSelectColumn) { + if (this.selectType != 'row' && !last.columns[ind]?.includes(column)) flag = false + this.selectNone(true) // no need to trigger select event + if (flag === true && sel.length == 1) { + this.unselect({ recid: recid, column: column }) + } else { + this.select({ recid: recid, column: column }) + } + } else { + if (this.selectType != 'row' && !last.columns[ind]?.includes(column)) flag = false + if (flag === true) { + this.unselect({ recid: recid, column: column }) + } else { + this.select({ recid: recid, column: column }) + } + } + } + this.status() + this.initResize() + // event after + edata.finish() + } + columnClick(field, event) { + // ignore click if column was resized + if (this.last.colResizing === true) { + return + } + // event before + let edata = this.trigger('columnClick', { target: this.name, field: field, originalEvent: event }) + if (edata.isCancelled === true) return + // default behaviour + if (this.selectType == 'row') { + let column = this.getColumn(field) + if (column && column.sortable) this.sort(field, null, (event && (event.ctrlKey || event.metaKey) ? true : false)) + if (edata.detail.field == 'line-number') { + if (this.getSelection().length >= this.records.length) { + this.selectNone() + } else { + this.selectAll() + } + } + } else { + if (event.altKey){ + let column = this.getColumn(field) + if (column && column.sortable) this.sort(field, null, (event && (event.ctrlKey || event.metaKey) ? true : false)) + } + // select entire column + if (edata.detail.field == 'line-number') { + if (this.getSelection().length >= this.records.length) { + this.selectNone() + } else { + this.selectAll() + } + } else { + if (!event.shiftKey && !event.metaKey && !event.ctrlKey) { + this.selectNone(true) + } + let tmp = this.getSelection() + let column = this.getColumn(edata.detail.field, true) + let sel = [] + let cols = [] + // check if there was a selection before + if (tmp.length != 0 && event.shiftKey) { + let start = column + let end = tmp[0].column + if (start > end) { + start = tmp[0].column + end = column + } + for (let i = start; i<=end; i++) cols.push(i) + } else { + cols.push(column) + } + edata = this.trigger('columnSelect', { target: this.name, columns: cols }) + if (edata.isCancelled !== true) { + for (let i = 0; i < this.records.length; i++) { + sel.push({ recid: this.records[i].recid, column: cols }) + } + this.select(sel) + } + edata.finish() + } + } + // event after + edata.finish() + } + columnDblClick(field, event) { + // event before + let edata = this.trigger('columnDblClick', { target: this.name, field: field, originalEvent: event }) + if (edata.isCancelled === true) return + // event after + edata.finish() + } + columnContextMenu(field, event) { + let edata = this.trigger('columnContextMenu', {target: this.name, field: field, originalEvent: event }) + if (edata.isCancelled === true) return + if (this.show.columnMenu) { + w2menu.show({ + type: 'check', + anchor: document.body, + originalEvent: event, + items: this.initColumnOnOff() + }) + .then(() => { + query('#w2overlay-context-menu .w2ui-grid-skip') + .off('.w2ui-grid') + .on('click.w2ui-grid', evt => { + evt.stopPropagation() + }) + .on('keypress', evt => { + if (evt.keyCode == 13) { + this.skip(evt.target.value) + this.toolbar.click('w2ui-column-on-off') // close menu + } + }) + }) + .select((event) => { + let id = event.detail.item.id + if (['w2ui-stateSave', 'w2ui-stateReset'].includes(id)) { + this[id.substring(5)]() + } else if (id == 'w2ui-skip') { + // empty + } else { + this.columnOnOff(event, event.detail.item.id) + } + clearTimeout(this.last.kbd_timer) // keep grid in focus + }) + clearTimeout(this.last.kbd_timer) // keep grid in focus + } + event.preventDefault() + edata.finish() + } + focus(event) { + // event before + let edata = this.trigger('focus', { target: this.name, originalEvent: event }) + if (edata.isCancelled === true) return false + // default behaviour + this.hasFocus = true + query(this.box).removeClass('w2ui-inactive').find('.w2ui-inactive').removeClass('w2ui-inactive') + setTimeout(() => { + let txt = query(this.box).find(`#grid_${this.name}_focus`).get(0) + if (txt && document.activeElement != txt) { + txt.focus() + } + }, 10) + // event after + edata.finish() + } + blur(event) { + // event before + let edata = this.trigger('blur', { target: this.name, originalEvent: event }) + if (edata.isCancelled === true) return false + // default behaviour + this.hasFocus = false + query(this.box).addClass('w2ui-inactive').find('.w2ui-selected').addClass('w2ui-inactive') + query(this.box).find('.w2ui-selection').addClass('w2ui-inactive') + // event after + edata.finish() + } + keydown(event) { + // this method is called from w2utils + let obj = this + let url = (typeof this.url != 'object' ? this.url : this.url.get) + if (obj.keyboard !== true) return + // trigger event + let edata = obj.trigger('keydown', { target: obj.name, originalEvent: event }) + if (edata.isCancelled === true) return + // default behavior + if (query(this.box).find('.w2ui-message').length > 0) { + // if there are messages + if (event.keyCode == 27) this.message() + return + } + let empty = false + let records = query(obj.box).find('#grid_'+ obj.name +'_records') + let sel = obj.getSelection() + if (sel.length === 0) empty = true + let recid = sel[0] || null + let columns = [] + let recid2 = sel[sel.length-1] + if (typeof recid == 'object' && recid != null) { + recid = sel[0].recid + columns = [] + let ii = 0 + while (true) { + if (!sel[ii] || sel[ii].recid != recid) break + columns.push(sel[ii].column) + ii++ + } + recid2 = sel[sel.length-1].recid + } + let ind = obj.get(recid, true) + let ind2 = obj.get(recid2, true) + let recEL = query(obj.box).find(`#grid_${obj.name}_rec_${(ind != null ? w2utils.escapeId(obj.records[ind].recid) : 'none')}`) + let pageSize = Math.floor(records[0].clientHeight / obj.recordHeight) + let cancel = false + let key = event.keyCode + let shiftKey = event.shiftKey + switch (key) { + case 8: // backspace + case 46: // delete + // delete if button is visible + obj.delete() + cancel = true + event.stopPropagation() + break + case 27: // escape + obj.selectNone() + cancel = true + break + case 65: // cmd + A + if (!event.metaKey && !event.ctrlKey) break + obj.selectAll() + cancel = true + break + case 13: // enter + // if expandable columns - expand it + if (this.selectType == 'row' && obj.show.expandColumn === true) { + if (recEL.length <= 0) break + obj.toggle(recid, event) + cancel = true + } else { // or enter edit + for (let c = 0; c < this.columns.length; c++) { + let edit = this.getCellEditable(ind, c) + if (edit) { + columns.push(parseInt(c)) + break + } + } + // edit last column that was edited + if (this.selectType == 'row' && this.last._edit && this.last._edit.column) { + columns = [this.last._edit.column] + } + if (columns.length > 0) { + obj.editField(recid, this.last.editColumn || columns[0], null, event) + cancel = true + } + } + break + case 37: // left + moveLeft() + break + case 39: // right + moveRight() + break + case 33: // + moveUp(pageSize) + break + case 34: // + moveDown(pageSize) + break + case 35: // + moveDown(-1) + break + case 36: // + moveUp(-1) + break + case 38: // up + // ctrl (or cmd) + up -> same as home + moveUp(event.metaKey || event.ctrlKey ? -1 : 1) + break + case 40: // down + // ctrl (or cmd) + up -> same as end + moveDown(event.metaKey || event.ctrlKey ? -1 : 1) + break + // copy & paste + case 17: // ctrl key + case 91: // cmd key + // SLOW: 10k records take 7.0 + if (empty) break + // in Safari need to copy to buffer on cmd or ctrl key (otherwise does not work) + if (w2utils.isSafari) { + obj.last.copy_event = obj.copy(false, event) + let focus = query(obj.box).find('#grid_'+ obj.name + '_focus') + focus.val(obj.last.copy_event.detail.text) + focus[0].select() + } + break + case 67: // - c + // this fill trigger event.onComplete + if (event.metaKey || event.ctrlKey) { + if (w2utils.isSafari) { + obj.copy(obj.last.copy_event, event) + } else { + obj.last.copy_event = obj.copy(false, event) + let focus = query(obj.box).find('#grid_'+ obj.name + '_focus') + focus.val(obj.last.copy_event.detail.text) + focus[0].select() + obj.copy(obj.last.copy_event, event) + } + } + break + case 88: // x - cut + if (empty) break + if (event.ctrlKey || event.metaKey) { + if (w2utils.isSafari) { + obj.copy(obj.last.copy_event, event) + } else { + obj.last.copy_event = obj.copy(false, event) + let focus = query(obj.box).find('#grid_'+ obj.name + '_focus') + focus.val(obj.last.copy_event.detail.text) + focus[0].select() + obj.copy(obj.last.copy_event, event) + } + } + break + } + let tmp = [32, 187, 189, 192, 219, 220, 221, 186, 222, 188, 190, 191] // other typeable chars + for (let i = 48; i <= 111; i++) tmp.push(i) // 0-9,a-z,A-Z,numpad + if (tmp.indexOf(key) != -1 && !event.ctrlKey && !event.metaKey && !cancel) { + if (columns.length === 0) columns.push(0) + cancel = false + // move typed key into edit + setTimeout(() => { + let focus = query(obj.box).find('#grid_'+ obj.name + '_focus') + let key = focus.val() + focus.val('') + obj.editField(recid, columns[0], key, event) + }, 1) + } + if (cancel) { // cancel default behaviour + if (event.preventDefault) event.preventDefault() + } + // event after + edata.finish() + function moveLeft() { + if (empty) { // no selection + selectTopRecord() + return + } + if (obj.selectType == 'row') { + if (recEL.length <= 0) return + let tmp = obj.records[ind].w2ui || {} + if (tmp && tmp.parent_recid != null && (!Array.isArray(tmp.children) || tmp.children.length === 0 || !tmp.expanded)) { + obj.unselect(recid) + obj.collapse(tmp.parent_recid, event) + obj.select(tmp.parent_recid) + } else { + obj.collapse(recid, event) + } + } else { + let prev = obj.prevCell(ind, columns[0]) + if (prev?.index != ind) { + prev = null + } else { + prev = prev?.colIndex + } + if (!shiftKey && prev == null) { + obj.selectNone(true) + prev = 0 + } + if (prev != null) { + if (shiftKey && obj.multiSelect) { + if (tmpUnselect()) return + let tmp = [] + let newSel = [] + let unSel = [] + if (columns.indexOf(obj.last.sel_col) === 0 && columns.length > 1) { + for (let i = 0; i < sel.length; i++) { + if (tmp.indexOf(sel[i].recid) == -1) tmp.push(sel[i].recid) + unSel.push({ recid: sel[i].recid, column: columns[columns.length-1] }) + } + obj.unselect(unSel) + obj.scrollIntoView(ind, columns[columns.length-1], true) + } else { + for (let i = 0; i < sel.length; i++) { + if (tmp.indexOf(sel[i].recid) == -1) tmp.push(sel[i].recid) + newSel.push({ recid: sel[i].recid, column: prev }) + } + obj.select(newSel) + obj.scrollIntoView(ind, prev, true) + } + } else { + obj.click({ recid: recid, column: prev }, event) + obj.scrollIntoView(ind, prev, true) + } + } else { + // if selected more then one, then select first + if (!shiftKey) { + obj.selectNone(true) + } + } + } + cancel = true + } + function moveRight() { + if (empty) { + selectTopRecord() + return + } + if (obj.selectType == 'row') { + if (recEL.length <= 0) return + obj.expand(recid, event) + } else { + let next = obj.nextCell(ind, columns[columns.length-1]) // columns is an array of selected columns + if (next.index != ind) { + next = null + } else { + next = next.colIndex + } + if (!shiftKey && next == null) { + obj.selectNone(true) + next = obj.columns.length-1 + } + if (next != null) { + if (shiftKey && key == 39 && obj.multiSelect) { + if (tmpUnselect()) return + let tmp = [] + let newSel = [] + let unSel = [] + if (columns.indexOf(obj.last.sel_col) == columns.length-1 && columns.length > 1) { + for (let i = 0; i < sel.length; i++) { + if (tmp.indexOf(sel[i].recid) == -1) tmp.push(sel[i].recid) + unSel.push({ recid: sel[i].recid, column: columns[0] }) + } + obj.unselect(unSel) + obj.scrollIntoView(ind, columns[0], true) + } else { + for (let i = 0; i < sel.length; i++) { + if (tmp.indexOf(sel[i].recid) == -1) tmp.push(sel[i].recid) + newSel.push({ recid: sel[i].recid, column: next }) + } + obj.select(newSel) + obj.scrollIntoView(ind, next, true) + } + } else { + obj.click({ recid: recid, column: next }, event) + obj.scrollIntoView(ind, next, true) + } + } else { + // if selected more then one, then select first + if (!shiftKey) { + obj.selectNone(true) + } + } + } + cancel = true + } + function moveUp(numRows) { + if (empty) selectTopRecord() + if (recEL.length <= 0) return + // move to the previous record + let prev = obj.prevRow(ind, obj.selectType == 'row' ? 0 : sel[0].column, numRows) + if (!shiftKey && prev == null) { + if (obj.searchData.length != 0 && !url) { + prev = obj.last.searchIds[0] + } else { + prev = 0 + } + } + if (prev != null) { + if (shiftKey && obj.multiSelect) { // expand selection + if (tmpUnselect()) return + if (obj.selectType == 'row') { + if (obj.last.sel_ind > prev && obj.last.sel_ind != ind2) { + obj.unselect(obj.records[ind2].recid) + } else { + obj.select(obj.records[prev].recid) + } + } else { + if (obj.last.sel_ind > prev && obj.last.sel_ind != ind2) { + prev = ind2 + let tmp = [] + for (let c = 0; c < columns.length; c++) tmp.push({ recid: obj.records[prev].recid, column: columns[c] }) + obj.unselect(tmp) + } else { + let tmp = [] + for (let c = 0; c < columns.length; c++) tmp.push({ recid: obj.records[prev].recid, column: columns[c] }) + obj.select(tmp) + } + } + } else { // move selected record + obj.selectNone(true) // no need to trigger select event + obj.click({ recid: obj.records[prev].recid, column: columns[0] }, event) + } + obj.scrollIntoView(prev, null, true, numRows != 1) // top align record + if (event.preventDefault) event.preventDefault() + } else { + // if selected more then one, then select first + if (!shiftKey) { + obj.selectNone(true) + } + } + } + function moveDown(numRows) { + if (empty) selectTopRecord() + if (recEL.length <= 0) return + // move to the next record + let next = obj.nextRow(ind2, obj.selectType == 'row' ? 0 : sel[0].column, numRows) + if (!shiftKey && next == null) { + if (obj.searchData.length != 0 && !url) { + next = obj.last.searchIds[obj.last.searchIds.length - 1] + } else { + next = obj.records.length - 1 + } + } + if (next != null) { + if (shiftKey && obj.multiSelect) { // expand selection + if (tmpUnselect()) return + if (obj.selectType == 'row') { + if (obj.last.sel_ind < next && obj.last.sel_ind != ind) { + obj.unselect(obj.records[ind].recid) + } else { + obj.select(obj.records[next].recid) + } + } else { + if (obj.last.sel_ind < next && obj.last.sel_ind != ind) { + next = ind + let tmp = [] + for (let c = 0; c < columns.length; c++) tmp.push({ recid: obj.records[next].recid, column: columns[c] }) + obj.unselect(tmp) + } else { + let tmp = [] + for (let c = 0; c < columns.length; c++) tmp.push({ recid: obj.records[next].recid, column: columns[c] }) + obj.select(tmp) + } + } + } else { // move selected record + obj.selectNone(true) // no need to trigger select event + obj.click({ recid: obj.records[next].recid, column: columns[0] }, event) + } + obj.scrollIntoView(next, null, true, numRows != 1) // top align record + cancel = true + } else { + // if selected more then one, then select first + if (!shiftKey) { + obj.selectNone(true) // no need to trigger select event + } + } + } + function selectTopRecord() { + if (!obj.records || obj.records.length === 0) return + let ind = Math.floor(records[0].scrollTop / obj.recordHeight) + 1 + if (!obj.records[ind] || ind < 2) ind = 0 + if (typeof obj.records[ind] === 'undefined') return + obj.select({ recid: obj.records[ind].recid, column: 0}) + } + function tmpUnselect () { + if (obj.last.sel_type != 'click') return false + if (obj.selectType != 'row') { + obj.last.sel_type = 'key' + if (sel.length > 1) { + for (let s = 0; s < sel.length; s++) { + if (sel[s].recid == obj.last.sel_recid && sel[s].column == obj.last.sel_col) { + sel.splice(s, 1) + break + } + } + obj.unselect(sel) + return true + } + return false + } else { + obj.last.sel_type = 'key' + if (sel.length > 1) { + sel.splice(sel.indexOf(obj.records[obj.last.sel_ind].recid), 1) + obj.unselect(sel) + return true + } + return false + } + } + } + scrollIntoView(ind, column, instant, recTop) { + let buffered = this.records.length + if (this.searchData.length != 0 && !this.url) buffered = this.last.searchIds.length + if (buffered === 0) return + if (ind == null) { + let sel = this.getSelection() + if (sel.length === 0) return + if (w2utils.isPlainObject(sel[0])) { + ind = sel[0].index + column = sel[0].column + } else { + ind = this.get(sel[0], true) + } + } + let records = query(this.box).find(`#grid_${this.name}_records`) + let recWidth = records[0].clientWidth + let recHeight = records[0].clientHeight + let recSTop = records[0].scrollTop + let recSLeft = records[0].scrollLeft + // if all records in view + let len = this.last.searchIds.length + if (len > 0) ind = this.last.searchIds.indexOf(ind) // if search is applied + // smooth or instant + records.css({ 'scroll-behavior': instant ? 'auto' : 'smooth' }) + // vertical + if (recHeight < this.recordHeight * (len > 0 ? len : buffered) && records.length > 0) { + // scroll to correct one + let t1 = Math.floor(recSTop / this.recordHeight) + let t2 = t1 + Math.floor(recHeight / this.recordHeight) + if (ind == t1) { + records.prop('scrollTop', recSTop - recHeight / 1.3) + } + if (ind == t2) { + records.prop('scrollTop', recSTop + recHeight / 1.3) + } + if (ind < t1 || ind > t2) { + records.prop('scrollTop', (ind - 1) * this.recordHeight) + } + if (recTop === true) { + records.prop('scrollTop', ind * this.recordHeight) + } + } + // horizontal + if (column != null) { + let x1 = 0 + let x2 = 0 + let sb = w2utils.scrollBarSize() + for (let i = 0; i <= column; i++) { + let col = this.columns[i] + if (col.frozen || col.hidden) continue + x1 = x2 + x2 += parseInt(col.sizeCalculated) + } + if (recWidth < x2 - recSLeft) { // right + records.prop('scrollLeft', x1 - sb) + } else if (x1 < recSLeft) { // left + records.prop('scrollLeft', x2 - recWidth + sb * 2) + } + } + } + scrollToColumn(field) { + if (field == null) + return + let sWidth = 0 + let found = false + for (let i = 0; i < this.columns.length; i++) { + let col = this.columns[i] + if (col.field == field) { + found = true + break + } + if (col.frozen || col.hidden) + continue + let cSize = parseInt(col.sizeCalculated ? col.sizeCalculated : col.size) + sWidth += cSize + } + if (!found) + return + this.last.scrollLeft = sWidth+1 + this.scroll() + } + + dblClick(recid, event) { + // find columns + let column = null + if ((typeof recid == 'object') && (recid !== null)) { + column = recid.column + recid = recid.recid + } + if (event == null) event = {} + // column user clicked on + if (column == null && event.target) { + let tmp = event.target + if (tmp.tagName.toUpperCase() != 'TD') tmp = query(tmp).closest('td')[0] + column = parseInt(query(tmp).attr('col')) + } + let index = this.get(recid, true) + let rec = this.records[index] + // event before + let edata = this.trigger('dblClick', { target: this.name, recid: recid, column: column, originalEvent: event }) + if (edata.isCancelled === true) return + // default action + this.selectNone(true) // no need to trigger select event + let edit = this.getCellEditable(index, column) + if (edit) { + this.editField(recid, column, null, event) + } else { + this.select({ recid: recid, column: column }) + if (this.show.expandColumn || (rec && rec.w2ui && Array.isArray(rec.w2ui.children))) this.toggle(recid) + } + // event after + edata.finish() + } + showContextMenu(recid, column, event) { + if (this.last.userSelect == 'text') return + if (event == null) { + event = { offsetX: 0, offsetY: 0, target: query(this.box).find(`#grid_${this.name}_rec_${recid}`)[0] } + } + if (event.offsetX == null) { + event.offsetX = event.layerX - event.target.offsetLeft + event.offsetY = event.layerY - event.target.offsetTop + } + if (w2utils.isFloat(recid)) recid = parseFloat(recid) + let sel = this.getSelection() + if (this.selectType == 'row') { + if (sel.indexOf(recid) == -1) this.click(recid) + } else { + let selected = false + // check if any selected sel in the right row/column + for (let i = 0; i < sel.length; i++) { + if (sel[i].recid == recid || sel[i].column == column) selected = true + } + if (!selected && recid != null) this.click({ recid: recid, column: column }) + if (!selected && column != null) this.columnClick(this.columns[column].field, event) + } + // event before + let edata = this.trigger('contextMenu', { target: this.name, originalEvent: event, recid, column }) + if (edata.isCancelled === true) return + // default action + if (this.contextMenu.length > 0) { + w2menu.show({ + anchor: document.body, + originalEvent: event, + items: this.contextMenu + }) + .select((event) => { + clearTimeout(this.last.kbd_timer) // keep grid in focus + this.contextMenuClick(recid, column, event) + }) + clearTimeout(this.last.kbd_timer) // keep grid in focus + } + // cancel browser context menu + event.preventDefault() + // event after + edata.finish() + } + contextMenuClick(recid, column, event) { + // event before + let edata = this.trigger('contextMenuClick', { + target: this.name, recid, column, originalEvent: event.detail.originalEvent, + menuEvent: event, menuIndex: event.detail.index, menuItem: event.detail.item + }) + if (edata.isCancelled === true) return + // no default action + edata.finish() + } + toggle(recid) { + let rec = this.get(recid) + if (rec == null) return + rec.w2ui = rec.w2ui ?? {} + if (rec.w2ui.expanded === true) return this.collapse(recid); else return this.expand(recid) + } + expand(recid, noRefresh) { + let ind = this.get(recid, true) + let rec = this.records[ind] + rec.w2ui = rec.w2ui ?? {} + let id = w2utils.escapeId(recid) + let children = rec.w2ui.children + let edata + if (Array.isArray(children)) { + if (rec.w2ui.expanded === true || children.length === 0) return false // already shown + edata = this.trigger('expand', { target: this.name, recid: recid }) + if (edata.isCancelled === true) return false + rec.w2ui.expanded = true + children.forEach((child) => { + child.w2ui = child.w2ui ?? {} + child.w2ui.parent_recid = rec.recid + if (child.w2ui.children == null) child.w2ui.children = [] + }) + this.records.splice.apply(this.records, [ind + 1, 0].concat(children)) + if (this.total !== -1) { + this.total += children.length + } + let url = (typeof this.url != 'object' ? this.url : this.url.get) + if (!url) { + this.localSort(true, true) + if (this.searchData.length > 0) { + this.localSearch(true) + } + } + if (noRefresh !== true) this.refresh() + edata.finish() + } else { + if (query(this.box).find('#grid_'+ this.name +'_rec_'+ id +'_expanded_row').length > 0 || this.show.expandColumn !== true) return false + if (rec.w2ui.expanded == 'none') return false + // insert expand row + query(this.box).find('#grid_'+ this.name +'_rec_'+ id).after( + ` + +
    + + + `) + query(this.box).find('#grid_'+ this.name +'_frec_'+ id).after( + ` + ${this.show.lineNumbers ? '' : ''} + +
    + + `) + // event before + edata = this.trigger('expand', { target: this.name, recid: recid, + box_id: 'grid_'+ this.name +'_rec_'+ recid +'_expanded', fbox_id: 'grid_'+ this.name +'_frec_'+ recid +'_expanded' }) + if (edata.isCancelled === true) { + query(this.box).find('#grid_'+ this.name +'_rec_'+ id +'_expanded_row').remove() + query(this.box).find('#grid_'+ this.name +'_frec_'+ id +'_expanded_row').remove() + return false + } + // expand column + let row1 = query(this.box).find('#grid_'+ this.name +'_rec_'+ recid +'_expanded') + let row2 = query(this.box).find('#grid_'+ this.name +'_frec_'+ recid +'_expanded') + let innerHeight = row1.find(':scope div:first-child')[0]?.clientHeight ?? 50 + if (row1[0].clientHeight < innerHeight) { + row1.css({ height: innerHeight + 'px' }) + } + if (row2[0].clientHeight < innerHeight) { + row2.css({ height: innerHeight + 'px' }) + } + // default action + query(this.box).find('#grid_'+ this.name +'_rec_'+ id).attr('expanded', 'yes').addClass('w2ui-expanded') + query(this.box).find('#grid_'+ this.name +'_frec_'+ id).attr('expanded', 'yes').addClass('w2ui-expanded') + query(this.box).find('#grid_'+ this.name +'_cell_'+ this.get(recid, true) +'_expand div').html('-') + rec.w2ui.expanded = true + // event after + edata.finish() + this.resizeRecords() + } + return true + } + collapse(recid, noRefresh) { + let ind = this.get(recid, true) + let rec = this.records[ind] + rec.w2ui = rec.w2ui || {} + let id = w2utils.escapeId(recid) + let children = rec.w2ui.children + let edata + if (Array.isArray(children)) { + if (rec.w2ui.expanded !== true) return false // already hidden + edata = this.trigger('collapse', { target: this.name, recid: recid }) + if (edata.isCancelled === true) return false + clearExpanded(rec) + let stops = [] + for (let r = rec; r != null; r = this.get(r.w2ui.parent_recid)) + stops.push(r.w2ui.parent_recid) + // stops contains 'undefined' plus the ID of all nodes in the path from 'rec' to the tree root + let start = ind + 1 + let end = start + while (true) { + if (this.records.length <= end + 1 || this.records[end+1].w2ui == null || + stops.indexOf(this.records[end+1].w2ui.parent_recid) >= 0) { + break + } + end++ + } + this.records.splice(start, end - start + 1) + if (this.total !== -1) { + this.total -= end - start + 1 + } + let url = (typeof this.url != 'object' ? this.url : this.url.get) + if (!url) { + if (this.searchData.length > 0) { + this.localSearch(true) + } + } + if (noRefresh !== true) this.refresh() + edata.finish() + } else { + if (query(this.box).find('#grid_'+ this.name +'_rec_'+ id +'_expanded_row').length === 0 || this.show.expandColumn !== true) return false + // event before + edata = this.trigger('collapse', { target: this.name, recid: recid, + box_id: 'grid_'+ this.name +'_rec_'+ recid +'_expanded', fbox_id: 'grid_'+ this.name +'_frec_'+ recid +'_expanded' }) + if (edata.isCancelled === true) return false + // default action + query(this.box).find('#grid_'+ this.name +'_rec_'+ id).removeAttr('expanded').removeClass('w2ui-expanded') + query(this.box).find('#grid_'+ this.name +'_frec_'+ id).removeAttr('expanded').removeClass('w2ui-expanded') + query(this.box).find('#grid_'+ this.name +'_cell_'+ this.get(recid, true) +'_expand div').html('+') + query(this.box).find('#grid_'+ this.name +'_rec_'+ id +'_expanded').css('height', '0px') + query(this.box).find('#grid_'+ this.name +'_frec_'+ id +'_expanded').css('height', '0px') + setTimeout(() => { + query(this.box).find('#grid_'+ this.name +'_rec_'+ id +'_expanded_row').remove() + query(this.box).find('#grid_'+ this.name +'_frec_'+ id +'_expanded_row').remove() + rec.w2ui.expanded = false + // event after + edata.finish() + this.resizeRecords() + }, 300) + } + return true + function clearExpanded(rec) { + rec.w2ui.expanded = false + for (let i = 0; i < rec.w2ui.children.length; i++) { + let subRec = rec.w2ui.children[i] + if (subRec.w2ui.expanded) { + clearExpanded(subRec) + } + } + } + } + sort(field, direction, multiField) { // if no params - clears sort + // event before + let edata = this.trigger('sort', { target: this.name, field: field, direction: direction, multiField: multiField }) + if (edata.isCancelled === true) return + // check if needed to quit + if (field != null) { + // default action + let sortIndex = this.sortData.length + for (let s = 0; s < this.sortData.length; s++) { + if (this.sortData[s].field == field) { sortIndex = s; break } + } + if (direction == null) { + if (this.sortData[sortIndex] == null) { + direction = 'asc' + } else { + if (this.sortData[sortIndex].direction == null) { + this.sortData[sortIndex].direction = '' + } + switch (this.sortData[sortIndex].direction.toLowerCase()) { + case 'asc' : direction = 'desc'; break + case 'desc' : direction = 'asc'; break + default : direction = 'asc'; break + } + } + } + if (this.multiSort === false) { this.sortData = []; sortIndex = 0 } + if (multiField != true) { this.sortData = []; sortIndex = 0 } + // set new sort + if (this.sortData[sortIndex] == null) this.sortData[sortIndex] = {} + this.sortData[sortIndex].field = field + this.sortData[sortIndex].direction = direction + } else { + this.sortData = [] + } + // if local + let url = (typeof this.url != 'object' ? this.url : this.url.get) + if (!url) { + this.localSort(false, true) + if (this.searchData.length > 0) this.localSearch(true) + // reset vertical scroll + this.last.scrollTop = 0 + query(this.box).find(`#grid_${this.name}_records`).prop('scrollTop', 0) + // event after + edata.finish({ direction }) + this.refresh() + } else { + // event after + edata.finish({ direction }) + this.last.fetch.offset = 0 + this.reload() + } + } + copy(flag, oEvent) { + if (w2utils.isPlainObject(flag)) { + // event after + flag.finish() + return flag.text + } + // generate text to copy + let sel = this.getSelection() + if (sel.length === 0) return '' + let text = '' + if (typeof sel[0] == 'object') { // cell copy + // find min/max column + let minCol = sel[0].column + let maxCol = sel[0].column + let recs = [] + for (let s = 0; s < sel.length; s++) { + if (sel[s].column < minCol) minCol = sel[s].column + if (sel[s].column > maxCol) maxCol = sel[s].column + if (recs.indexOf(sel[s].index) == -1) recs.push(sel[s].index) + } + recs.sort((a, b) => { return a-b }) // sort function must be for numerical sort + for (let r = 0 ; r < recs.length; r++) { + let ind = recs[r] + for (let c = minCol; c <= maxCol; c++) { + let col = this.columns[c] + if (col.hidden === true) continue + text += this.getCellCopy(ind, c) + '\t' + } + text = text.substr(0, text.length-1) // remove last \t + text += '\n' + } + } else { // row copy + // copy headers + for (let c = 0; c < this.columns.length; c++) { + let col = this.columns[c] + if (col.hidden === true) continue + let colName = (col.text ? col.text : col.field) + if (col.text && col.text.length < 3 && col.tooltip) colName = col.tooltip // if column name is less then 3 char and there is tooltip - use it + text += '"' + w2utils.stripTags(colName) + '"\t' + } + text = text.substr(0, text.length-1) // remove last \t + text += '\n' + // copy selected text + for (let s = 0; s < sel.length; s++) { + let ind = this.get(sel[s], true) + for (let c = 0; c < this.columns.length; c++) { + let col = this.columns[c] + if (col.hidden === true) continue + text += '"' + this.getCellCopy(ind, c) + '"\t' + } + text = text.substr(0, text.length-1) // remove last \t + text += '\n' + } + } + text = text.substr(0, text.length - 1) + // if called without params + let edata + if (flag == null) { + // before event + edata = this.trigger('copy', { target: this.name, text: text, + cut: (oEvent.keyCode == 88 ? true : false), originalEvent: oEvent }) + if (edata.isCancelled === true) return '' + text = edata.detail.text + // event after + edata.finish() + return text + } else if (flag === false) { // only before event + // before event + edata = this.trigger('copy', { target: this.name, text: text, + cut: (oEvent.keyCode == 88 ? true : false), originalEvent: oEvent }) + if (edata.isCancelled === true) return '' + text = edata.detail.text + return edata + } + } + /** + * Gets value to be copied to the clipboard + * @param ind index of the record + * @param col_ind index of the column + * @returns the displayed value of the field's record associated with the cell + */ + getCellCopy(ind, col_ind) { + return w2utils.stripTags(this.getCellHTML(ind, col_ind)) + } + paste(text, event) { + let sel = this.getSelection() + let ind = this.get(sel[0].recid, true) + let col = sel[0].column + // before event + let edata = this.trigger('paste', { target: this.name, text: text, index: ind, column: col, originalEvent: event }) + if (edata.isCancelled === true) return + text = edata.detail.text + // default action + if (this.selectType == 'row' || sel.length === 0) { + console.log('ERROR: You can paste only if grid.selectType = \'cell\' and when at least one cell selected.') + // event after + edata.finish() + return + } + if (typeof text !== 'object') { + let newSel = [] + text = text.split('\n') + for (let t = 0; t < text.length; t++) { + let tmp = text[t].split('\t') + let cnt = 0 + let rec = this.records[ind] + let cols = [] + if (rec == null) continue + for (let dt = 0; dt < tmp.length; dt++) { + if (!this.columns[col + cnt]) continue + setCellPaste(rec, this.columns[col + cnt].field, tmp[dt]) + cols.push(col + cnt) + cnt++ + } + for (let c = 0; c < cols.length; c++) newSel.push({ recid: rec.recid, column: cols[c] }) + ind++ + } + this.selectNone(true) // no need to trigger select event + this.select(newSel) + } else { + this.selectNone(true) // no need to trigger select event + this.select([{ recid: this.records[ind], column: col }]) + } + this.refresh() + // event after + edata.finish() + function setCellPaste(rec, field, paste) { + rec.w2ui = rec.w2ui ?? {} + rec.w2ui.changes = rec.w2ui.changes || {} + rec.w2ui.changes[field] = paste + } + } + // ================================================== + // --- Common functions + resize() { + let time = Date.now() + // make sure the box is right + if (!this.box || query(this.box).attr('name') != this.name) return + // event before + let edata = this.trigger('resize', { target: this.name }) + if (edata.isCancelled === true) return + // resize + this.resizeBoxes() + this.resizeRecords() + // event after + edata.finish() + return Date.now() - time + } + update({ cells, fullCellRefresh, ignoreColumns } = {}) { + let time = Date.now() + let self = this + if (this.box == null) return 0 + if (Array.isArray(cells)) { + for (let i = 0; i < cells.length; i++) { + let index = cells[i].index + let column = cells[i].column + if (index < 0) continue + if (index == null || column == null) { + console.log('ERROR: Wrong argument for grid.update({ cells }), cells should be [{ index: X, column: Y }, ...]') + continue + } + let rec = this.records[index] ?? {} + rec.w2ui = rec.w2ui ?? {} + rec.w2ui._update = rec.w2ui._update ?? { cells: [] } + let row1 = rec.w2ui._update.row1 + let row2 = rec.w2ui._update.row2 + if (row1 == null || !row1.isConnected || row2 == null || !row2.isColSelected) { + row1 = this.box.querySelector(`#grid_${this.name}_rec_${w2utils.escapeId(rec.recid)}`) + row2 = this.box.querySelector(`#grid_${this.name}_frec_${w2utils.escapeId(rec.recid)}`) + rec.w2ui._update.row1 = row1 + rec.w2ui._update.row2 = row2 + } + _update(rec, row1, row2, index, column) + } + } else { + for (let i = this.last.range_start-1; i <= this.last.range_end; i++) { + let index = i + if (this.last.searchIds.length > 0) { // if search is applied + index = this.last.searchIds[i] + } else { + index = i + } + let rec = this.records[index] + if (index < 0 || rec == null) continue + rec.w2ui = rec.w2ui ?? {} + rec.w2ui._update = rec.w2ui._update ?? { cells: [] } + let row1 = rec.w2ui._update.row1 + let row2 = rec.w2ui._update.row2 + if (row1 == null || !row1.isConnected || row2 == null || !row2.isColSelected) { + row1 = this.box.querySelector(`#grid_${this.name}_rec_${w2utils.escapeId(rec.recid)}`) + row2 = this.box.querySelector(`#grid_${this.name}_frec_${w2utils.escapeId(rec.recid)}`) + rec.w2ui._update.row1 = row1 + rec.w2ui._update.row2 = row2 + } + for (let column = 0; column < this.columns.length; column++) { + _update(rec, row1, row2, index, column) + } + } + } + return Date.now() - time + function _update(rec, row1, row2, index, column) { + let pcol = self.columns[column] + if (Array.isArray(ignoreColumns) && (ignoreColumns.includes(column) || ignoreColumns.includes(pcol.field))) { + return + } + let cell = rec.w2ui._update.cells[column] + if (cell == null || !cell.isConnected) { + cell = self.box.querySelector(`#grid_${self.name}_data_${index}_${column}`) + rec.w2ui._update.cells[column] = cell + } + if (cell == null) return + if (fullCellRefresh) { + query(cell).replace(self.getCellHTML(index, column, false)) + // need to reselect as it was replaced + cell = self.box.querySelector(`#grid_${self.name}_data_${index}_${column}`) + rec.w2ui._update.cells[column] = cell + } else { + let div = cell.children[0] // there is always a div inside a cell + // value, attr, style, className, divAttr -- all on TD level except divAttr + let { value, style, className } = self.getCellValue(index, column, false, true) + if (div.innerHTML != value) { + div.innerHTML = value + } + if (style != '' && cell.style.cssText != style) { + cell.style.cssText = style + } + if (className != '') { + let ignore = ['w2ui-grid-data'] + let remove = [] + let add = className.split(' ').filter(cl => !!cl) // remove empty + cell.classList.forEach(cl => { if (!ignore.includes(cl)) remove.push(cl)}) + cell.classList.remove(...remove) + cell.classList.add(...add) + } + } + // column styles if any (lower priority) + if (self.columns[column].style && self.columns[column].style != cell.style.cssText) { + cell.style.cssText = self.columns[column].style ?? '' + } + // record class if any + if (rec.w2ui.class != null) { + if (typeof rec.w2ui.class == 'string') { + let ignore = ['w2ui-odd', 'w2ui-even', 'w2ui-record'] + let remove = [] + let add = rec.w2ui.class.split(' ').filter(cl => !!cl) // remove empty + if (row1 && row2) { + row1.classList.forEach(cl => { if (!ignore.includes(cl)) remove.push(cl)}) + row1.classList.remove(...remove) + row1.classList.add(...add) + row2.classList.remove(...remove) + row2.classList.add(...add) + } + } + if (w2utils.isPlainObject(rec.w2ui.class) && typeof rec.w2ui.class[pcol.field] == 'string') { + let ignore = ['w2ui-grid-data'] + let remove = [] + let add = rec.w2ui.class[pcol.field].split(' ').filter(cl => !!cl) + cell.classList.forEach(cl => { if (!ignore.includes(cl)) remove.push(cl)}) + cell.classList.remove(...remove) + cell.classList.add(...add) + } + } + // record styles if any + if (rec.w2ui.style != null) { + if (row1 && row2 && typeof rec.w2ui.style == 'string' && row1.style.cssText !== rec.w2ui.style) { + row1.style.cssText = 'height: '+ self.recordHeight + 'px;' + rec.w2ui.style + row1.setAttribute('custom_style', rec.w2ui.style) + row2.style.cssText = 'height: '+ self.recordHeight + 'px;' + rec.w2ui.style + row2.setAttribute('custom_style', rec.w2ui.style) + } + if (w2utils.isPlainObject(rec.w2ui.style) && typeof rec.w2ui.style[pcol.field] == 'string' + && cell.style.cssText !== rec.w2ui.style[pcol.field]) { + cell.style.cssText = rec.w2ui.style[pcol.field] + } + } + } + } + refreshCell(recid, field) { + let index = this.get(recid, true) + let col_ind = this.getColumn(field, true) + let isSummary = (this.records[index] && this.records[index].recid == recid ? false : true) + let cell = query(this.box).find(`${isSummary ? '.w2ui-grid-summary ' : ''}#grid_${this.name}_data_${index}_${col_ind}`) + if (cell.length == 0) return false + // set cell html and changed flag + cell.replace(this.getCellHTML(index, col_ind, isSummary)) + return true + } + refreshRow(recid, ind = null) { + let tr1 = query(this.box).find('#grid_'+ this.name +'_frec_'+ w2utils.escapeId(recid)) + let tr2 = query(this.box).find('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)) + if (tr1.length > 0) { + if (ind == null) ind = this.get(recid, true) + let line = tr1.attr('line') + let isSummary = (this.records[ind] && this.records[ind].recid == recid ? false : true) + // if it is searched, find index in search array + let url = (typeof this.url != 'object' ? this.url : this.url.get) + if (this.searchData.length > 0 && !url) for (let s = 0; s < this.last.searchIds.length; s++) if (this.last.searchIds[s] == ind) ind = s + let rec_html = this.getRecordHTML(ind, line, isSummary) + tr1.replace(rec_html[0]) + tr2.replace(rec_html[1]) + // apply style to row if it was changed in render functions + let st = (this.records[ind].w2ui ? this.records[ind].w2ui.style : '') + if (typeof st == 'string') { + tr1 = query(this.box).find('#grid_'+ this.name +'_frec_'+ w2utils.escapeId(recid)) + tr2 = query(this.box).find('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)) + tr1.attr('custom_style', st) + tr2.attr('custom_style', st) + if (tr1.hasClass('w2ui-selected')) { + st = st.replace('background-color', 'none') + } + tr1[0].style.cssText = 'height: '+ this.recordHeight + 'px;' + st + tr2[0].style.cssText = 'height: '+ this.recordHeight + 'px;' + st + } + if (isSummary) { + this.resize() + } + return true + } + return false + } + refresh() { + let time = Date.now() + let url = (typeof this.url != 'object' ? this.url : this.url.get) + if (this.total <= 0 && !url && this.searchData.length === 0) { + this.total = this.records.length + } + if (!this.box) return + // event before + let edata = this.trigger('refresh', { target: this.name }) + if (edata.isCancelled === true) return + // -- header + if (this.show.header) { + query(this.box).find(`#grid_${this.name}_header`).html(w2utils.lang(this.header) +' ').show() + } else { + query(this.box).find(`#grid_${this.name}_header`).hide() + } + // -- toolbar + if (this.show.toolbar) { + query(this.box).find('#grid_'+ this.name +'_toolbar').show() + } else { + query(this.box).find('#grid_'+ this.name +'_toolbar').hide() + } + // -- make sure search is closed + this.searchClose() + // search placeholder + let sInput = query(this.box).find('#grid_'+ this.name +'_search_all') + if (!this.multiSearch && this.last.field == 'all' && this.searches.length > 0) { + this.last.field = this.searches[0].field + this.last.label = this.searches[0].label + } + for (let s = 0; s < this.searches.length; s++) { + if (this.searches[s].field == this.last.field) this.last.label = this.searches[s].label + } + if (this.last.multi) { + sInput.attr('placeholder', '[' + w2utils.lang('Multiple Fields') + ']') + } else { + sInput.attr('placeholder', w2utils.lang('Search') + ' ' + w2utils.lang(this.last.label, true)) + } + if (sInput.val() != this.last.search) { + let val = this.last.search + let tmp = sInput._w2field + if (tmp) val = tmp.format(val) + sInput.val(val) + } + this.refreshSearch() + this.refreshBody() + // -- footer + if (this.show.footer) { + query(this.box).find(`#grid_${this.name}_footer`).html(this.getFooterHTML()).show() + } else { + query(this.box).find(`#grid_${this.name}_footer`).hide() + } + // all selected? + let sel = this.last.selection, + areAllSelected = (this.records.length > 0 && sel.indexes.length == this.records.length), + areAllSearchedSelected = (sel.indexes.length > 0 && this.searchData.length !== 0 && sel.indexes.length == this.last.searchIds.length) + if (areAllSelected || areAllSearchedSelected) { + query(this.box).find('#grid_'+ this.name +'_check_all').prop('checked', true) + } else { + query(this.box).find('#grid_'+ this.name +'_check_all').prop('checked', false) + } + // show number of selected + this.status() + // collapse all records + let rows = this.find({ 'w2ui.expanded': true }, true, true) + for (let r = 0; r < rows.length; r++) { + let tmp = this.records[rows[r]].w2ui + if (tmp && !Array.isArray(tmp.children)) { + tmp.expanded = false + } + } + // mark selection + if (this.markSearch) { + setTimeout(() => { + // mark all search strings + let search = [] + for (let s = 0; s < this.searchData.length; s++) { + let sdata = this.searchData[s] + let fld = this.getSearch(sdata.field) + if (!fld || fld.hidden) continue + let ind = this.getColumn(sdata.field, true) + search.push({ field: sdata.field, search: sdata.value, col: ind }) + } + if (search.length > 0) { + search.forEach((item) => { + let el = query(this.box).find('td[col="'+ item.col +'"]:not(.w2ui-head)') + w2utils.marker(el, item.search) + }) + } + }, 50) + } + this.updateToolbar(this.last.selection) + // event after + edata.finish() + this.resize() + this.addRange('selection') + setTimeout(() => { // allow to render first + this.resize() // needed for horizontal scroll to show (do not remove) + this.scroll() + }, 1) + if (this.reorderColumns && !this.last.columnDrag) { + this.last.columnDrag = this.initColumnDrag() + } else if (!this.reorderColumns && this.last.columnDrag) { + this.last.columnDrag.remove() + } + return Date.now() - time + } + refreshSearch() { + if (this.multiSearch && this.searchData.length > 0) { + if (query(this.box).find('.w2ui-grid-searches').length == 0) { + query(this.box).find('.w2ui-grid-toolbar') + .css('height', (this.last.toolbar_height + 35) + 'px') + .append(`
    `) + } + let searches = ` + +
    ` + this.searchData.forEach((sd, sd_ind) => { + let ind = this.getSearch(sd.field, true) + let sf = this.searches[ind] + let display + if (Array.isArray(sd.value)) { + display = `${sd.value.length}` + } else if (sf && sf.type == 'list') { + display = !!sd.text && sd.text !== sd.value ? `: ${sd.text}` : `: ${sd.value}` + } else { + display = `: ${sd.value}` + } + if (sf && sf.type == 'date') { + if (sd.operator == 'between') { + let dsp1 = sd.value[0] + let dsp2 = sd.value[1] + if (Number(dsp1) === dsp1) { + dsp1 = w2utils.formatDate(dsp1) + } + if (Number(dsp2) === dsp2) { + dsp2 = w2utils.formatDate(dsp2) + } + display = `: ${dsp1} - ${dsp2}` + } else { + let dsp = sd.value + if (Number(dsp) == dsp) { + dsp = w2utils.formatDate(dsp) + } + let oper = sd.operator + if (oper == 'more') oper = 'since' + if (oper == 'less') oper = 'before' + if (oper.substr(0, 5) == 'more:') { + oper = 'since' + } + display = `: ${oper} ${dsp}` + } + } + searches += ` + ${sf ? sf.label : ''} + ${display} + + ` + }) + // clear and save + searches += ` + ${this.show.searchSave + ? `
    + + ` + : '' +} + + ` + query(this.box).find(`#grid_${this.name}_searches`).html(searches) + query(this.box).find(`#grid_${this.name}_search_logic`).html(w2utils.lang(this.last.logic == 'AND' ? 'All' : 'Any')) + } else { + query(this.box).find('.w2ui-grid-toolbar') + .css('height', this.last.toolbar_height + 'px') + .find('.w2ui-grid-searches') + .remove() + } + if (this.searchSelected) { + query(this.box).find(`#grid_${this.name}_search_all`).val(' ').prop('readOnly', true) + query(this.box).find(`#grid_${this.name}_search_name`).show().find('.name-text').html(this.searchSelected.text) + } else { + query(this.box).find(`#grid_${this.name}_search_all`).prop('readOnly', false) + query(this.box).find(`#grid_${this.name}_search_name`).hide().find('.name-text').html('') + } + w2utils.bindEvents(query(this.box).find(`#grid_${this.name}_searches .w2ui-action, #grid_${this.name}_searches button`), this) + } + refreshBody() { + this.scroll() // need to calculate virtual scrolling for columns + let recHTML = this.getRecordsHTML() + let colHTML = this.getColumnsHTML() + let bodyHTML = + '
    '+ + recHTML[0] + + '
    '+ + '
    ' + + recHTML[1] + + '
    '+ + '
    '+ + // Columns need to be after to be able to overlap + '
    '+ + ' '+ colHTML[0] +'
    '+ + '
    '+ + '
    '+ + ' '+ colHTML[1] +'
    '+ + '
    '+ + `` + let gridBody = query(this.box).find(`#grid_${this.name}_body`, this.box).html(bodyHTML) + let records = query(this.box).find(`#grid_${this.name}_records`, this.box) + let frecords = query(this.box).find(`#grid_${this.name}_frecords`, this.box) + if (this.selectType == 'row') { + records.on('mouseover mouseout', { delegate: 'tr' }, (event) => { + let recid = query(event.delegate).attr('recid') + query(this.box).find(`#grid_${this.name}_frec_${w2utils.escapeId(recid)}`) + .toggleClass('w2ui-record-hover', event.type == 'mouseover') + }) + frecords.on('mouseover mouseout', { delegate: 'tr' }, (event) => { + let recid = query(event.delegate).attr('recid') + query(this.box).find(`#grid_${this.name}_rec_${w2utils.escapeId(recid)}`) + .toggleClass('w2ui-record-hover', event.type == 'mouseover') + }) + } + if (w2utils.isIOS) { + records.append(frecords) + .on('click', { delegate: 'tr' }, (event) => { + let recid = query(event.delegate).attr('recid') + this.dblClick(recid, event) + }) + } else { + records.add(frecords) + .on('click', { delegate: 'tr' }, (event) => { + let recid = query(event.delegate).attr('recid') + // do not generate click if empty record is clicked + if (recid != '-none-') { + this.click(recid, event) + } + }) + .on('contextmenu', { delegate: 'tr' }, (event) => { + let recid = query(event.delegate).attr('recid') + let td = query(event.target).closest('td') + let column = parseInt(td.attr('col') ?? -1) + this.showContextMenu(recid, column, event) + }) + .on('mouseover', { delegate: 'tr' }, (event) => { + this.last.rec_out = false + let index = query(event.delegate).attr('index') + let recid = query(event.delegate).attr('recid') + if (index !== this.last.rec_over) { + this.last.rec_over = index + // setTimeout is needed for correct event order enter/leave + setTimeout(() => { + delete this.last.rec_out + let edata = this.trigger('mouseEnter', { target: this.name, originalEvent: event, index, recid }) + edata.finish() + }) + } + }) + .on('mouseout', { delegate: 'tr' }, (event) => { + let index = query(event.delegate).attr('index') + let recid = query(event.delegate).attr('recid') + this.last.rec_out = true + // setTimeouts are needed for correct event order enter/leave + setTimeout(() => { + let recLeave = () => { + let edata = this.trigger('mouseLeave', { target: this.name, originalEvent: event, index, recid }) + edata.finish() + } + if (index !== this.last.rec_over) { + recLeave() + } + setTimeout(() => { + if (this.last.rec_out) { + delete this.last.rec_out + delete this.last.rec_over + recLeave() + } + }) + }) + }) + } + // enable scrolling on frozen records, + gridBody + .data('scroll', { lastDelta: 0, lastTime: 0 }) + .find('.w2ui-grid-frecords') + .on('mousewheel DOMMouseScroll ', (event) => { + event.preventDefault() + // TODO: improve, scroll is not smooth, if scrolled to the end, it takes a while to return + let scroll = gridBody.data('scroll') + let container = gridBody.find('.w2ui-grid-records') + let amount = typeof event.wheelDelta != null ? -event.wheelDelta : (event.detail || event.deltaY) + let newScrollTop = container.prop('scrollTop') + scroll.lastDelta += amount + amount = Math.round(scroll.lastDelta) + gridBody.data('scroll', scroll) + // make scroll amount dependent on visible rows + // amount *= (Math.round(records.prop('clientHeight') / self.recordHeight) - 1) * self.recordHeight / 4 + container.get(0).scroll({ top: newScrollTop + amount, behavior: 'smooth' }) + }) + // scroll on records (and frozen records) + records.off('.body-global') + .on('scroll.body-global', { delegate: '.w2ui-grid-records' }, event => { + this.scroll(event) + }) + query(this.box).find('.w2ui-grid-body') // gridBody + .off('.body-global') + // header column click + .on('click.body-global dblclick.body-global contextmenu.body-global', { delegate: 'td.w2ui-head' }, event => { + let col_ind = query(event.delegate).attr('col') + let col = this.columns[col_ind] ?? { field: col_ind } // it could be line number + switch (event.type) { + case 'click': + this.columnClick(col.field, event) + break + case 'dblclick': + this.columnDblClick(col.field, event) + break + case 'contextmenu': + this.columnContextMenu(col.field, event) + break + } + }) + .on('mouseover.body-global', { delegate: '.w2ui-col-header' }, event => { + let col = query(event.delegate).parent().attr('col') + this.columnTooltipShow(col, event) + query(event.delegate) + .off('.tooltip') + .on('mouseleave.tooltip', () => { + this.columnTooltipHide(col, event) + }) + }) + // select all + .on('click.body-global', { delegate: 'input.w2ui-select-all' }, event => { + if (event.delegate.checked) { this.selectAll() } else { this.selectNone() } + event.stopPropagation() + clearTimeout(this.last.kbd_timer) // keep grid in focus + }) + // tree-like grid (or expandable column) expand/collapse + .on('click.body-global', { delegate: '.w2ui-show-children, .w2ui-col-expand' }, event => { + event.stopPropagation() + this.toggle(query(event.target).parents('tr').attr('recid')) + }) + // info bubbles + .on('click.body-global mouseover.body-global', { delegate: '.w2ui-info' }, event => { + let td = query(event.delegate).closest('td') + let tr = td.parent() + let col = this.columns[td.attr('col')] + let isSummary = tr.parents('.w2ui-grid-body').hasClass('w2ui-grid-summary') + if (['mouseenter', 'mouseover'].includes(col.info?.showOn?.toLowerCase()) && event.type == 'mouseover') { + this.showBubble(tr.attr('index'), td.attr('col'), isSummary) + .then(() => { + query(event.delegate) + .off('.tooltip') + .on('mouseleave.tooltip', () => { w2tooltip.hide(this.name + '-bubble') }) + }) + } else if (event.type == 'click') { + w2tooltip.hide(this.name + '-bubble') + this.showBubble(tr.attr('index'), td.attr('col'), isSummary) + } + }) + // clipborad copy icon + .on('mouseover.body-global', { delegate: '.w2ui-clipboard-copy' }, event => { + if (event.delegate._tooltipShow) return + let td = query(event.delegate).parent() + let tr = td.parent() + let col = this.columns[td.attr('col')] + let isSummary = tr.parents('.w2ui-grid-body').hasClass('w2ui-grid-summary') + w2tooltip.show({ + name: this.name + '-bubble', + anchor: event.delegate, + html: w2utils.lang(typeof col.clipboardCopy == 'string' ? col.clipboardCopy : 'Copy to clipboard'), + position: 'top|bottom', + offsetY: -2 + }) + .hide(evt => { + event.delegate._tooltipShow = false + query(event.delegate).off('.tooltip') + }) + query(event.delegate) + .off('.tooltip') + .on('mouseleave.tooltip', evt => { + w2tooltip.hide(this.name + '-bubble') + }) + .on('click.tooltip', evt => { + evt.stopPropagation() + w2tooltip.update(this.name + '-bubble', w2utils.lang('Copied')) + this.clipboardCopy(tr.attr('index'), td.attr('col'), isSummary) + }) + event.delegate._tooltipShow = true + }) + .on('click.body-global', { delegate: '.w2ui-editable-checkbox' }, event => { + let dt = query(event.delegate).data() + this.editChange.call(this, event.delegate, dt.changeind, dt.colind, event) + this.updateToolbar() + }) + // show empty message + if (this.records.length === 0 && this.msgEmpty) { + query(this.box).find(`#grid_${this.name}_body`) + .append(`
    ${w2utils.lang(this.msgEmpty)}
    `) + } else if (query(this.box).find(`#grid_${this.name}_empty_msg`).length > 0) { + query(this.box).find(`#grid_${this.name}_empty_msg`).remove() + } + // show summary records + if (this.summary.length > 0) { + let sumHTML = this.getSummaryHTML() + query(this.box).find(`#grid_${this.name}_fsummary`).html(sumHTML[0]).show() + query(this.box).find(`#grid_${this.name}_summary`).html(sumHTML[1]).show() + } else { + query(this.box).find(`#grid_${this.name}_fsummary`).hide() + query(this.box).find(`#grid_${this.name}_summary`).hide() + } + } + render(box) { + let time = Date.now() + let obj = this + if (typeof box == 'string') box = query(box).get(0) + // event before + let edata = this.trigger('render', { target: this.name, box: box ?? this.box }) + if (edata.isCancelled === true) return + // default action + if (box != null) { + // clean previous box + if (query(this.box).find(`#grid_${this.name}_body`).length > 0) { + query(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-grid w2ui-inactive') + .html('') + } + this.box = box + } + if (!this.box) return + let url = (typeof this.url != 'object' ? this.url : this.url.get) + // reset needed if grid existed + this.reset(true) + // --- default search field + if (!this.last.field) { + if (!this.multiSearch || !this.show.searchAll) { + let tmp = 0 + while (tmp < this.searches.length && (this.searches[tmp].hidden || this.searches[tmp].simple === false)) tmp++ + if (tmp >= this.searches.length) { + // all searches are hidden + this.last.field = '' + this.last.label = '' + } else { + this.last.field = this.searches[tmp].field + this.last.label = this.searches[tmp].label + } + } else { + this.last.field = 'all' + this.last.label = 'All Fields' + } + } + // insert elements + query(this.box) + .attr('name', this.name) + .addClass('w2ui-reset w2ui-grid w2ui-inactive') + .html('
    '+ + '
    '+ + '
    '+ + '
    '+ + '
    '+ + '
    '+ + ' '+ + ' '+ // readonly needed on android not to open keyboard + '
    ') + if (this.selectType != 'row') query(this.box).addClass('w2ui-ss') + if (query(this.box).length > 0) query(this.box)[0].style.cssText += this.style + // init toolbar + this.initToolbar() + if (this.toolbar != null) this.toolbar.render(query(this.box).find('#grid_'+ this.name +'_toolbar')[0]) + this.last.toolbar_height = query(this.box).find(`#grid_${this.name}_toolbar`).prop('offsetHeight') + // re-init search_all + if (this.last.field && this.last.field != 'all') { + let sd = this.searchData + setTimeout(() => { this.searchInitInput(this.last.field, (sd.length == 1 ? sd[0].value : null)) }, 1) + } + // init footer + query(this.box).find(`#grid_${this.name}_footer`).html(this.getFooterHTML()) + // refresh + if (!this.last.state) this.last.state = this.stateSave(true) // initial default state + this.stateRestore() + if (url) { this.clear(); this.refresh() } // show empty grid (need it) - should it be only for remote data source + // if hidden searches - apply it + let hasHiddenSearches = false + for (let i = 0; i < this.searches.length; i++) { + if (this.searches[i].hidden) { hasHiddenSearches = true; break } + } + if (hasHiddenSearches) { + this.searchReset(false) // will call reload + if (!url) setTimeout(() => { this.searchReset() }, 1) + } else { + this.reload() + } + // focus + query(this.box).find(`#grid_${this.name}_focus`) + .on('focus', (event) => { + clearTimeout(this.last.kbd_timer) + if (!this.hasFocus) this.focus() + }) + .on('blur', (event) => { + clearTimeout(this.last.kbd_timer) + this.last.kbd_timer = setTimeout(() => { + if (this.hasFocus) { this.blur() } + }, 100) // need this timer to be 100 ms + }) + .on('paste', (event) => { + let cd = (event.clipboardData ? event.clipboardData : null) + if (cd) { + let items = cd.items + if (items.length == 2) { + if (items.length == 2 && items[1].kind == 'file') { + items = [items[1]] + } + if (items.length == 2 && items[0].type == 'text/plain' && items[1].type == 'text/html') { + items = [items[1]] + } + } + let items2send = [] + // might contain data in different formats, but it is a single paste + for (let index in items) { + let item = items[index] + if (item.kind === 'file') { + let file = item.getAsFile() + items2send.push({ kind: 'file', data: file }) + } else if (item.kind === 'string' && (item.type === 'text/plain' || item.type === 'text/html')) { + event.preventDefault() + let text = cd.getData('text/plain') + if (text.indexOf('\r') != -1 && text.indexOf('\n') == -1) { + text = text.replace(/\r/g, '\n') + } + items2send.push({ kind: (item.type == 'text/html' ? 'html' : 'text'), data: text }) + } + } + if (items2send.length === 1 && items2send[0].kind != 'file') { + items2send = items2send[0].data + } + w2ui[this.name].paste(items2send, event) + event.preventDefault() + } + }) + .on('keydown', function (event) { + w2ui[obj.name].keydown.call(w2ui[obj.name], event) + }) + // init mouse events for mouse selection + let edataCol // event for column select + query(this.box).off('mousedown.mouseStart').on('mousedown.mouseStart', mouseStart) + this.updateToolbar() + // event after + edata.finish() + // observe div resize + this.last.observeResize = new ResizeObserver(() => { this.resize() }) + this.last.observeResize.observe(this.box) + return Date.now() - time + function mouseStart (event) { + if (event.which != 1) return // if not left mouse button + // restore css user-select + if (obj.last.userSelect == 'text') { + obj.last.userSelect = '' + query(obj.box).find('.w2ui-grid-body').css('user-select', 'none') + } + // regular record select + if (obj.selectType == 'row' && (query(event.target).parents().hasClass('w2ui-head') || query(event.target).hasClass('w2ui-head'))) return + if (obj.last.move && obj.last.move.type == 'expand') return + // if altKey - alow text selection + if (event.altKey) { + query(obj.box).find('.w2ui-grid-body').css('user-select', 'text') + obj.selectNone() + obj.last.move = { type: 'text-select' } + obj.last.userSelect = 'text' + } else { + let tmp = event.target + let pos = { + x: event.offsetX - 10, + y: event.offsetY - 10 + } + let tmps = false + while (tmp) { + if (tmp.classList && tmp.classList.contains('w2ui-grid')) break + if (tmp.tagName && tmp.tagName.toUpperCase() == 'TD') tmps = true + if (tmp.tagName && tmp.tagName.toUpperCase() != 'TR' && tmps == true) { + pos.x += tmp.offsetLeft + pos.y += tmp.offsetTop + } + tmp = tmp.parentNode + } + obj.last.move = { + x : event.screenX, + y : event.screenY, + divX : 0, + divY : 0, + focusX : pos.x, + focusY : pos.y, + recid : query(event.target).parents('tr').attr('recid'), + column : parseInt(event.target.tagName.toUpperCase() == 'TD' ? query(event.target).attr('col') : query(event.target).parents('td').attr('col')), + type : 'select', + ghost : false, + start : true + } + if (obj.last.move.recid == null) obj.last.move.type = 'select-column' + // set focus to grid + let target = event.target + let $input = query(obj.box).find('#grid_'+ obj.name + '_focus') + // move input next to cursor so screen does not jump + if (obj.last.move) { + let sLeft = obj.last.move.focusX + let sTop = obj.last.move.focusY + let $owner = query(target).parents('table').parent() + if ($owner.hasClass('w2ui-grid-records') || $owner.hasClass('w2ui-grid-frecords') + || $owner.hasClass('w2ui-grid-columns') || $owner.hasClass('w2ui-grid-fcolumns') + || $owner.hasClass('w2ui-grid-summary')) { + sLeft = obj.last.move.focusX - query(obj.box).find('#grid_'+ obj.name +'_records').prop('scrollLeft') + sTop = obj.last.move.focusY - query(obj.box).find('#grid_'+ obj.name +'_records').prop('scrollTop') + } + if (query(target).hasClass('w2ui-grid-footer') || query(target).parents('div.w2ui-grid-footer').length > 0) { + sTop = query(obj.box).find('#grid_'+ obj.name +'_footer').get(0).offsetTop + } + // if clicked on toolbar + if ($owner.hasClass('w2ui-scroll-wrapper') && $owner.parent().hasClass('w2ui-toolbar')) { + sLeft = obj.last.move.focusX - $owner.prop('scrollLeft') + } + $input.css({ + left: sLeft - 10, + top : sTop + }) + } + // if toolbar input is clicked + setTimeout(() => { + if (!obj.last.inEditMode) { + if (['INPUT', 'TEXTAREA', 'SELECT'].includes(target.tagName)) { + target.focus() + } else { + if ($input.get(0) !== document.active) $input.get(0)?.focus({ preventScroll: true }) + } + } + }, 50) + // disable click select for this condition + if (!obj.multiSelect && !obj.reorderRows && obj.last.move.type == 'drag') { + delete obj.last.move + } + } + if (obj.reorderRows == true) { + let el = event.target + if (el.tagName.toUpperCase() != 'TD') el = query(el).parents('td')[0] + if (query(el).hasClass('w2ui-col-number') || query(el).hasClass('w2ui-col-order')) { + obj.selectNone() + obj.last.move.reorder = true + // suppress hover + let eColor = query(obj.box).find('.w2ui-even.w2ui-empty-record').css('background-color') + let oColor = query(obj.box).find('.w2ui-odd.w2ui-empty-record').css('background-color') + query(obj.box).find('.w2ui-even td').filter(':not(.w2ui-col-number)').css('background-color', eColor) + query(obj.box).find('.w2ui-odd td').filter(':not(.w2ui-col-number)').css('background-color', oColor) + // display empty record and ghost record + let mv = obj.last.move + let recs = query(obj.box).find('.w2ui-grid-records') + if (!mv.ghost) { + let row = query(obj.box).find(`#grid_${obj.name}_rec_${mv.recid}`) + let tmp = row.parents('table').find('tr:first-child').get(0).cloneNode(true) + mv.offsetY = event.offsetY + mv.from = mv.recid + mv.pos = { top: row.get(0).offsetTop-1, left: row.get(0).offsetLeft } + mv.ghost = query(row.get(0).cloneNode(true)) + mv.ghost.removeAttr('id') + mv.ghost.find('td').css({ + 'border-top': '1px solid silver', + 'border-bottom': '1px solid silver' + }) + row.find('td').remove() + row.append(`
    `) + recs.append('
    ') + recs.append('
    ') + query(obj.box).find('#grid_'+ obj.name + '_ghost').append(tmp).append(mv.ghost) + } + let ghost = query(obj.box).find('#grid_'+ obj.name + '_ghost') + ghost.css({ + top : mv.pos.top + 'px', + left : mv.pos.left + 'px' + }) + } else { + obj.last.move.reorder = false + } + } + query(document) + .on('mousemove.w2ui-' + obj.name, mouseMove) + .on('mouseup.w2ui-' + obj.name, mouseStop) + // needed when grid grids are nested, see issue #1275 + event.stopPropagation() + } + function mouseMove(event) { + if (!event.target.tagName) { + // element has no tagName - most likely the target is the #document itself + // this can happen is you click+drag and move the mouse out of the DOM area, + // e.g. into the browser's toolbar area + return + } + let mv = obj.last.move + if (!mv || ['select', 'select-column'].indexOf(mv.type) == -1) return + mv.divX = (event.screenX - mv.x) + mv.divY = (event.screenY - mv.y) + if (Math.abs(mv.divX) <= 1 && Math.abs(mv.divY) <= 1) return // only if moved more then 1px + obj.last.cancelClick = true + if (obj.reorderRows == true && obj.last.move.reorder) { + let tmp = query(event.target).parents('tr') + let recid = tmp.attr('recid') + if (recid == '-none-') recid = 'bottom' + if (recid != mv.from) { + // let row1 = query(obj.box).find('#grid_'+ obj.name + '_rec_'+ mv.recid) + let row2 = query(obj.box).find('#grid_'+ obj.name + '_rec_'+ recid) + query(obj.box).find('.insert-before') + row2.addClass('insert-before') + // MOVABLE GHOST + // if (event.screenY - mv.lastY < 0) row1.after(row2); else row2.after(row1); + mv.lastY = event.screenY + mv.to = recid + // line to insert before + let pos = { top: row2.get(0)?.offsetTop, left: row2.get(0)?.offsetLeft } + let ghost_line = query(obj.box).find('#grid_'+ obj.name + '_ghost_line') + if (pos) { + ghost_line.css({ + top : pos.top + 'px', + left : mv.pos.left + 'px', + 'border-top': '2px solid #769EFC' + }) + } else { + ghost_line.css({ + 'border-top': '2px solid transparent' + }) + } + } + let ghost = query(obj.box).find('#grid_'+ obj.name + '_ghost') + ghost.css({ + top : (mv.pos.top + mv.divY) + 'px', + left : mv.pos.left + 'px' + }) + return + } + if (mv.start && mv.recid) { + obj.selectNone() + mv.start = false + } + let newSel = [] + let recid = (event.target.tagName.toUpperCase() == 'TR' ? query(event.target).attr('recid') : query(event.target).parents('tr').attr('recid')) + if (recid == null) { + // select by dragging columns + if (obj.selectType == 'row') return + if (obj.last.move && obj.last.move.type == 'select') return + let col = parseInt(query(event.target).parents('td').attr('col')) + if (isNaN(col)) { + obj.removeRange('column-selection') + query(obj.box).find('.w2ui-grid-columns .w2ui-col-header, .w2ui-grid-fcolumns .w2ui-col-header').removeClass('w2ui-col-selected') + query(obj.box).find('.w2ui-col-number').removeClass('w2ui-row-selected') + delete mv.colRange + } else { + // add all columns in between + let newRange = col + '-' + col + if (mv.column < col) newRange = mv.column + '-' + col + if (mv.column > col) newRange = col + '-' + mv.column + // array of selected columns + let cols = [] + let tmp = newRange.split('-') + for (let ii = parseInt(tmp[0]); ii <= parseInt(tmp[1]); ii++) { + cols.push(ii) + } + if (mv.colRange != newRange) { + edataCol = obj.trigger('columnSelect', { target: obj.name, columns: cols }) + if (edataCol.isCancelled !== true) { + if (mv.colRange == null) obj.selectNone() + // highlight columns + let tmp = newRange.split('-') + query(obj.box).find('.w2ui-grid-columns .w2ui-col-header, .w2ui-grid-fcolumns .w2ui-col-header').removeClass('w2ui-col-selected') + for (let j = parseInt(tmp[0]); j <= parseInt(tmp[1]); j++) { + query(obj.box).find('#grid_'+ obj.name +'_column_' + j + ' .w2ui-col-header').addClass('w2ui-col-selected') + } + query(obj.box).find('.w2ui-col-number').not('.w2ui-head').addClass('w2ui-row-selected') + // show new range + mv.colRange = newRange + obj.removeRange('column-selection') + obj.addRange({ + name : 'column-selection', + range : [{ recid: obj.records[0].recid, column: tmp[0] }, { recid: obj.records[obj.records.length-1].recid, column: tmp[1] }], + style : 'background-color: rgba(90, 145, 234, 0.1)' + }) + } + } + } + } else { // regular selection + let ind1 = obj.get(mv.recid, true) + // this happens when selection is started on summary row + if (ind1 == null || (obj.records[ind1] && obj.records[ind1].recid != mv.recid)) return + let ind2 = obj.get(recid, true) + // this happens when selection is extended into summary row (a good place to implement scrolling) + if (ind2 == null) return + let col1 = parseInt(mv.column) + let col2 = parseInt(event.target.tagName.toUpperCase() == 'TD' ? query(event.target).attr('col') : query(event.target).parents('td').attr('col')) + if (isNaN(col1) && isNaN(col2)) { // line number select entire record + col1 = 0 + col2 = obj.columns.length-1 + } + if (ind1 > ind2) { let tmp = ind1; ind1 = ind2; ind2 = tmp } + // check if need to refresh + let tmp = 'ind1:'+ ind1 +',ind2;'+ ind2 +',col1:'+ col1 +',col2:'+ col2 + if (mv.range == tmp) return + mv.range = tmp + for (let i = ind1; i <= ind2; i++) { + if (obj.last.searchIds.length > 0 && obj.last.searchIds.indexOf(i) == -1) continue + if (obj.selectType != 'row') { + if (col1 > col2) { let tmp = col1; col1 = col2; col2 = tmp } + for (let c = col1; c <= col2; c++) { + if (obj.columns[c].hidden) continue + newSel.push({ recid: obj.records[i].recid, column: parseInt(c) }) + } + } else { + newSel.push(obj.records[i].recid) + } + } + if (obj.selectType != 'row') { + let sel = obj.getSelection() + // add more items + let tmp = [] + for (let ns = 0; ns < newSel.length; ns++) { + let flag = false + for (let s = 0; s < sel.length; s++) if (newSel[ns].recid == sel[s].recid && newSel[ns].column == sel[s].column) flag = true + if (!flag) tmp.push({ recid: newSel[ns].recid, column: newSel[ns].column }) + } + obj.select(tmp) + // remove items + tmp = [] + for (let s = 0; s < sel.length; s++) { + let flag = false + for (let ns = 0; ns < newSel.length; ns++) if (newSel[ns].recid == sel[s].recid && newSel[ns].column == sel[s].column) flag = true + if (!flag) tmp.push({ recid: sel[s].recid, column: sel[s].column }) + } + obj.unselect(tmp) + } else { + if (obj.multiSelect) { + let sel = obj.getSelection() + for (let ns = 0; ns < newSel.length; ns++) { + if (sel.indexOf(newSel[ns]) == -1) obj.select(newSel[ns]) // add more items + } + for (let s = 0; s < sel.length; s++) { + if (newSel.indexOf(sel[s]) == -1) obj.unselect(sel[s]) // remove items + } + } + } + } + } + function mouseStop (event) { + let mv = obj.last.move + setTimeout(() => { delete obj.last.cancelClick }, 1) + if (query(event.target).parents().hasClass('.w2ui-head') || query(event.target).hasClass('.w2ui-head')) return + if (mv && ['select', 'select-column'].indexOf(mv.type) != -1) { + if (mv.colRange != null && edataCol.isCancelled !== true) { + let tmp = mv.colRange.split('-') + let sel = [] + for (let i = 0; i < obj.records.length; i++) { + let cols = [] + for (let j = parseInt(tmp[0]); j <= parseInt(tmp[1]); j++) cols.push(j) + sel.push({ recid: obj.records[i].recid, column: cols }) + } + obj.removeRange('column-selection') + edataCol.finish() + obj.select(sel) + } + if (obj.reorderRows == true && obj.last.move.reorder) { + if (mv.to != null) { + // event + let edata = obj.trigger('reorderRow', { target: obj.name, recid: mv.from, moveBefore: mv.to }) + if (edata.isCancelled === true) { + resetRowReorder() + delete obj.last.move + return + } + // default behavior + let ind1 = obj.get(mv.from, true) + let ind2 = obj.get(mv.to, true) + if (mv.to == 'bottom') ind2 = obj.records.length // end of list + let tmp = obj.records[ind1] + // swap records + if (ind1 != null && ind2 != null) { + obj.records.splice(ind1, 1) + if (ind1 > ind2) { + obj.records.splice(ind2, 0, tmp) + } else { + obj.records.splice(ind2 - 1, 0, tmp) + } + } + // clear sortData + obj.sortData = [] + query(obj.box) + .find(`#grid_${obj.name}_columns .w2ui-col-header`) + .removeClass('w2ui-col-sorted') + resetRowReorder() + // event after + edata.finish() + } else { + resetRowReorder() + } + } + } + delete obj.last.move + query(document).off('.w2ui-' + obj.name) + } + function resetRowReorder() { + query(obj.box).find(`#grid_${obj.name}_ghost`).remove() + query(obj.box).find(`#grid_${obj.name}_ghost_line`).remove() + obj.refresh() + delete obj.last.move + } + } + destroy() { + // event before + let edata = this.trigger('destroy', { target: this.name }) + if (edata.isCancelled === true) return + // remove all events + query(this.box).off() + // clean up + if (typeof this.toolbar == 'object' && this.toolbar.destroy) this.toolbar.destroy() + if (query(this.box).find(`#grid_${this.name}_body`).length > 0) { + query(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-grid w2ui-inactive') + .html('') + } + this.last.observeResize?.disconnect() + delete w2ui[this.name] + // event after + edata.finish() + } + // =========================================== + // --- Internal Functions + initColumnOnOff() { + let items = [ + { id: 'line-numbers', text: 'Line #', checked: this.show.lineNumbers } + ] + // columns + for (let c = 0; c < this.columns.length; c++) { + let col = this.columns[c] + let text = this.columns[c].text + if (col.hideable === false) continue + if (!text && this.columns[c].tooltip) text = this.columns[c].tooltip + if (!text) text = '- column '+ (parseInt(c) + 1) +' -' + items.push({ id: col.field, text: w2utils.stripTags(text), checked: !col.hidden }) + } + let url = (typeof this.url != 'object' ? this.url : this.url.get) + if ((url && this.show.skipRecords) || this.show.saveRestoreState) { + items.push({ text: '--' }) + } + // skip records + if (this.show.skipRecords) { + let skip = w2utils.lang('Skip') + + `` + + w2utils.lang('records') + items.push({ id: 'w2ui-skip', text: skip, group: false, icon: 'w2ui-icon-empty' }) + } + // save/restore state + if (this.show.saveRestoreState) { + items.push( + { id: 'w2ui-stateSave', text: w2utils.lang('Save Grid State'), icon: 'w2ui-icon-empty', group: false }, + { id: 'w2ui-stateReset', text: w2utils.lang('Restore Default State'), icon: 'w2ui-icon-empty', group: false } + ) + } + let selected = [] + items.forEach(item => { + item.text = w2utils.lang(item.text) // translate + if (item.checked) selected.push(item.id) + }) + this.toolbar.set('w2ui-column-on-off', { selected, items }) + return items + } + initColumnDrag(box) { + // throw error if using column groups + if (this.columnGroups && this.columnGroups.length) { + throw 'Draggable columns are not currently supported with column groups.' + } + let self = this + let dragData = { + pressed: false, + targetPos: null, + columnHead: null + } + let hasInvalidClass = (target, lastColumn) => { + let iClass = ['w2ui-col-number', 'w2ui-col-expand', 'w2ui-col-select'] + if (lastColumn !== true) iClass.push('w2ui-head-last') + for (let i = 0; i < iClass.length; i++) { + if (query(target).closest('.w2ui-head').hasClass(iClass[i])) { + return true + } + } + return false + } + // attach original event listener + query(self.box) + .off('.colDrag') + .on('mousedown.colDrag', dragColStart) + function dragColStart(event) { + if (dragData.pressed || dragData.numberPreColumnsPresent === 0 || event.button !== 0) return + let edata, columns, origColumn, origColumnNumber + let preColHeadersSelector = '.w2ui-head.w2ui-col-number, .w2ui-head.w2ui-col-expand, .w2ui-head.w2ui-col-select' + // do nothing if it is not a header + if (!query(event.target).parents().hasClass('w2ui-head') || hasInvalidClass(event.target)) return + dragData.pressed = true + dragData.initialX = event.pageX + dragData.initialY = event.pageY + dragData.numberPreColumnsPresent = query(self.box).find(preColHeadersSelector).length + // start event for drag start + dragData.columnHead = origColumn = query(event.target).closest('.w2ui-head') + dragData.originalPos = origColumnNumber = parseInt(origColumn.attr('col'), 10) + edata = self.trigger('columnDragStart', { originalEvent: event, origColumnNumber, target: origColumn[0] }) + if (edata.isCancelled === true) return false + columns = dragData.columns = query(self.box).find('.w2ui-head:not(.w2ui-head-last)') + // add events + query(document).on('mouseup.colDrag', dragColEnd) + query(document).on('mousemove.colDrag', dragColOver) + let col = self.columns[dragData.originalPos] + let colText = w2utils.lang(typeof col.text == 'function' ? col.text(col) : col.text) + dragData.ghost = query.html(`${colText}`)[0] + query(document.body).append(dragData.ghost) + query(dragData.ghost) + .css({ + display: 'none', + left: event.pageX, + top: event.pageY, + opacity: 1, + margin: '3px 0 0 20px', + padding: '3px', + 'background-color': 'white', + position: 'fixed', + 'z-index': 999999, + }) + .addClass('.w2ui-grid-ghost') + + // establish current offsets + dragData.offsets = [] + for (let i = 0, l = columns.length; i < l; i++) { + let rect = columns[i].getBoundingClientRect() + dragData.offsets.push(rect.left) + } + // conclude event + edata.finish() + } + function dragColOver(event) { + if (!dragData.pressed || !dragData.columnHead) return + let cursorX = event.pageX + let cursorY = event.pageY + if (!hasInvalidClass(event.target, true)) { + markIntersection(event) + } + trackGhost(cursorX, cursorY) + } + function dragColEnd(event) { + if (!dragData.pressed || !dragData.columnHead) return + dragData.pressed = false + let edata, target, selected, columnConfig + let finish = () => { + let ghosts = query(self.box).find('.w2ui-grid-ghost') + query(self.box).find('.w2ui-intersection-marker').hide() + query(dragData.ghost).remove() + ghosts.remove() + // dragData.columns.css({ overflow: '' }).children('div').css({ overflow: '' }); + query(document).off('.colDrag') + dragData = {} + } + // if no move, then click event for sorting + if (event.pageX == dragData.initialX && event.pageY == dragData.initialY) { + self.columnClick(self.columns[dragData.originalPos].field, event) + finish() + return + } + // start event for drag start + edata = self.trigger('columnDragEnd', { originalEvent: event, target: dragData.columnHead[0], dragData }) + if (edata.isCancelled === true) return false + selected = self.columns[dragData.originalPos] + columnConfig = self.columns + if (dragData.originalPos != dragData.targetPos && dragData.targetPos != null) { + columnConfig.splice(dragData.targetPos, 0, w2utils.clone(selected)) + columnConfig.splice(columnConfig.indexOf(selected), 1) + } + finish() + self.refresh() + edata.finish({ targetColumn: target - 1 }) + } + function markIntersection(event) { + // if mouse over is not over table + if (query(event.target).closest('td').length == 0) { + return + } + // if mouse over invalid column + let rect1 = query(self.box).find('.w2ui-grid-body').get(0).getBoundingClientRect() + let rect2 = query(event.target).closest('td').get(0).getBoundingClientRect() + query(self.box).find('.w2ui-intersection-marker') + .show() + .css({ + left: (rect2.left - rect1.left) + 'px' + }) + let td = query(event.target).closest('td') + dragData.targetPos = td.hasClass('w2ui-head-last') ? self.columns.length : parseInt(td.attr('col')) + return + } + function trackGhost(cursorX, cursorY){ + query(dragData.ghost) + .css({ + left : (cursorX - 10) + 'px', + top : (cursorY - 10) + 'px' + }) + .show() + } + // return an object to remove drag if it has ever been enabled + return { + remove() { + query(self.box).off('.colDrag') + self.last.columnDrag = false + } + } + } + columnOnOff(event, field) { + // event before + let edata = this.trigger('columnOnOff', { target: this.name, field: field, originalEvent: event }) + if (edata.isCancelled === true) return + // collapse expanded rows + let rows = this.find({ 'w2ui.expanded': true }, true) + for (let r = 0; r < rows.length; r++) { + let tmp = this.records[r].w2ui + if (tmp && !Array.isArray(tmp.children)) { + this.records[r].w2ui.expanded = false + } + } + // show/hide + if (field == 'line-numbers') { + this.show.lineNumbers = !this.show.lineNumbers + this.refresh() + } else { + let col = this.getColumn(field) + if (col.hidden) { + this.showColumn(col.field) + } else { + this.hideColumn(col.field) + } + } + // event after + edata.finish() + } + initToolbar() { + // if it is already initiazlied + if (this.toolbar.render != null) { + return + } + let tb_items = this.toolbar.items || [] + this.toolbar.items = [] + this.toolbar = new w2toolbar(w2utils.extend({}, this.toolbar, { name: this.name +'_toolbar', owner: this })) + if (this.show.toolbarReload) { + this.toolbar.items.push(w2utils.extend({}, this.buttons.reload)) + } + if (this.show.toolbarColumns) { + this.toolbar.items.push(w2utils.extend({}, this.buttons.columns)) + } + if (this.show.toolbarSearch) { + let html =` +
    + ${this.buttons.search.html} +
    + + + x +
    + +
    + +
    +
    ` + this.toolbar.items.push({ + id: 'w2ui-search', + type: 'html', + html, + onRefresh: async (event) => { + await event.complete + let input = query(this.box).find(`#grid_${this.name}_search_all`) + w2utils.bindEvents(query(this.box).find(`#grid_${this.name}_search_all, .w2ui-action`), this) + // slow down live search calls + let slowSearch = w2utils.debounce((event) => { + let val = event.target.value + if (this.liveSearch && this.last.liveText != val) { + this.last.liveText = val + this.search(this.last.field, val) + } + if (event.keyCode == 40) { // arrow down + this.searchSuggest(true) + } + }, 250) + input + .on('change', event => { + if (!this.liveSearch) { + this.search(this.last.field, event.target.value) + this.searchSuggest(true, true, this) + } + }) + .on('blur', () => { this.last.liveText = '' }) + .on('keyup', slowSearch) + } + }) + } + if (Array.isArray(tb_items)) { + let ids = tb_items.map(item => item.id) + if (this.show.toolbarAdd && !ids.includes(this.buttons.add.id)) { + this.toolbar.items.push(w2utils.extend({}, this.buttons.add)) + } + if (this.show.toolbarEdit && !ids.includes(this.buttons.edit.id)) { + this.toolbar.items.push(w2utils.extend({}, this.buttons.edit)) + } + if (this.show.toolbarDelete && !ids.includes(this.buttons.delete.id)) { + this.toolbar.items.push(w2utils.extend({}, this.buttons.delete)) + } + if (this.show.toolbarSave && !ids.includes(this.buttons.save.id)) { + if (this.show.toolbarAdd || this.show.toolbarDelete || this.show.toolbarEdit) { + this.toolbar.items.push({ type: 'break', id: 'w2ui-break2' }) + } + this.toolbar.items.push(w2utils.extend({}, this.buttons.save)) + } + // fill in overwritten items with default buttons + // ids are w2ui-* but in this.buttons the map is just [add, edit, delete] + // must specify at least {id, name} in this.toolbar.items if you want to keep order + tb_items = tb_items.map(item => this.buttons[item.name] + ? w2utils.extend({}, this.buttons[item.name], item) : item) + } + // add original buttons + this.toolbar.items.push(...tb_items) + // ============================================= + // ------ Toolbar onClick processing + this.toolbar.on('click', (event) => { + let edata = this.trigger('toolbar', { target: event.target, originalEvent: event }) + if (edata.isCancelled === true) return + let edata2 + switch (event.detail.item.id) { + case 'w2ui-reload': + edata2 = this.trigger('reload', { target: this.name }) + if (edata2.isCancelled === true) return false + this.reload() + edata2.finish() + break + case 'w2ui-column-on-off': + // TODO: tap on columns will hide menu before opening, only in grid not in toolbar + if (event.detail.subItem) { + let id = event.detail.subItem.id + if (['w2ui-stateSave', 'w2ui-stateReset'].includes(id)) { + this[id.substring(5)]() + } else if (id == 'w2ui-skip') { + // empty + } else { + this.columnOnOff(event, event.detail.subItem.id) + } + } else { + this.initColumnOnOff() + // init input control with records to skip + setTimeout(() => { + query(`#w2overlay-${this.name}_toolbar-drop .w2ui-grid-skip`) + .off('.w2ui-grid') + .on('click.w2ui-grid', evt => { + evt.stopPropagation() + }) + .on('keypress', evt => { + if (evt.keyCode == 13) { + this.skip(evt.target.value) + this.toolbar.click('w2ui-column-on-off') // close menu + } + }) + }, 100) + } + break + case 'w2ui-add': + // events + edata2 = this.trigger('add', { target: this.name, recid: null }) + if (edata2.isCancelled === true) return false + edata2.finish() + break + case 'w2ui-edit': { + let sel = this.getSelection() + let recid = null + if (sel.length == 1) recid = sel[0] + // events + edata2 = this.trigger('edit', { target: this.name, recid: recid }) + if (edata2.isCancelled === true) return false + edata2.finish() + break + } + case 'w2ui-delete': + this.delete() + break + case 'w2ui-save': + this.save() + break + } + // no default action + edata.finish() + }) + this.toolbar.on('refresh', (event) => { + if (event.target == 'w2ui-search') { + let sd = this.searchData + setTimeout(() => { + this.searchInitInput(this.last.field, (sd.length == 1 ? sd[0].value : null)) + }, 1) + } + }) + } + initResize() { + let obj = this + query(this.box).find('.w2ui-resizer') + .off('.grid-col-resize') + .on('click.grid-col-resize', function(event) { + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true + if (event.preventDefault) event.preventDefault() + }) + .on('mousedown.grid-col-resize', function(event) { + if (!event) event = window.event + obj.last.colResizing = true + obj.last.tmp = { + x : event.screenX, + y : event.screenY, + gx : event.screenX, + gy : event.screenY, + col : parseInt(query(this).attr('name')) + } + // find tds that will be resized + obj.last.tmp.tds = query(obj.box).find('#grid_'+ obj.name +'_body table tr:first-child td[col="'+ obj.last.tmp.col +'"]') + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true + if (event.preventDefault) event.preventDefault() + // fix sizes + for (let c = 0; c < obj.columns.length; c++) { + if (obj.columns[c].hidden) continue + if (obj.columns[c].sizeOriginal == null) obj.columns[c].sizeOriginal = obj.columns[c].size + obj.columns[c].size = obj.columns[c].sizeCalculated + } + let edata = { phase: 'before', type: 'columnResize', target: obj.name, column: obj.last.tmp.col, field: obj.columns[obj.last.tmp.col].field } + edata = obj.trigger(w2utils.extend(edata, { resizeBy: 0, originalEvent: event })) + // set move event + let timer + let mouseMove = function(event) { + if (obj.last.colResizing != true) return + if (!event) event = window.event + // event before + edata = obj.trigger(w2utils.extend(edata, { resizeBy: (event.screenX - obj.last.tmp.gx), originalEvent: event })) + if (edata.isCancelled === true) { edata.isCancelled = false; return } + // default action + obj.last.tmp.x = (event.screenX - obj.last.tmp.x) + obj.last.tmp.y = (event.screenY - obj.last.tmp.y) + let newWidth = (parseInt(obj.columns[obj.last.tmp.col].size) + obj.last.tmp.x) + 'px' + obj.columns[obj.last.tmp.col].size = newWidth + if (timer) clearTimeout(timer) + timer = setTimeout(() => { + obj.resizeRecords() + obj.scroll() + }, 100) + // quick resize + obj.last.tmp.tds.css({ width: newWidth }) + // reset + obj.last.tmp.x = event.screenX + obj.last.tmp.y = event.screenY + } + let mouseUp = function(event) { + query(document).off('.grid-col-resize') + obj.resizeRecords() + obj.scroll() + // event after + edata.finish({ originalEvent: event }) + // need timeout to finish processing events + setTimeout(() => { obj.last.colResizing = false }, 1) + } + query(document) + .off('.grid-col-resize') + .on('mousemove.grid-col-resize', mouseMove) + .on('mouseup.grid-col-resize', mouseUp) + }) + .on('dblclick.grid-col-resize', function(event) { + let colId = parseInt(query(this).attr('name')), + col = obj.columns[colId], + maxDiff = 0 + if (col.autoResize === false) { + return true + } + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true + if (event.preventDefault) event.preventDefault() + query(obj.box).find('.w2ui-grid-records td[col="' + colId + '"] > div', obj.box).each(() => { + let thisDiff = this.offsetWidth - this.scrollWidth + if (thisDiff < maxDiff) { + maxDiff = thisDiff - 3 // 3px buffer needed for Firefox + } + }) + // event before + let edata = { phase: 'before', type: 'columnAutoResize', target: obj.name, column: col, field: col.field } + edata = obj.trigger(w2utils.extend(edata, { resizeBy: Math.abs(maxDiff), originalEvent: event })) + if (edata.isCancelled === true) { edata.isCancelled = false; return } + if (maxDiff < 0) { + col.size = Math.min(parseInt(col.size) + Math.abs(maxDiff), col.max || Infinity) + 'px' + obj.resizeRecords() + obj.resizeRecords() // Why do we have to call it twice in order to show the scrollbar? + obj.scroll() + } + // event after + edata.finish({ originalEvent: event }) + }) + .each(el => { + let td = query(el).get(0).parentNode + query(el).css({ + 'height' : td.clientHeight + 'px', + 'margin-left' : (td.clientWidth - 3) + 'px' + }) + }) + } + resizeBoxes() { + // elements + let header = query(this.box).find(`#grid_${this.name}_header`) + let toolbar = query(this.box).find(`#grid_${this.name}_toolbar`) + let fsummary = query(this.box).find(`#grid_${this.name}_fsummary`) + let summary = query(this.box).find(`#grid_${this.name}_summary`) + let footer = query(this.box).find(`#grid_${this.name}_footer`) + let body = query(this.box).find(`#grid_${this.name}_body`) + if (this.show.header) { + header.css({ + top: '0px', + left: '0px', + right: '0px' + }) + } + if (this.show.toolbar) { + toolbar.css({ + top: (0 + (this.show.header ? w2utils.getSize(header, 'height') : 0)) + 'px', + left: '0px', + right: '0px' + }) + } + if (this.summary.length > 0) { + fsummary.css({ + bottom: (0 + (this.show.footer ? w2utils.getSize(footer, 'height') : 0)) + 'px' + }) + summary.css({ + bottom: (0 + (this.show.footer ? w2utils.getSize(footer, 'height') : 0)) + 'px', + right: '0px' + }) + } + if (this.show.footer) { + footer.css({ + bottom: '0px', + left: '0px', + right: '0px' + }) + } + body.css({ + top: (0 + (this.show.header ? w2utils.getSize(header, 'height') : 0) + (this.show.toolbar ? w2utils.getSize(toolbar, 'height') : 0)) + 'px', + bottom: (0 + (this.show.footer ? w2utils.getSize(footer, 'height') : 0) + (this.summary.length > 0 ? w2utils.getSize(summary, 'height') : 0)) + 'px', + left: '0px', + right: '0px' + }) + } + resizeRecords() { + let obj = this + // remove empty records + query(this.box).find('.w2ui-empty-record').remove() + // -- Calculate Column size in PX + let box = query(this.box) + let grid = query(this.box).find(':scope > div.w2ui-grid-box') + let header = query(this.box).find(`#grid_${this.name}_header`) + let toolbar = query(this.box).find(`#grid_${this.name}_toolbar`) + let summary = query(this.box).find(`#grid_${this.name}_summary`) + let fsummary = query(this.box).find(`#grid_${this.name}_fsummary`) + let footer = query(this.box).find(`#grid_${this.name}_footer`) + let body = query(this.box).find(`#grid_${this.name}_body`) + let columns = query(this.box).find(`#grid_${this.name}_columns`) + let fcolumns = query(this.box).find(`#grid_${this.name}_fcolumns`) + let records = query(this.box).find(`#grid_${this.name}_records`) + let frecords = query(this.box).find(`#grid_${this.name}_frecords`) + let scroll1 = query(this.box).find(`#grid_${this.name}_scroll1`) + let lineNumberWidth = String(this.total).length * 8 + 10 + if (lineNumberWidth < 34) lineNumberWidth = 34 // 3 digit width + if (this.lineNumberWidth != null) lineNumberWidth = this.lineNumberWidth + let bodyOverflowX = false + let bodyOverflowY = false + let sWidth = 0 + for (let i = 0; i < this.columns.length; i++) { + if (this.columns[i].frozen || this.columns[i].hidden) continue + let cSize = parseInt(this.columns[i].sizeCalculated ? this.columns[i].sizeCalculated : this.columns[i].size) + sWidth += cSize + } + if (records[0]?.clientWidth < sWidth) bodyOverflowX = true + if (body[0]?.clientHeight - (columns[0]?.clientHeight ?? 0) + < (query(records).find(':scope > table')[0]?.clientHeight ?? 0) + (bodyOverflowX ? w2utils.scrollBarSize() : 0)) { + bodyOverflowY = true + } + // body might be expanded by data + if (!this.fixedBody) { + // allow it to render records, then resize + let bodyHeight = w2utils.getSize(columns, 'height') + + w2utils.getSize(query(this.box).find('#grid_'+ this.name +'_records table'), 'height') + + (bodyOverflowX ? w2utils.scrollBarSize() : 0) + let calculatedHeight = bodyHeight + + (this.show.header ? w2utils.getSize(header, 'height') : 0) + + (this.show.toolbar ? w2utils.getSize(toolbar, 'height') : 0) + + (summary.css('display') != 'none' ? w2utils.getSize(summary, 'height') : 0) + + (this.show.footer ? w2utils.getSize(footer, 'height') : 0) + grid.css('height', calculatedHeight + 'px') + body.css('height', bodyHeight + 'px') + box.css('height', w2utils.getSize(grid, 'height') + 'px') + } else { + // fixed body height + let calculatedHeight = grid[0]?.clientHeight + - (this.show.header ? w2utils.getSize(header, 'height') : 0) + - (this.show.toolbar ? w2utils.getSize(toolbar, 'height') : 0) + - (summary.css('display') != 'none' ? w2utils.getSize(summary, 'height') : 0) + - (this.show.footer ? w2utils.getSize(footer, 'height') : 0) + body.css('height', calculatedHeight + 'px') + } + let buffered = this.records.length + let url = (typeof this.url != 'object' ? this.url : this.url.get) + if (this.searchData.length != 0 && !url) buffered = this.last.searchIds.length + // apply overflow + if (!this.fixedBody) { bodyOverflowY = false } + if (bodyOverflowX || bodyOverflowY) { + columns.find(':scope > table > tbody > tr:nth-child(1) td.w2ui-head-last') + .css('width', w2utils.scrollBarSize() + 'px') + .show() + records.css({ + top: ((this.columnGroups.length > 0 && this.show.columns ? 1 : 0) + w2utils.getSize(columns, 'height')) +'px', + '-webkit-overflow-scrolling': 'touch', + 'overflow-x': (bodyOverflowX ? 'auto' : 'hidden'), + 'overflow-y': (bodyOverflowY ? 'auto' : 'hidden') + }) + } else { + columns.find(':scope > table > tbody > tr:nth-child(1) td.w2ui-head-last').hide() + records.css({ + top: ((this.columnGroups.length > 0 && this.show.columns ? 1 : 0) + w2utils.getSize(columns, 'height')) +'px', + overflow: 'hidden' + }) + if (records.length > 0) { this.last.scrollTop = 0; this.last.scrollLeft = 0 } // if no scrollbars, always show top + } + if (bodyOverflowX) { + frecords.css('margin-bottom', w2utils.scrollBarSize() + 'px') + scroll1.show() + } else { + frecords.css('margin-bottom', 0) + scroll1.hide() + } + frecords.css({ overflow: 'hidden', top: records.css('top') }) + if (this.show.emptyRecords && !bodyOverflowY) { + let max = Math.floor((records[0]?.clientHeight ?? 0) / this.recordHeight) - 1 + let leftover = 0 + if (records[0]) leftover = records[0].scrollHeight - max * this.recordHeight + if (leftover >= this.recordHeight) { + leftover -= this.recordHeight + max++ + } + if (this.fixedBody) { + for (let di = buffered; di < max; di++) { + addEmptyRow(di, this.recordHeight, this) + } + addEmptyRow(max, leftover, this) + } + } + function addEmptyRow(row, height, grid) { + let html1 = '' + let html2 = '' + let htmlp = '' + html1 += '' + html2 += '' + if (grid.show.lineNumbers) html1 += '' + if (grid.show.selectColumn) html1 += '' + if (grid.show.expandColumn) html1 += '' + html2 += '' + if (grid.reorderRows) html2 += '' + for (let j = 0; j < grid.columns.length; j++) { + let col = grid.columns[j] + if ((col.hidden || j < grid.last.colStart || j > grid.last.colEnd) && !col.frozen) continue + htmlp = '' + if (col.frozen) html1 += htmlp; else html2 += htmlp + } + html1 += ' ' + html2 += ' ' + query(grid.box).find('#grid_'+ grid.name +'_frecords > table').append(html1) + query(grid.box).find('#grid_'+ grid.name +'_records > table').append(html2) + } + let width_box, percent + if (body.length > 0) { + let width_max = parseInt(body[0].clientWidth) + - (bodyOverflowY ? w2utils.scrollBarSize() : 0) + - (this.show.lineNumbers ? lineNumberWidth : 0) + - (this.reorderRows ? 26 : 0) + - (this.show.selectColumn ? 26 : 0) + - (this.show.expandColumn ? 26 : 0) + - 1 // left is 1px due to border width + width_box = width_max + percent = 0 + // gridMinWidth processing + let restart = false + for (let i = 0; i < this.columns.length; i++) { + let col = this.columns[i] + if (col.gridMinWidth > 0) { + if (col.gridMinWidth > width_box && col.hidden !== true) { + col.hidden = true + restart = true + } + if (col.gridMinWidth < width_box && col.hidden === true) { + col.hidden = false + restart = true + } + } + } + if (restart === true) { + this.refresh() + return + } + // assign PX column s + for (let i = 0; i < this.columns.length; i++) { + let col = this.columns[i] + if (col.hidden) continue + if (String(col.size).substr(String(col.size).length-2).toLowerCase() == 'px') { + width_max -= parseFloat(col.size) + this.columns[i].sizeCalculated = col.size + this.columns[i].sizeType = 'px' + } else { + percent += parseFloat(col.size) + this.columns[i].sizeType = '%' + delete col.sizeCorrected + } + } + // if sum != 100% -- reassign proportionally + if (percent != 100 && percent > 0) { + for (let i = 0; i < this.columns.length; i++) { + let col = this.columns[i] + if (col.hidden) continue + if (col.sizeType == '%') { + col.sizeCorrected = Math.round(parseFloat(col.size) * 100 * 100 / percent) / 100 + '%' + } + } + } + // calculate % columns + for (let i = 0; i < this.columns.length; i++) { + let col = this.columns[i] + if (col.hidden) continue + if (col.sizeType == '%') { + if (this.columns[i].sizeCorrected != null) { + // make it 1px smaller, so margin of error can be calculated correctly + this.columns[i].sizeCalculated = Math.floor(width_max * parseFloat(col.sizeCorrected) / 100) - 1 + 'px' + } else { + // make it 1px smaller, so margin of error can be calculated correctly + this.columns[i].sizeCalculated = Math.floor(width_max * parseFloat(col.size) / 100) - 1 + 'px' + } + } + } + } + // fix margin of error that is due percentage calculations + let width_cols = 0 + for (let i = 0; i < this.columns.length; i++) { + let col = this.columns[i] + if (col.hidden) continue + if (col.min == null) col.min = 20 + if (parseInt(col.sizeCalculated) < parseInt(col.min)) col.sizeCalculated = col.min + 'px' + if (parseInt(col.sizeCalculated) > parseInt(col.max)) col.sizeCalculated = col.max + 'px' + width_cols += parseInt(col.sizeCalculated) + } + let width_diff = parseInt(width_box) - parseInt(width_cols) + if (width_diff > 0 && percent > 0) { + let i = 0 + while (true) { + let col = this.columns[i] + if (col == null) { i = 0; continue } + if (col.hidden || col.sizeType == 'px') { i++; continue } + col.sizeCalculated = (parseInt(col.sizeCalculated) + 1) + 'px' + width_diff-- + if (width_diff === 0) break + i++ + } + } else if (width_diff > 0) { + columns.find(':scope > table > tbody > tr:nth-child(1) td.w2ui-head-last') + .css('width', w2utils.scrollBarSize() + 'px') + .show() + } + // find width of frozen columns + let fwidth = 1 + if (this.show.lineNumbers) fwidth += lineNumberWidth + if (this.show.selectColumn) fwidth += 26 + // if (this.reorderRows) fwidth += 26; + if (this.show.expandColumn) fwidth += 26 + for (let i = 0; i < this.columns.length; i++) { + if (this.columns[i].hidden) continue + if (this.columns[i].frozen) fwidth += parseInt(this.columns[i].sizeCalculated) + } + fcolumns.css('width', fwidth + 'px') + frecords.css('width', fwidth + 'px') + fsummary.css('width', fwidth + 'px') + scroll1.css('width', fwidth + 'px') + columns.css('left', fwidth + 'px') + records.css('left', fwidth + 'px') + summary.css('left', fwidth + 'px') + // resize columns + columns.find(':scope > table > tbody > tr:nth-child(1) td') + .add(fcolumns.find(':scope > table > tbody > tr:nth-child(1) td')) + .each(el => { + // line numbers + if (query(el).hasClass('w2ui-col-number')) { + query(el).css('width', lineNumberWidth + 'px') + } + // records + let ind = query(el).attr('col') + if (ind != null) { + if (ind == 'start') { + let width = 0 + for (let i = 0; i < obj.last.colStart; i++) { + if (!obj.columns[i] || obj.columns[i].frozen || obj.columns[i].hidden) continue + width += parseInt(obj.columns[i].sizeCalculated) + } + query(el).css('width', width + 'px') + } + if (obj.columns[ind]) query(el).css('width', obj.columns[ind].sizeCalculated) // already has px + } + // last column + if (query(el).hasClass('w2ui-head-last')) { + if (obj.last.colEnd + 1 < obj.columns.length) { + let width = 0 + for (let i = obj.last.colEnd + 1; i < obj.columns.length; i++) { + if (!obj.columns[i] || obj.columns[i].frozen || obj.columns[i].hidden) continue + width += parseInt(obj.columns[i].sizeCalculated) + } + query(el).css('width', width + 'px') + } else { + query(el).css('width', w2utils.scrollBarSize() + (width_diff > 0 && percent === 0 ? width_diff : 0) + 'px') + } + } + }) + // if there are column groups - hide first row (needed for sizing) + if (columns.find(':scope > table > tbody > tr').length == 3) { + columns.find(':scope > table > tbody > tr:nth-child(1) td') + .add(fcolumns.find(':scope > table > tbody > tr:nth-child(1) td')) + .html('').css({ + 'height' : '0', + 'border' : '0', + 'padding': '0', + 'margin' : '0' + }) + } + // resize records + records.find(':scope > table > tbody > tr:nth-child(1) td') + .add(frecords.find(':scope > table > tbody > tr:nth-child(1) td')) + .each(el => { + // line numbers + if (query(el).hasClass('w2ui-col-number')) { + query(el).css('width', lineNumberWidth + 'px') + } + // records + let ind = query(el).attr('col') + if (ind != null) { + if (ind == 'start') { + let width = 0 + for (let i = 0; i < obj.last.colStart; i++) { + if (!obj.columns[i] || obj.columns[i].frozen || obj.columns[i].hidden) continue + width += parseInt(obj.columns[i].sizeCalculated) + } + query(el).css('width', width + 'px') + } + if (obj.columns[ind]) query(el).css('width', obj.columns[ind].sizeCalculated) + } + // last column + if (query(el).hasClass('w2ui-grid-data-last') && query(el).parents('.w2ui-grid-frecords').length === 0) { // not in frecords + if (obj.last.colEnd + 1 < obj.columns.length) { + let width = 0 + for (let i = obj.last.colEnd + 1; i < obj.columns.length; i++) { + if (!obj.columns[i] || obj.columns[i].frozen || obj.columns[i].hidden) continue + width += parseInt(obj.columns[i].sizeCalculated) + } + query(el).css('width', width + 'px') + } else { + query(el).css('width', (width_diff > 0 && percent === 0 ? width_diff : 0) + 'px') + } + } + }) + // resize summary + summary.find(':scope > table > tbody > tr:nth-child(1) td') + .add(fsummary.find(':scope > table > tbody > tr:nth-child(1) td')) + .each(el => { + // line numbers + if (query(el).hasClass('w2ui-col-number')) { + query(el).css('width', lineNumberWidth + 'px') + } + // records + let ind = query(el).attr('col') + if (ind != null) { + if (ind == 'start') { + let width = 0 + for (let i = 0; i < obj.last.colStart; i++) { + if (!obj.columns[i] || obj.columns[i].frozen || obj.columns[i].hidden) continue + width += parseInt(obj.columns[i].sizeCalculated) + } + query(el).css('width', width + 'px') + } + if (obj.columns[ind]) query(el).css('width', obj.columns[ind].sizeCalculated) + } + // last column + if (query(el).hasClass('w2ui-grid-data-last') && query(el).parents('.w2ui-grid-frecords').length === 0) { // not in frecords + query(el).css('width', w2utils.scrollBarSize() + (width_diff > 0 && percent === 0 ? width_diff : 0) + 'px') + } + }) + this.initResize() + this.refreshRanges() + // apply last scroll if any + if ((this.last.scrollTop || this.last.scrollLeft) && records.length > 0) { + columns.prop('scrollLeft', this.last.scrollLeft) + records.prop('scrollTop', this.last.scrollTop) + records.prop('scrollLeft', this.last.scrollLeft) + } + // Improved performance when scrolling through tables + columns.css('will-change', 'scroll-position') + } + getSearchesHTML() { + let html = ` +
    + ${w2utils.lang('Advanced Search')} + + + +
    + + ` + for (let i = 0; i < this.searches.length; i++) { + let s = this.searches[i] + s.type = String(s.type).toLowerCase() + if (s.hidden) continue + if (s.attr == null) s.attr = '' + if (s.text == null) s.text = '' + if (s.style == null) s.style = '' + if (s.type == null) s.type = 'text' + if (s.label == null && s.caption != null) { + console.log('NOTICE: grid search.caption property is deprecated, please use search.label. Search ->', s) + s.label = s.caption + } + let operator =`` + html += ` + + + ' + + '' + } + html += ` + + +
    ${(w2utils.lang(s.label) || '')}${operator}` + let tmpStyle + switch (s.type) { + case 'text': + case 'alphanumeric': + case 'hex': + case 'color': + case 'list': + case 'combo': + case 'enum': + tmpStyle = 'width: 250px;' + if (['hex', 'color'].indexOf(s.type) != -1) tmpStyle = 'width: 90px;' + html += `` + break + case 'int': + case 'float': + case 'money': + case 'currency': + case 'percent': + case 'date': + case 'time': + case 'datetime': + tmpStyle = 'width: 90px;' + if (s.type == 'datetime') tmpStyle = 'width: 140px;' + html += ` + ` + break + case 'select': + html += `` + break + } + html += s.text + + '
    + + + + +
    ` + return html + } + getOperators(type, opers) { + let operators = this.operators[this.operatorsMap[type]] || [] + if (opers != null && Array.isArray(opers)) { + operators = opers + } + let html = '' + operators.forEach(oper => { + let displayText = oper + let operValue = oper + if (Array.isArray(oper)) { + displayText = oper[1] + operValue = oper[0] + } else if (w2utils.isPlainObject(oper)) { + displayText = oper.text + operValue = oper.oper + } + if (displayText == null) displayText = oper + html += `\n` + }) + return html + } + initOperator(ind) { + let options + let search = this.searches[ind] + let sdata = this.getSearchData(search.field) + let overlay = query(`#w2overlay-${this.name}-search-overlay`) + let $rng = overlay.find(`#grid_${this.name}_range_${ind}`) + let $fld1 = overlay.find(`#grid_${this.name}_field_${ind}`) + let $fld2 = overlay.find(`#grid_${this.name}_field2_${ind}`) + let $oper = overlay.find(`#grid_${this.name}_operator_${ind}`) + let oper = $oper.val() + $fld1.show() + $rng.hide() + // init based on operator value + switch (oper) { + case 'between': + $rng.show() + break + case 'null': + case 'not null': + $fld1.hide() + $fld1.val(oper) // need to insert something for search to activate + $fld1.trigger('change') + break + } + // init based on search type + switch (search.type) { + case 'text': + case 'alphanumeric': + let fld = $fld1[0]._w2field + if (fld) { fld.reset() } + break + case 'int': + case 'float': + case 'hex': + case 'color': + case 'money': + case 'currency': + case 'percent': + case 'date': + case 'time': + case 'datetime': + if (!$fld1[0]._w2field) { + // init fields + new w2field(search.type, { el: $fld1[0], ...search.options }) + new w2field(search.type, { el: $fld2[0], ...search.options }) + setTimeout(() => { // convert to date if it is number + $fld1.trigger('keydown') + $fld2.trigger('keydown') + }, 1) + } + break + case 'list': + case 'combo': + case 'enum': + options = search.options + if (search.type == 'list') options.selected = {} + if (search.type == 'enum') options.selected = [] + if (sdata) options.selected = sdata.value + if (!$fld1[0]._w2field) { + let fld = new w2field(search.type, { el: $fld1[0], ...options }) + if (sdata && sdata.text != null) { + fld.set({ id: sdata.value, text: sdata.text }) + } + } + break + case 'select': + // build options + options = '' + for (let i = 0; i < search.options.items.length; i++) { + let si = search.options.items[i] + if (w2utils.isPlainObject(search.options.items[i])) { + let val = si.id + let txt = si.text + if (val == null && si.value != null) val = si.value + if (txt == null && si.text != null) txt = si.text + if (val == null) val = '' + options += '' + } else { + options += '' + } + } + $fld1.html(options) + break + } + } + initSearches() { + let overlay = query(`#w2overlay-${this.name}-search-overlay`) + // init searches + for (let ind = 0; ind < this.searches.length; ind++) { + let search = this.searches[ind] + let sdata = this.getSearchData(search.field) + search.type = String(search.type).toLowerCase() + if (typeof search.options != 'object') search.options = {} + // operators + let operator = search.operator + let operators = [...this.operators[this.operatorsMap[search.type]]] || [] // need a copy + if (search.operators) operators = search.operators + // normalize + if (w2utils.isPlainObject(operator)) operator = operator.oper + operators.forEach((oper, ind) => { + if (w2utils.isPlainObject(oper)) operators[ind] = oper.oper + }) + if (sdata && sdata.operator) { + operator = sdata.operator + } + // default operator + let def = this.defaultOperator[this.operatorsMap[search.type]] + if (operators.indexOf(operator) == -1) { + operator = def + } + overlay.find(`#grid_${this.name}_operator_${ind}`).val(operator) + this.initOperator(ind) + // populate field value + let $fld1 = overlay.find(`#grid_${this.name}_field_${ind}`) + let $fld2 = overlay.find(`#grid_${this.name}_field2_${ind}`) + if (sdata != null) { + if (!Array.isArray(sdata.value)) { + if (sdata.value != null) $fld1.val(sdata.value).trigger('change') + } else { + if (['in', 'not in'].includes(sdata.operator)) { + $fld1[0]._w2field.set(sdata.value) + } else { + $fld1.val(sdata.value[0]).trigger('change') + $fld2.val(sdata.value[1]).trigger('change') + } + } + } + } + // add on change event + overlay.find('.w2ui-grid-search-advanced *[rel=search]') + .on('keypress', evnt => { + if (evnt.keyCode == 13) { + this.search() + w2tooltip.hide(this.name + '-search-overlay') + } + }) + } + getColumnsHTML() { + let self = this + let html1 = '' + let html2 = '' + if (this.show.columnHeaders) { + if (this.columnGroups.length > 0) { + let tmp1 = getColumns(true) + let tmp2 = getGroups() + let tmp3 = getColumns(false) + html1 = tmp1[0] + tmp2[0] + tmp3[0] + html2 = tmp1[1] + tmp2[1] + tmp3[1] + } else { + let tmp = getColumns(true) + html1 = tmp[0] + html2 = tmp[1] + } + } + return [html1, html2] + function getGroups() { + let html1 = '' + let html2 = '' + let tmpf = '' + // add empty group at the end + let tmp = self.columnGroups.length - 1 + if (self.columnGroups[tmp].text == null && self.columnGroups[tmp].caption != null) { + console.log('NOTICE: grid columnGroup.caption property is deprecated, please use columnGroup.text. Group -> ', self.columnGroups[tmp]) + self.columnGroups[tmp].text = self.columnGroups[tmp].caption + } + if (self.columnGroups[self.columnGroups.length-1].text != '') self.columnGroups.push({ text: '' }) + if (self.show.lineNumbers) { + html1 += '' + + '
     
    ' + + '' + } + if (self.show.selectColumn) { + html1 += '' + + '
     
    ' + + '' + } + if (self.show.expandColumn) { + html1 += '' + + '
     
    ' + + '' + } + let ii = 0 + html2 += `` + if (self.reorderRows) { + html2 += '' + + '
     
    ' + + '' + } + for (let i = 0; i < self.columnGroups.length; i++) { + let colg = self.columnGroups[i] + let col = self.columns[ii] || {} + if (colg.colspan != null) colg.span = colg.colspan + if (colg.span == null || colg.span != parseInt(colg.span)) colg.span = 1 + if (col.text == null && col.caption != null) { + console.log('NOTICE: grid column.caption property is deprecated, please use column.text. Column ->', col) + col.text = col.caption + } + let colspan = 0 + for (let jj = ii; jj < ii + colg.span; jj++) { + if (self.columns[jj] && !self.columns[jj].hidden) { + colspan++ + } + } + if (i == self.columnGroups.length-1) { + colspan = 100 // last column + } + if (colspan <= 0) { + // do nothing here, all columns in the group are hidden. + } else if (colg.main === true) { + let sortStyle = '' + for (let si = 0; si < self.sortData.length; si++) { + if (self.sortData[si].field == col.field) { + if ((self.sortData[si].direction || '').toLowerCase() === 'asc') sortStyle = 'w2ui-sort-up' + if ((self.sortData[si].direction || '').toLowerCase() === 'desc') sortStyle = 'w2ui-sort-down' + } + } + let resizer = '' + if (col.resizable !== false) { + resizer = `
    ` + } + let text = w2utils.lang(typeof col.text == 'function' ? col.text(col) : col.text) + tmpf = ``+ resizer + + `
    ` + + `
    ` + (!text ? ' ' : text) + + '
    '+ + '' + if (col && col.frozen) html1 += tmpf; else html2 += tmpf + } else { + let gText = w2utils.lang(typeof colg.text == 'function' ? colg.text(colg) : colg.text) + tmpf = `` + + `
    ${!gText ? ' ' : gText}
    ` + + '' + if (col && col.frozen) html1 += tmpf; else html2 += tmpf + } + ii += colg.span + } + html1 += '' // need empty column for border-right + html2 += `` + return [html1, html2] + } + function getColumns(main) { + let html1 = '' + let html2 = '' + if (self.show.lineNumbers) { + html1 += '' + + '
    #
    ' + + '' + } + if (self.show.selectColumn) { + html1 += '' + + '
    ' + + ` ' + + '
    ' + + '' + } + if (self.show.expandColumn) { + html1 += '' + + '
     
    ' + + '' + } + let ii = 0 + let id = 0 + let colg + html2 += `` + if (self.reorderRows) { + html2 += ''+ + '
     
    '+ + '' + } + for (let i = 0; i < self.columns.length; i++) { + let col = self.columns[i] + if (col.text == null && col.caption != null) { + console.log('NOTICE: grid column.caption property is deprecated, please use column.text. Column -> ', col) + col.text = col.caption + } + if (col.size == null) col.size = '100%' + if (i == id) { // always true on first iteration + colg = self.columnGroups[ii++] || {} + id = id + colg.span + } + if ((i < self.last.colStart || i > self.last.colEnd) && !col.frozen) + continue + if (col.hidden) + continue + if (colg.main !== true || main) { // grouping of columns + let colCellHTML = self.getColumnCellHTML(i) + if (col && col.frozen) html1 += colCellHTML; else html2 += colCellHTML + } + } + html1 += '
     
    ' + html2 += '
     
    ' + html1 += '' + html2 += '' + return [html1, html2] + } + } + getColumnCellHTML(i) { + let col = this.columns[i] + if (col == null) return '' + // reorder style + let reorderCols = (this.reorderColumns && (!this.columnGroups || !this.columnGroups.length)) ? ' w2ui-col-reorderable ' : '' + // sort style + let sortStyle = '' + for (let si = 0; si < this.sortData.length; si++) { + if (this.sortData[si].field == col.field) { + if ((this.sortData[si].direction || '').toLowerCase() === 'asc') sortStyle = 'w2ui-sort-up' + if ((this.sortData[si].direction || '').toLowerCase() === 'desc') sortStyle = 'w2ui-sort-down' + } + } + // col selected + let tmp = this.last.selection.columns + let selected = false + for (let t in tmp) { + for (let si = 0; si < tmp[t].length; si++) { + if (tmp[t][si] == i) selected = true + } + } + let text = w2utils.lang(typeof col.text == 'function' ? col.text(col) : col.text) + let html = '' + + (col.resizable !== false ? '
    ' : '') + + '
    '+ + '
    '+ + (!text ? ' ' : text) + + '
    '+ + '' + return html + } + columnTooltipShow(ind, event) { + let $el = query(this.box).find('#grid_'+ this.name + '_column_'+ ind) + let item = this.columns[ind] + let pos = this.columnTooltip + w2tooltip.show({ + name: this.name + '-column-tooltip', + anchor: $el.get(0), + html: item?.tooltip, + position: pos, + }) + } + columnTooltipHide(ind, event) { + w2tooltip.hide(this.name + '-column-tooltip') + } + getRecordsHTML() { + let buffered = this.records.length + let url = (typeof this.url != 'object' ? this.url : this.url.get) + if (this.searchData.length != 0 && !url) buffered = this.last.searchIds.length + // larger number works better with chrome, smaller with FF. + if (buffered > this.vs_start) this.last.show_extra = this.vs_extra; else this.last.show_extra = this.vs_start + let records = query(this.box).find(`#grid_${this.name}_records`) + let limit = Math.floor((records.get(0)?.clientHeight || 0) / this.recordHeight) + this.last.show_extra + 1 + if (!this.fixedBody || limit > buffered) limit = buffered + // always need first record for resizing purposes + let rec_html = this.getRecordHTML(-1, 0) + let html1 = '' + rec_html[0] + let html2 = '
    ' + rec_html[1] + // first empty row with height + html1 += ''+ + ' '+ + '' + html2 += ''+ + ' '+ + '' + for (let i = 0; i < limit; i++) { + rec_html = this.getRecordHTML(i, i+1) + html1 += rec_html[0] + html2 += rec_html[1] + } + let h2 = (buffered - limit) * this.recordHeight + html1 += '' + + ' '+ + ''+ + ''+ + ' '+ + ''+ + '
    ' + html2 += '' + + ' '+ + ''+ + ''+ + ' '+ + ''+ + '' + this.last.range_start = 0 + this.last.range_end = limit + return [html1, html2] + } + getSummaryHTML() { + if (this.summary.length === 0) return + let rec_html = this.getRecordHTML(-1, 0) // need this in summary too for colspan to work properly + let html1 = '' + rec_html[0] + let html2 = '
    ' + rec_html[1] + for (let i = 0; i < this.summary.length; i++) { + rec_html = this.getRecordHTML(i, i+1, true) + html1 += rec_html[0] + html2 += rec_html[1] + } + html1 += '
    ' + html2 += '' + return [html1, html2] + } + scroll(event) { + let obj = this + let url = (typeof this.url != 'object' ? this.url : this.url.get) + let records = query(this.box).find(`#grid_${this.name}_records`) + let frecords = query(this.box).find(`#grid_${this.name}_frecords`) + // sync scroll positions + if (event) { + let sTop = event.target.scrollTop + let sLeft = event.target.scrollLeft + this.last.scrollTop = sTop + this.last.scrollLeft = sLeft + let cols = query(this.box).find(`#grid_${this.name}_columns`)[0] + let summary = query(this.box).find(`#grid_${this.name}_summary`)[0] + if (cols) cols.scrollLeft = sLeft + if (summary) summary.scrollLeft = sLeft + if (frecords[0]) frecords[0].scrollTop = sTop + } + // hide bubble + if (this.last.bubbleEl) { + w2tooltip.hide(this.name + '-bubble') + this.last.bubbleEl = null + } + // column virtual scroll + let colStart = null + let colEnd = null + if (this.disableCVS || this.columnGroups.length > 0) { + // disable virtual scroll + colStart = 0 + colEnd = this.columns.length - 1 + } else { + let sWidth = records.prop('clientWidth') + let cLeft = 0 + for (let i = 0; i < this.columns.length; i++) { + if (this.columns[i].frozen || this.columns[i].hidden) continue + let cSize = parseInt(this.columns[i].sizeCalculated ? this.columns[i].sizeCalculated : this.columns[i].size) + if (cLeft + cSize + 30 > this.last.scrollLeft && colStart == null) colStart = i + if (cLeft + cSize - 30 > this.last.scrollLeft + sWidth && colEnd == null) colEnd = i + cLeft += cSize + } + if (colEnd == null) colEnd = this.columns.length - 1 + } + if (colStart != null) { + if (colStart < 0) colStart = 0 + if (colEnd < 0) colEnd = 0 + if (colStart == colEnd) { + if (colStart > 0) colStart--; else colEnd++ // show at least one column + } + // --------- + if (colStart != this.last.colStart || colEnd != this.last.colEnd) { + let $box = query(this.box) + let deltaStart = Math.abs(colStart - this.last.colStart) + let deltaEnd = Math.abs(colEnd - this.last.colEnd) + // add/remove columns for small jumps + if (deltaStart < 5 && deltaEnd < 5) { + let $cfirst = $box.find(`.w2ui-grid-columns #grid_${this.name}_column_start`) + let $clast = $box.find('.w2ui-grid-columns .w2ui-head-last') + let $rfirst = $box.find(`#grid_${this.name}_records .w2ui-grid-data-spacer`) + let $rlast = $box.find(`#grid_${this.name}_records .w2ui-grid-data-last`) + let $sfirst = $box.find(`#grid_${this.name}_summary .w2ui-grid-data-spacer`) + let $slast = $box.find(`#grid_${this.name}_summary .w2ui-grid-data-last`) + // remove on left + if (colStart > this.last.colStart) { + for (let i = this.last.colStart; i < colStart; i++) { + $box.find('#grid_'+ this.name +'_columns #grid_'+ this.name +'_column_'+ i).remove() // column + $box.find('#grid_'+ this.name +'_records td[col="'+ i +'"]').remove() // record + $box.find('#grid_'+ this.name +'_summary td[col="'+ i +'"]').remove() // summary + } + } + // remove on right + if (colEnd < this.last.colEnd) { + for (let i = this.last.colEnd; i > colEnd; i--) { + $box.find('#grid_'+ this.name +'_columns #grid_'+ this.name +'_column_'+ i).remove() // column + $box.find('#grid_'+ this.name +'_records td[col="'+ i +'"]').remove() // record + $box.find('#grid_'+ this.name +'_summary td[col="'+ i +'"]').remove() // summary + } + } + // add on left + if (colStart < this.last.colStart) { + for (let i = this.last.colStart - 1; i >= colStart; i--) { + if (this.columns[i] && (this.columns[i].frozen || this.columns[i].hidden)) continue + $cfirst.after(this.getColumnCellHTML(i)) // column + // record + $rfirst.each(el => { + let index = query(el).parent().attr('index') + let td = '' // width column + if (index != null) td = this.getCellHTML(parseInt(index), i, false) + query(el).after(td) + }) + // summary + $sfirst.each(el => { + let index = query(el).parent().attr('index') + let td = '' // width column + if (index != null) td = this.getCellHTML(parseInt(index), i, true) + query(el).after(td) + }) + } + } + // add on right + if (colEnd > this.last.colEnd) { + for (let i = this.last.colEnd + 1; i <= colEnd; i++) { + if (this.columns[i] && (this.columns[i].frozen || this.columns[i].hidden)) continue + $clast.before(this.getColumnCellHTML(i)) // column + // record + $rlast.each(el => { + let index = query(el).parent().attr('index') + let td = '' // width column + if (index != null) td = this.getCellHTML(parseInt(index), i, false) + query(el).before(td) + }) + // summary + $slast.each(el => { + let index = query(el).parent().attr('index') || -1 + let td = this.getCellHTML(parseInt(index), i, true) + query(el).before(td) + }) + } + } + this.last.colStart = colStart + this.last.colEnd = colEnd + this.resizeRecords() + } else { + this.last.colStart = colStart + this.last.colEnd = colEnd + // dot not just call this.refresh(); + let colHTML = this.getColumnsHTML() + let recHTML = this.getRecordsHTML() + let sumHTML = this.getSummaryHTML() + let $columns = $box.find(`#grid_${this.name}_columns`) + let $records = $box.find(`#grid_${this.name}_records`) + let $frecords = $box.find(`#grid_${this.name}_frecords`) + let $summary = $box.find(`#grid_${this.name}_summary`) + $columns.find('tbody').html(colHTML[1]) + $frecords.html(recHTML[0]) + $records.prepend(recHTML[1]) + if (sumHTML != null) $summary.html(sumHTML[1]) + // need timeout to clean up (otherwise scroll problem) + setTimeout(() => { + $records.find(':scope > table').filter(':not(table:first-child)').remove() + if ($summary[0]) $summary[0].scrollLeft = this.last.scrollLeft + }, 1) + this.resizeRecords() + } + } + } + // perform virtual scroll + let buffered = this.records.length + if (buffered > this.total && this.total !== -1) buffered = this.total + if (this.searchData.length != 0 && !url) buffered = this.last.searchIds.length + if (buffered === 0 || records.length === 0 || records.prop('clientHeight') === 0) return + if (buffered > this.vs_start) this.last.show_extra = this.vs_extra; else this.last.show_extra = this.vs_start + // update footer + let t1 = Math.round(records.prop('scrollTop') / this.recordHeight + 1) + let t2 = t1 + (Math.round(records.prop('clientHeight') / this.recordHeight) - 1) + if (t1 > buffered) t1 = buffered + if (t2 >= buffered - 1) t2 = buffered + query(this.box).find('#grid_'+ this.name + '_footer .w2ui-footer-right').html( + (this.show.statusRange + ? w2utils.formatNumber(this.offset + t1) + '-' + w2utils.formatNumber(this.offset + t2) + + (this.total != -1 ? ' ' + w2utils.lang('of') + ' ' + w2utils.formatNumber(this.total) : '') + : '') + + (url && this.show.statusBuffered ? ' ('+ w2utils.lang('buffered') + ' '+ w2utils.formatNumber(buffered) + + (this.offset > 0 ? ', skip ' + w2utils.formatNumber(this.offset) : '') + ')' : '') + ) + // only for local data source, else no extra records loaded + if (!url && (!this.fixedBody || (this.total != -1 && this.total <= this.vs_start))) return + // regular processing + let start = Math.floor(records.prop('scrollTop') / this.recordHeight) - this.last.show_extra + let end = start + Math.floor(records.prop('clientHeight') / this.recordHeight) + this.last.show_extra * 2 + 1 + // let div = start - this.last.range_start; + if (start < 1) start = 1 + if (end > this.total && this.total != -1) end = this.total + let tr1 = records.find('#grid_'+ this.name +'_rec_top') + let tr2 = records.find('#grid_'+ this.name +'_rec_bottom') + let tr1f = frecords.find('#grid_'+ this.name +'_frec_top') + let tr2f = frecords.find('#grid_'+ this.name +'_frec_bottom') + // if row is expanded + if (String(tr1.next().prop('id')).indexOf('_expanded_row') != -1) { + tr1.next().remove() + tr1f.next().remove() + } + if (this.total > end && String(tr2.prev().prop('id')).indexOf('_expanded_row') != -1) { + tr2.prev().remove() + tr2f.prev().remove() + } + let first = parseInt(tr1.next().attr('line')) + let last = parseInt(tr2.prev().attr('line')) + let tmp, tmp1, tmp2, rec_start, rec_html + if (first < start || first == 1 || this.last.pull_refresh) { // scroll down + if (end <= last + this.last.show_extra - 2 && end != this.total) return + this.last.pull_refresh = false + // remove from top + while (true) { + tmp1 = frecords.find('#grid_'+ this.name +'_frec_top').next() + tmp2 = records.find('#grid_'+ this.name +'_rec_top').next() + if (tmp2.attr('line') == 'bottom') break + if (parseInt(tmp2.attr('line')) < start) { + tmp1.remove() + tmp2.remove() + } else { + break + } + } + // add at bottom + tmp = records.find('#grid_'+ this.name +'_rec_bottom').prev() + rec_start = tmp.attr('line') + if (rec_start == 'top') rec_start = start + for (let i = parseInt(rec_start) + 1; i <= end; i++) { + if (!this.records[i-1]) continue + tmp2 = this.records[i-1].w2ui + if (tmp2 && !Array.isArray(tmp2.children)) { + tmp2.expanded = false + } + rec_html = this.getRecordHTML(i-1, i) + tr2.before(rec_html[1]) + tr2f.before(rec_html[0]) + } + markSearch() + setTimeout(() => { this.refreshRanges() }, 0) + } else { // scroll up + if (start >= first - this.last.show_extra + 2 && start > 1) return + // remove from bottom + while (true) { + tmp1 = frecords.find('#grid_'+ this.name +'_frec_bottom').prev() + tmp2 = records.find('#grid_'+ this.name +'_rec_bottom').prev() + if (tmp2.attr('line') == 'top') break + if (parseInt(tmp2.attr('line')) > end) { + tmp1.remove() + tmp2.remove() + } else { + break + } + } + // add at top + tmp = records.find('#grid_'+ this.name +'_rec_top').next() + rec_start = tmp.attr('line') + if (rec_start == 'bottom') rec_start = end + for (let i = parseInt(rec_start) - 1; i >= start; i--) { + if (!this.records[i-1]) continue + tmp2 = this.records[i-1].w2ui + if (tmp2 && !Array.isArray(tmp2.children)) { + tmp2.expanded = false + } + rec_html = this.getRecordHTML(i-1, i) + tr1.after(rec_html[1]) + tr1f.after(rec_html[0]) + } + markSearch() + setTimeout(() => { this.refreshRanges() }, 0) + } + // first/last row size + let h1 = (start - 1) * this.recordHeight + let h2 = (buffered - end) * this.recordHeight + if (h2 < 0) h2 = 0 + tr1.css('height', h1 + 'px') + tr1f.css('height', h1 + 'px') + tr2.css('height', h2 + 'px') + tr2f.css('height', h2 + 'px') + this.last.range_start = start + this.last.range_end = end + // load more if needed + let s = Math.floor(records.prop('scrollTop') / this.recordHeight) + let e = s + Math.floor(records.prop('clientHeight') / this.recordHeight) + if (e + 10 > buffered && this.last.pull_more !== true && (buffered < this.total - this.offset || (this.total == -1 && this.last.fetch.hasMore))) { + if (this.autoLoad === true) { + this.last.pull_more = true + this.last.fetch.offset += this.limit + this.request('load') + } + // scroll function + let more = query(this.box).find('#grid_'+ this.name +'_rec_more, #grid_'+ this.name +'_frec_more') + more.show() + .eq(1) // only main table + .off('.load-more') + .on('click.load-more', function() { + // show spinner + query(this).find('td').html('
    ') + // load more + obj.last.pull_more = true + obj.last.fetch.offset += obj.limit + obj.request('load') + }) + .find('td') + .html(obj.autoLoad + ? '
    ' + : '
    '+ w2utils.lang('Load ${count} more...', { count: obj.limit }) + '
    ' + ) + } + function markSearch() { + // mark search + if (!obj.markSearch) return + clearTimeout(obj.last.marker_timer) + obj.last.marker_timer = setTimeout(() => { + // mark all search strings + let search = [] + for (let s = 0; s < obj.searchData.length; s++) { + let sdata = obj.searchData[s] + let fld = obj.getSearch(sdata.field) + if (!fld || fld.hidden) continue + let ind = obj.getColumn(sdata.field, true) + search.push({ field: sdata.field, search: sdata.value, col: ind }) + } + if (search.length > 0) { + search.forEach((item) => { + let el = query(obj.box).find('td[col="'+ item.col +'"]:not(.w2ui-head)') + w2utils.marker(el, item.search) + }) + } + }, 50) + } + } + getRecordHTML(ind, lineNum, summary) { + let tmph = '' + let rec_html1 = '' + let rec_html2 = '' + let sel = this.last.selection + let record + // first record needs for resize purposes + if (ind == -1) { + rec_html1 += '' + rec_html2 += '' + if (this.show.lineNumbers) rec_html1 += '' + if (this.show.selectColumn) rec_html1 += '' + if (this.show.expandColumn) rec_html1 += '' + rec_html2 += '' + if (this.reorderRows) rec_html2 += '' + for (let i = 0; i < this.columns.length; i++) { + let col = this.columns[i] + tmph = '' + if (col.frozen && !col.hidden) { + rec_html1 += tmph + } else { + if (col.hidden || i < this.last.colStart || i > this.last.colEnd) continue + rec_html2 += tmph + } + } + rec_html1 += '' + rec_html2 += '' + rec_html1 += '' + rec_html2 += '' + return [rec_html1, rec_html2] + } + // regular record + let url = (typeof this.url != 'object' ? this.url : this.url.get) + if (summary !== true) { + if (this.searchData.length > 0 && !url) { + if (ind >= this.last.searchIds.length) return '' + ind = this.last.searchIds[ind] + record = this.records[ind] + } else { + if (ind >= this.records.length) return '' + record = this.records[ind] + } + } else { + if (ind >= this.summary.length) return '' + record = this.summary[ind] + } + if (!record) return '' + if (record.recid == null && this.recid != null) { + let rid = this.parseField(record, this.recid) + if (rid != null) record.recid = rid + } + let isRowSelected = false + if (sel.indexes.indexOf(ind) != -1) isRowSelected = true + let rec_style = (record.w2ui ? record.w2ui.style : '') + if (rec_style == null || typeof rec_style != 'string') rec_style = '' + let rec_class = (record.w2ui ? record.w2ui.class : '') + if (rec_class == null || typeof rec_class != 'string') rec_class = '' + // render TR + rec_html1 += '' + rec_html2 += '' + if (this.show.lineNumbers) { + rec_html1 += ''+ + (summary !== true ? this.getLineHTML(lineNum, record) : '') + + '' + } + if (this.show.selectColumn) { + rec_html1 += + ''+ + (summary !== true && !(record.w2ui && record.w2ui.hideCheckBox === true) ? + '
    '+ + ' '+ + '
    ' + : + '' ) + + '' + } + if (this.show.expandColumn) { + let tmp_img = '' + if (record.w2ui?.expanded === true) tmp_img = '-'; else tmp_img = '+' + if ((record.w2ui?.expanded == 'none' || !Array.isArray(record.w2ui?.children) || !record.w2ui?.children.length)) tmp_img = '+' + if (record.w2ui?.expanded == 'spinner') tmp_img = '
    ' + rec_html1 += + ''+ + (summary !== true ? `
    ${tmp_img}
    ` : '' ) + + '' + } + // insert empty first column + rec_html2 += '' + if (this.reorderRows) { + rec_html2 += + ''+ + (summary !== true ? '
     
    ' : '' ) + + '' + } + let col_ind = 0 + let col_skip = 0 + while (true) { + let col_span = 1 + let col = this.columns[col_ind] + if (col == null) break + if (col.hidden) { + col_ind++ + if (col_skip > 0) col_skip-- + continue + } + if (col_skip > 0) { + col_ind++ + if (this.columns[col_ind] == null) break + record.w2ui.colspan[this.columns[col_ind-1].field] = 0 // need it for other methods + col_skip-- + continue + } else if (record.w2ui) { + let tmp1 = record.w2ui.colspan + let tmp2 = this.columns[col_ind].field + if (tmp1 && tmp1[tmp2] === 0) { + delete tmp1[tmp2] // if no longer colspan then remove 0 + } + } + // column virtual scroll + if ((col_ind < this.last.colStart || col_ind > this.last.colEnd) && !col.frozen) { + col_ind++ + continue + } + if (record.w2ui) { + if (typeof record.w2ui.colspan == 'object') { + let span = parseInt(record.w2ui.colspan[col.field]) || null + if (span > 1) { + // if there are hidden columns, then no colspan on them + let hcnt = 0 + for (let i = col_ind; i < col_ind + span; i++) { + if (i >= this.columns.length) break + if (this.columns[i].hidden) hcnt++ + } + col_span = span - hcnt + col_skip = span - 1 + } + } + } + let rec_cell = this.getCellHTML(ind, col_ind, summary, col_span) + if (col.frozen) rec_html1 += rec_cell; else rec_html2 += rec_cell + col_ind++ + } + rec_html1 += '' + rec_html2 += '' + rec_html1 += '' + rec_html2 += '' + return [rec_html1, rec_html2] + } + getLineHTML(lineNum) { + return '
    ' + lineNum + '
    ' + } + getCellHTML(ind, col_ind, summary, col_span) { + let obj = this + let col = this.columns[col_ind] + if (col == null) return '' + let record = (summary !== true ? this.records[ind] : this.summary[ind]) + // value, attr, style, className, divAttr + let { value, style, className, attr, divAttr } = this.getCellValue(ind, col_ind, summary, true) + let edit = (ind !== -1 ? this.getCellEditable(ind, col_ind) : '') + let divStyle = 'max-height: '+ parseInt(this.recordHeight) +'px;' + (col.clipboardCopy ? 'margin-right: 20px' : '') + let isChanged = !summary && record?.w2ui?.changes && record.w2ui.changes[col.field] != null + let sel = this.last.selection + let isRowSelected = false + let infoBubble = '' + if (sel.indexes.indexOf(ind) != -1) isRowSelected = true + if (col_span == null) { + if (record?.w2ui?.colspan && record.w2ui.colspan[col.field]) { + col_span = record.w2ui.colspan[col.field] + } else { + col_span = 1 + } + } + // expand icon + if (col_ind === 0 && Array.isArray(record?.w2ui?.children)) { + let level = 0 + let subrec = this.get(record.w2ui.parent_recid, true) + while (true) { + if (subrec != null) { + level++ + let tmp = this.records[subrec].w2ui + if (tmp != null && tmp.parent_recid != null) { + subrec = this.get(tmp.parent_recid, true) + } else { + break + } + } else { + break + } + } + if (record.w2ui.parent_recid) { + for (let i = 0; i < level; i++) { + infoBubble += '' + } + } + let className = record.w2ui.children.length > 0 + ? (record.w2ui.expanded ? 'w2ui-icon-collapse' : 'w2ui-icon-expand') + : 'w2ui-icon-empty' + infoBubble += `` + } + // info bubble + if (col.info === true) col.info = {} + if (col.info != null) { + let infoIcon = 'w2ui-icon-info' + if (typeof col.info.icon == 'function') { + infoIcon = col.info.icon(record, { self: this, index: ind, colIndex: col_ind, summary: !!summary }) + } else if (typeof col.info.icon == 'object') { + infoIcon = col.info.icon[this.parseField(record, col.field)] || '' + } else if (typeof col.info.icon == 'string') { + infoIcon = col.info.icon + } + let infoStyle = col.info.style || '' + if (typeof col.info.style == 'function') { + infoStyle = col.info.style(record, { self: this, index: ind, colIndex: col_ind, summary: !!summary }) + } else if (typeof col.info.style == 'object') { + infoStyle = col.info.style[this.parseField(record, col.field)] || '' + } else if (typeof col.info.style == 'string') { + infoStyle = col.info.style + } + infoBubble += `` + } + let data = value + // if editable checkbox + if (edit && ['checkbox', 'check'].indexOf(edit.type) != -1) { + let changeInd = summary ? -(ind + 1) : ind + divStyle += 'text-align: center;' + data = `` + infoBubble = '' + } + data = `
    ${infoBubble}${String(data)}
    ` + if (data == null) data = '' + // --> cell TD + if (typeof col.render == 'string') { + let tmp = col.render.toLowerCase().split(':') + if (['number', 'int', 'float', 'money', 'currency', 'percent', 'size'].indexOf(tmp[0]) != -1) { + style += 'text-align: right;' + } + } + if (record?.w2ui) { + if (typeof record.w2ui.style == 'object') { + if (typeof record.w2ui.style[col_ind] == 'string') style += record.w2ui.style[col_ind] + ';' + if (typeof record.w2ui.style[col.field] == 'string') style += record.w2ui.style[col.field] + ';' + } + if (typeof record.w2ui.class == 'object') { + if (typeof record.w2ui.class[col_ind] == 'string') className += record.w2ui.class[col_ind] + ' ' + if (typeof record.w2ui.class[col.field] == 'string') className += record.w2ui.class[col.field] + ' ' + } + } + let isCellSelected = false + if (isRowSelected && sel.columns[ind]?.includes(col_ind)) isCellSelected = true + // clipboardCopy + let clipboardIcon + if (col.clipboardCopy){ + clipboardIcon = '' + } + // data + data = ' 1 ? 'colspan="'+ col_span + '"' : '') + + '>' + data + (clipboardIcon && w2utils.stripTags(data) ? clipboardIcon : '') +'' + // summary top row + if (ind === -1 && summary === true) { + data = ' 1 ? 'colspan="'+ col_span + '"' : '') + + '>' + } + return data + function getTitle(cellData){ + let title + if (obj.show.recordTitles) { + if (col.title != null) { + if (typeof col.title == 'function') { + title = col.title.call(obj, record, { self: this, index: ind, colIndex: col_ind, summary: !!summary }) + } + if (typeof col.title == 'string') title = col.title + } else { + title = w2utils.stripTags(String(cellData).replace(/"/g, '\'\'')) + } + } + return (title != null) ? 'title="' + String(title) + '"' : '' + } + } + clipboardCopy(ind, col_ind, summary) { + let rec = summary ? this.summary[ind] : this.records[ind] + let col = this.columns[col_ind] + let txt = (col ? this.parseField(rec, col.field) : '') + if (typeof col.clipboardCopy == 'function') { + txt = col.clipboardCopy(rec, { self: this, index: ind, colIndex: col_ind, summary: !!summary }) + } + query(this.box).find('#grid_' + this.name + '_focus').text(txt).get(0).select() + document.execCommand('copy') + } + showBubble(ind, col_ind, summary) { + let info = this.columns[col_ind].info + if (!info) return + let html = '' + let rec = this.records[ind] + let el = query(this.box).find(`${summary ? '.w2ui-grid-summary' : ''} #grid_${this.name}_data_${ind}_${col_ind} .w2ui-info`) + if (this.last.bubbleEl) { + w2tooltip.hide(this.name + '-bubble') + } + this.last.bubbleEl = el + // if no fields defined - show all + if (info.fields == null) { + info.fields = [] + for (let i = 0; i < this.columns.length; i++) { + let col = this.columns[i] + info.fields.push(col.field + (typeof col.render == 'string' ? ':' + col.render : '')) + } + } + let fields = info.fields + if (typeof fields == 'function') { + fields = fields(rec, { self: this, index: ind, colIndex: col_ind, summary: !!summary }) // custom renderer + } + // generate html + if (typeof info.render == 'function') { + html = info.render(rec, { self: this, index: ind, colIndex: col_ind, summary: !!summary }) + } else if (Array.isArray(fields)) { + // display mentioned fields + html = '' + for (let i = 0; i < fields.length; i++) { + let tmp = String(fields[i]).split(':') + if (tmp[0] == '' || tmp[0] == '-' || tmp[0] == '--' || tmp[0] == '---') { + html += '' + continue + } + let col = this.getColumn(tmp[0]) + if (col == null) col = { field: tmp[0], caption: tmp[0] } // if not found in columns + let val = (col ? this.parseField(rec, col.field) : '') + if (tmp.length > 1) { + if (w2utils.formatters[tmp[1]]) { + val = w2utils.formatters[tmp[1]](val, tmp[2] || null, rec) + } else { + console.log('ERROR: w2utils.formatters["'+ tmp[1] + '"] does not exists.') + } + } + if (info.showEmpty !== true && (val == null || val == '')) continue + if (info.maxLength != null && typeof val == 'string' && val.length > info.maxLength) val = val.substr(0, info.maxLength) + '...' + html += '' + } + html += '
    ' + col.text + '' + ((val === 0 ? '0' : val) || '') + '
    ' + } else if (w2utils.isPlainObject(fields)) { + // display some fields + html = '' + for (let caption in fields) { + let fld = fields[caption] + if (fld == '' || fld == '-' || fld == '--' || fld == '---') { + html += '' + continue + } + let tmp = String(fld).split(':') + let col = this.getColumn(tmp[0]) + if (col == null) col = { field: tmp[0], caption: tmp[0] } // if not found in columns + let val = (col ? this.parseField(rec, col.field) : '') + if (tmp.length > 1) { + if (w2utils.formatters[tmp[1]]) { + val = w2utils.formatters[tmp[1]](val, tmp[2] || null, rec) + } else { + console.log('ERROR: w2utils.formatters["'+ tmp[1] + '"] does not exists.') + } + } + if (typeof fld == 'function') { + val = fld(rec, { self: this, index: ind, colIndex: col_ind, summary: !!summary }) + } + if (info.showEmpty !== true && (val == null || val == '')) continue + if (info.maxLength != null && typeof val == 'string' && val.length > info.maxLength) val = val.substr(0, info.maxLength) + '...' + html += '' + } + html += '
    ' + caption + '' + ((val === 0 ? '0' : val) || '') + '
    ' + } + return w2tooltip.show(w2utils.extend({ + name: this.name + '-bubble', + html, + anchor: el.get(0), + position: 'top|bottom', + class: 'w2ui-info-bubble', + style: '', + hideOn: ['doc-click'] + }, info.options ?? {})) + .hide(() => [ + this.last.bubbleEl = null + ]) + } + // return null or the editable object if the given cell is editable + getCellEditable(ind, col_ind) { + let col = this.columns[col_ind] + let rec = this.records[ind] + if (!rec || !col) return null + let edit = (rec.w2ui ? rec.w2ui.editable : null) + if (edit === false) return null + if (edit == null || edit === true) { + edit = (Object.keys(col.editable ?? {}).length > 0 ? col.editable : null) + if (typeof edit === 'function') { + let value = this.getCellValue(ind, col_ind, false) + // same arguments as col.render() + edit = edit.call(this, rec, { self: this, value, index: ind, colIndex: col_ind }) + } + } + return edit + } + getCellValue(ind, col_ind, summary, extra) { + let col = this.columns[col_ind] + let record = (summary !== true ? this.records[ind] : this.summary[ind]) + let value = this.parseField(record, col.field) + let className = '', style = '', attr = '', divAttr = '' + // if change by inline editing + if (record?.w2ui?.changes?.[col.field] != null) { + value = record.w2ui.changes[col.field] + } + // if there is a cell renderer + if (col.render != null && ind !== -1) { + if (typeof col.render == 'function' && record != null) { + let html + try { + html = col.render(record, { self: this, value, index: ind, colIndex: col_ind, summary: !!summary }) + } catch (e) { + throw new Error(`Render function for column "${col.field}" in grid "${this.name}": -- ` + e.message) + } + if (html != null && typeof html == 'object' && typeof html != 'function') { + if (html.id != null && html.text != null) { + // normalized menu kind of return + value = html.text + } else if (typeof html.html == 'string') { + value = (html.html || '').trim() + } else { + value = '' + console.log('ERROR: render function should return a primitive or an object of the following structure.', + { html: '', attr: '', style: '', class: '', divAttr: '' }) + } + attr = html.attr ?? '' + style = html.style ?? '' + className = html.class ?? '' + divAttr = html.divAttr ?? '' + } else { + value = String(html || '').trim() + } + } + // if it is an object + if (typeof col.render == 'object') { + let tmp = col.render[value] + if (tmp != null && tmp !== '') { + value = tmp + } + } + // formatters + if (typeof col.render == 'string') { + let strInd = col.render.toLowerCase().indexOf(':') + let tmp = [] + if (strInd == -1) { + tmp[0] = col.render.toLowerCase() + tmp[1] = '' + } else { + tmp[0] = col.render.toLowerCase().substr(0, strInd) + tmp[1] = col.render.toLowerCase().substr(strInd + 1) + } + // formatters + let func = w2utils.formatters[tmp[0]] + if (col.options && col.options.autoFormat === false) { + func = null + } + value = (typeof func == 'function' ? func(value, tmp[1], record) : '') + } + } + if (value == null) value = '' + return !extra ? value : { value, attr, style, className, divAttr } + } + getFooterHTML() { + return '
    '+ + ' '+ + ' '+ + ' '+ + '
    ' + } + status(msg) { + if (msg != null) { + query(this.box).find(`#grid_${this.name}_footer`).find('.w2ui-footer-left').html(msg) + } else { + // show number of selected + let msgLeft = '' + let sel = this.getSelection() + if (sel.length > 0) { + if (this.show.statusSelection && sel.length > 1) { + msgLeft = String(sel.length).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1' + w2utils.settings.groupSymbol) + ' ' + w2utils.lang('selected') + } + if (this.show.statusRecordID && sel.length == 1) { + let tmp = sel[0] + if (typeof tmp == 'object') tmp = tmp.recid + ', '+ w2utils.lang('Column') +': '+ tmp.column + msgLeft = w2utils.lang('Record ID') + ': '+ tmp + ' ' + } + } + query(this.box).find('#grid_'+ this.name +'_footer .w2ui-footer-left').html(msgLeft) + } + } + lock(msg, showSpinner) { + let args = Array.from(arguments) + args.unshift(this.box) + setTimeout(() => { + // hide empty msg if any + query(this.box).find('#grid_'+ this.name +'_empty_msg').remove() + w2utils.lock(...args) + }, 10) + } + unlock(speed) { + setTimeout(() => { + // do not unlock if there is a message + if (query(this.box).find('.w2ui-message').hasClass('w2ui-closing')) return + w2utils.unlock(this.box, speed) + }, 25) // needed timer so if server fast, it will not flash + } + stateSave(returnOnly) { + let state = { + columns: [], + show: w2utils.clone(this.show), + last: { + search: this.last.search, + multi : this.last.multi, + logic : this.last.logic, + label : this.last.label, + field : this.last.field, + scrollTop : this.last.scrollTop, + scrollLeft: this.last.scrollLeft + }, + sortData : [], + searchData: [] + } + let prop_val + for (let i = 0; i < this.columns.length; i++) { + let col = this.columns[i] + let col_save_obj = {} + // iterate properties to save + Object.keys(this.stateColProps).forEach((prop, idx) => { + if (this.stateColProps[prop]){ + // check if the property is defined on the column + if (col[prop] !== undefined){ + prop_val = col[prop] + } else { + // use fallback or null + prop_val = this.colTemplate[prop] || null + } + col_save_obj[prop] = prop_val + } + }) + state.columns.push(col_save_obj) + } + for (let i = 0; i < this.sortData.length; i++) state.sortData.push(w2utils.clone(this.sortData[i])) + for (let i = 0; i < this.searchData.length; i++) state.searchData.push(w2utils.clone(this.searchData[i])) + // event before + let edata = this.trigger('stateSave', { target: this.name, state: state }) + if (edata.isCancelled === true) { + return + } + // save into local storage + if (returnOnly !== true) { + this.cacheSave('state', state) + } + // event after + edata.finish() + return state + } + stateRestore(newState) { + let url = (typeof this.url != 'object' ? this.url : this.url.get) + if (!newState) { + newState = this.cache('state') + } + // event before + let edata = this.trigger('stateRestore', { target: this.name, state: newState }) + if (edata.isCancelled === true) { + return + } + // default behavior + if (w2utils.isPlainObject(newState)) { + w2utils.extend(this.show, newState.show ?? {}) + w2utils.extend(this.last, newState.last ?? {}) + let sTop = this.last.scrollTop + let sLeft = this.last.scrollLeft + for (let c = 0; c < newState.columns?.length; c++) { + let tmp = newState.columns[c] + let col_index = this.getColumn(tmp.field, true) + if (col_index !== null) { + w2utils.extend(this.columns[col_index], tmp) + // restore column order from saved state + if (c !== col_index) this.columns.splice(c, 0, this.columns.splice(col_index, 1)[0]) + } + } + this.sortData.splice(0, this.sortData.length) + for (let c = 0; c < newState.sortData?.length; c++) { + this.sortData.push(newState.sortData[c]) + } + this.searchData.splice(0, this.searchData.length) + for (let c = 0; c < newState.searchData?.length; c++) { + this.searchData.push(newState.searchData[c]) + } + // apply sort and search + setTimeout(() => { + // needs timeout as records need to be populated + // ez 10.09.2014 this --> + if (!url) { + if (this.sortData.length > 0) this.localSort() + if (this.searchData.length > 0) this.localSearch() + } + this.last.scrollTop = sTop + this.last.scrollLeft = sLeft + this.refresh() + }, 1) + console.log(`INFO (w2ui): state restored for "${this.name}"`) + } + // event after + edata.finish() + return true + } + stateReset() { + this.stateRestore(this.last.state) + this.cacheSave('state', null) + } + parseField(obj, field) { + if (this.nestedFields) { + let val = '' + try { // need this to make sure no error in fields + val = obj + let tmp = String(field).split('.') + for (let i = 0; i < tmp.length; i++) { + val = val[tmp[i]] + } + } catch (event) { + val = '' + } + return val + } else { + return obj ? obj[field] : '' + } + } + prepareData() { + let obj = this + // loops thru records and prepares date and time objects + for (let r = 0; r < this.records.length; r++) { + let rec = this.records[r] + prepareRecord(rec) + } + // prepare date and time objects for the 'rec' record and its closed children + function prepareRecord(rec) { + for (let c = 0; c < obj.columns.length; c++) { + let column = obj.columns[c] + if (rec[column.field] == null || typeof column.render != 'string') continue + // number + if (['number', 'int', 'float', 'money', 'currency', 'percent'].indexOf(column.render.split(':')[0]) != -1) { + if (typeof rec[column.field] != 'number') rec[column.field] = parseFloat(rec[column.field]) + } + // date + if (['date', 'age'].indexOf(column.render.split(':')[0]) != -1) { + if (!rec[column.field + '_']) { + let dt = rec[column.field] + if (w2utils.isInt(dt)) dt = parseInt(dt) + rec[column.field + '_'] = new Date(dt) + } + } + // time + if (['time'].indexOf(column.render) != -1) { + if (w2utils.isTime(rec[column.field])) { // if string + let tmp = w2utils.isTime(rec[column.field], true) + let dt = new Date() + dt.setHours(tmp.hours, tmp.minutes, (tmp.seconds ? tmp.seconds : 0), 0) // sets hours, min, sec, mills + if (!rec[column.field + '_']) rec[column.field + '_'] = dt + } else { // if date object + let tmp = rec[column.field] + if (w2utils.isInt(tmp)) tmp = parseInt(tmp) + tmp = (tmp != null ? new Date(tmp) : new Date()) + let dt = new Date() + dt.setHours(tmp.getHours(), tmp.getMinutes(), tmp.getSeconds(), 0) // sets hours, min, sec, mills + if (!rec[column.field + '_']) rec[column.field + '_'] = dt + } + } + } + if (rec.w2ui?.children && rec.w2ui?.expanded !== true) { + // there are closed children, prepare them too. + for (let r = 0; r < rec.w2ui.children.length; r++) { + let subRec = rec.w2ui.children[r] + prepareRecord(subRec) + } + } + } + } + nextCell(index, col_ind, editable) { + let check = col_ind + 1 + if (check >= this.columns.length) { + index = this.nextRow(index) + return index == null ? index : this.nextCell(index, -1, editable) + } + let tmp = this.records[index].w2ui + let col = this.columns[check] + let span = (tmp && tmp.colspan && !isNaN(tmp.colspan[col.field]) ? parseInt(tmp.colspan[col.field]) : 1) + if (col == null) return null + if (col && col.hidden || span === 0) return this.nextCell(index, check, editable) + if (editable) { + let edit = this.getCellEditable(index, check) + if (edit == null || ['checkbox', 'check'].indexOf(edit.type) != -1) { + return this.nextCell(index, check, editable) + } + } + return { index, colIndex: check } + } + prevCell(index, col_ind, editable) { + let check = col_ind - 1 + if (check < 0) { + index = this.prevRow(index) + return index == null ? index : this.prevCell(index, this.columns.length, editable) + } + if (check < 0) return null + let tmp = this.records[index].w2ui + let col = this.columns[check] + let span = (tmp && tmp.colspan && !isNaN(tmp.colspan[col.field]) ? parseInt(tmp.colspan[col.field]) : 1) + if (col == null) return null + if (col && col.hidden || span === 0) return this.prevCell(index, check, editable) + if (editable) { + let edit = this.getCellEditable(index, check) + if (edit == null || ['checkbox', 'check'].indexOf(edit.type) != -1) { + return this.prevCell(index, check, editable) + } + } + return { index, colIndex: check } + } + nextRow(ind, col_ind, numRows) { + let sids = this.last.searchIds + let ret = null + if (numRows == null) numRows = 1 + if (numRows == -1) { + return this.records.length-1 + } + if ((ind + numRows < this.records.length && sids.length === 0) // if there are more records + || (sids.length > 0 && ind < sids[sids.length-numRows])) { + ind += numRows + if (sids.length > 0) while (true) { + if (sids.includes(ind) || ind > this.records.length) break + ind += numRows + } + // colspan + let tmp = this.records[ind].w2ui + let col = this.columns[col_ind] + let span = (tmp && tmp.colspan && col != null && !isNaN(tmp.colspan[col.field]) ? parseInt(tmp.colspan[col.field]) : 1) + if (span === 0) { + ret = this.nextRow(ind, col_ind, numRows) + } else { + ret = ind + } + } + return ret + } + prevRow(ind, col_ind, numRows) { + let sids = this.last.searchIds + let ret = null + if (numRows == null) numRows = 1 + if (numRows == -1) { + return 0 + } + if ((ind - numRows >= 0 && sids.length === 0) // if there are more records + || (sids.length > 0 && ind > sids[0])) { + ind -= numRows + if (sids.length > 0) while (true) { + if (sids.includes(ind) || ind < 0) break + ind -= numRows + } + // colspan + let tmp = this.records[ind].w2ui + let col = this.columns[col_ind] + let span = (tmp && tmp.colspan && col != null && !isNaN(tmp.colspan[col.field]) ? parseInt(tmp.colspan[col.field]) : 1) + if (span === 0) { + ret = this.prevRow(ind, col_ind, numRows) + } else { + ret = ind + } + } + return ret + } + selectionSave() { + this.last.saved_sel = this.getSelection() + return this.last.saved_sel + } + selectionRestore(noRefresh) { + let time = Date.now() + this.last.selection = { indexes: [], columns: {} } + let sel = this.last.selection + let lst = this.last.saved_sel + if (lst) for (let i = 0; i < lst.length; i++) { + if (w2utils.isPlainObject(lst[i])) { + // selectType: cell + let tmp = this.get(lst[i].recid, true) + if (tmp != null) { + if (sel.indexes.indexOf(tmp) == -1) sel.indexes.push(tmp) + if (!sel.columns[tmp]) sel.columns[tmp] = [] + sel.columns[tmp].push(lst[i].column) + } + } else { + // selectType: row + let tmp = this.get(lst[i], true) + if (tmp != null) sel.indexes.push(tmp) + } + } + delete this.last.saved_sel + if (noRefresh !== true) this.refresh() + return Date.now() - time + } + message(options) { + return w2utils.message({ + owner: this, + box : this.box, + after: '.w2ui-grid-header' + }, options) + } + confirm(options) { + return w2utils.confirm({ + owner: this, + box : this.box, + after: '.w2ui-grid-header' + }, options) + } +} + +/** + * Part of w2ui 2.0 library + * - Dependencies: mQuery, w2utils, w2base, w2tabs, w2toolbar, w2tooltip, w2field + * + * == TODO == + * - include delta on save + * - tabs below some fields (could already be implemented) + * - form with toolbar & tabs + * - promise for load, save, etc. + * + * == 2.0 changes + * - CSP - fixed inline events + * - removed jQuery dependency + * - better groups support tabs now + * - form.confirm - refactored + * - form.message - refactored + * - observeResize for the box + * - removed msgNotJSON, msgAJAXerror + * - applyFocus -> setFocus + * - getFieldValue(fieldName) = returns { curent, previous, original } + * - setFieldVallue(fieldName, value) + * - getValue(..., original) -- return original if any + * - added .hideErrors() + * - reuqest, save, submit - return promises + * - this.recid = null if no record needs to be pulled + * - remove form.multiplart + * - this.method - for saving only + */ + +class w2form extends w2base { + constructor(options) { + super(options.name) + this.name = null + this.header = '' + this.box = null // HTML element that hold this element + this.url = '' + this.method = null // if defined, it will be http method when saving + this.routeData = {} // data for dynamic routes + this.formURL = '' // url where to get form HTML + this.formHTML = '' // form HTML (might be loaded from the url) + this.page = 0 // current page + this.pageStyle = '' + this.recid = null // if not null, then load record + this.fields = [] + this.actions = {} + this.record = {} + this.original = null + this.dataType = null // only used when not null, otherwise from w2utils.settings.dataType + this.postData = {} + this.httpHeaders = {} + this.toolbar = {} // if not empty, then it is toolbar + this.tabs = {} // if not empty, then it is tabs object + this.style = '' + this.focus = 0 // focus first or other element + this.autosize = true // autosize, if false the container must have a height set + this.nestedFields = true // use field name containing dots as separator to look into object + this.tabindexBase = 0 // this will be added to the auto numbering + this.isGenerated = false + this.last = { + fetchCtrl: null, // last fetch AbortController + fetchOptions: null, // last fetch options + errors: [] + } + this.onRequest = null + this.onLoad = null + this.onValidate = null + this.onSubmit = null + this.onProgress = null + this.onSave = null + this.onChange = null + this.onInput = null + this.onRender = null + this.onRefresh = null + this.onResize = null + this.onDestroy = null + this.onAction = null + this.onToolbar = null + this.onError = null + this.msgRefresh = 'Loading...' + this.msgSaving = 'Saving...' + this.msgServerError = 'Server error' + this.ALL_TYPES = [ 'text', 'textarea', 'email', 'pass', 'password', 'int', 'float', 'money', 'currency', + 'percent', 'hex', 'alphanumeric', 'color', 'date', 'time', 'datetime', 'toggle', 'checkbox', 'radio', + 'check', 'checks', 'list', 'combo', 'enum', 'file', 'select', 'map', 'array', 'div', 'custom', 'html', + 'empty'] + this.LIST_TYPES = ['select', 'radio', 'check', 'checks', 'list', 'combo', 'enum'] + this.W2FIELD_TYPES = ['int', 'float', 'money', 'currency', 'percent', 'hex', 'alphanumeric', 'color', + 'date', 'time', 'datetime', 'list', 'combo', 'enum', 'file'] + // mix in options + w2utils.extend(this, options) + // remember items + let record = options.record + let original = options.original + let fields = options.fields + let toolbar = options.toolbar + let tabs = options.tabs + // extend items + Object.assign(this, { record: {}, original: null, fields: [], tabs: {}, toolbar: {}, handlers: [] }) + // preprocess fields + if (fields) { + let sub =_processFields(fields) + this.fields = sub.fields + if (!tabs && sub.tabs.length > 0) { + tabs = sub.tabs + } + } + // prepare tabs + if (Array.isArray(tabs)) { + w2utils.extend(this.tabs, { tabs: [] }) + for (let t = 0; t < tabs.length; t++) { + let tmp = tabs[t] + if (typeof tmp === 'object') { + this.tabs.tabs.push(tmp) + if (tmp.active === true) { + this.tabs.active = tmp.id + } + } else { + this.tabs.tabs.push({ id: tmp, text: tmp }) + } + } + } else { + w2utils.extend(this.tabs, tabs) + } + w2utils.extend(this.toolbar, toolbar) + for (let p in record) { // it is an object + if (w2utils.isPlainObject(record[p])) { + this.record[p] = w2utils.clone(record[p]) + } else { + this.record[p] = record[p] + } + } + for (let p in original) { // it is an object + if (w2utils.isPlainObject(original[p])) { + this.original[p] = w2utils.clone(original[p]) + } else { + this.original[p] = original[p] + } + } + // generate html if necessary + if (this.formURL !== '') { + fetch(this.formURL) + .then(resp => resp.text()) + .then(text => { + this.formHTML = text + this.isGenerated = true + if (this.box) this.render(this.box) + }) + } else if (!this.formURL && !this.formHTML) { + this.formHTML = this.generateHTML() + this.isGenerated = true + } else if (this.formHTML) { + this.isGenerated = true + } + // render if box specified + if (typeof this.box == 'string') this.box = query(this.box).get(0) + if (this.box) this.render(this.box) + function _processFields(fields) { + let newFields = [] + let tabs = [] + // if it is an object + if (w2utils.isPlainObject(fields)) { + let tmp = fields + fields = [] + Object.keys(tmp).forEach((key) => { + let fld = tmp[key] + if (fld.type == 'group') { + fld.text = key + if (w2utils.isPlainObject(fld.fields)) { + let tmp2 = fld.fields + fld.fields = [] + Object.keys(tmp2).forEach((key2) => { + let fld2 = tmp2[key2] + fld2.field = key2 + fld.fields.push(_process(fld2)) + }) + } + fields.push(fld) + } else if (fld.type == 'tab') { + // add tab + let tab = { id: key, text: key } + if (fld.style) { + tab.style = fld.style + } + tabs.push(tab) + // add page to fields + let sub = _processFields(fld.fields).fields + sub.forEach(fld2 => { + fld2.html = fld2.html || {} + fld2.html.page = tabs.length -1 + _process2(fld, fld2) + }) + fields.push(...sub) + } else { + fld.field = key + fields.push(_process(fld)) + } + }) + function _process(fld) { + let ignore = ['html'] + if (fld.html == null) fld.html = {} + Object.keys(fld).forEach((key => { + if (ignore.indexOf(key) != -1) return + if (['label', 'attr', 'style', 'text', 'span', 'page', 'column', 'anchor', + 'group', 'groupStyle', 'groupTitleStyle', 'groupCollapsible'].indexOf(key) != -1) { + fld.html[key] = fld[key] + delete fld[key] + } + })) + return fld + } + function _process2(fld, fld2) { + let ignore = ['style', 'html'] + Object.keys(fld).forEach((key => { + if (ignore.indexOf(key) != -1) return + if (['span', 'column', 'attr', 'text', 'label'].indexOf(key) != -1) { + if (fld[key] && !fld2.html[key]) { + fld2.html[key] = fld[key] + } + } + })) + } + } + // process groups + fields.forEach(field => { + if (field.type == 'group') { + // group properties + let group = { + group: field.text || '', + groupStyle: field.style || '', + groupTitleStyle: field.titleStyle || '', + groupCollapsible: field.collapsible === true ? true : false, + } + // loop through fields + if (Array.isArray(field.fields)) { + field.fields.forEach(gfield => { + let fld = w2utils.clone(gfield) + if (fld.html == null) fld.html = {} + w2utils.extend(fld.html, group) + Array('span', 'column', 'attr', 'label', 'page').forEach(key => { + if (fld.html[key] == null && field[key] != null) { + fld.html[key] = field[key] + } + }) + if (fld.field == null && fld.name != null) { + console.log('NOTICE: form field.name property is deprecated, please use field.field. Field ->', field) + fld.field = fld.name + } + newFields.push(fld) + }) + } + } else { + let fld = w2utils.clone(field) + if (fld.field == null && fld.name != null) { + console.log('NOTICE: form field.name property is deprecated, please use field.field. Field ->', field) + fld.field = fld.name + } + newFields.push(fld) + } + }) + return { fields: newFields, tabs } + } + } + get(field, returnIndex) { + if (arguments.length === 0) { + let all = [] + for (let f1 = 0; f1 < this.fields.length; f1++) { + if (this.fields[f1].field != null) all.push(this.fields[f1].field) + } + return all + } else { + for (let f2 = 0; f2 < this.fields.length; f2++) { + if (this.fields[f2].field == field) { + if (returnIndex === true) return f2; else return this.fields[f2] + } + } + return null + } + } + set(field, obj) { + for (let f = 0; f < this.fields.length; f++) { + if (this.fields[f].field == field) { + w2utils.extend(this.fields[f] , obj) + this.refresh(field) + return true + } + } + return false + } + getValue(field, original) { + if (this.nestedFields) { + let val = undefined + try { // need this to make sure no error in fields + let rec = original === true ? this.original : this.record + val = String(field).split('.').reduce((rec, i) => { return rec[i] }, rec) + } catch (event) { + } + return val + } else { + return this.record[field] + } + } + setValue(field, value) { + // will not refresh the form! + if (value === '' || value == null + || (Array.isArray(value) && value.length === 0) + || (w2utils.isPlainObject(value) && Object.keys(value).length == 0)) { + value = null + } + if (this.nestedFields) { + try { // need this to make sure no error in fields + let rec = this.record + String(field).split('.').map((fld, i, arr) => { + if (arr.length - 1 !== i) { + if (rec[fld]) rec = rec[fld]; else { rec[fld] = {}; rec = rec[fld] } + } else { + rec[fld] = value + } + }) + return true + } catch (event) { + return false + } + } else { + this.record[field] = value + return true + } + } + getFieldValue(name) { + let field = this.get(name) + if (field == null) return + let el = field.el + let previous = this.getValue(name) + let original = this.getValue(name, true) + // orginary input control + let current = el.value + // should not be set to '', incosistent logic + // if (previous == null) previous = '' + // clean extra chars + if (['int', 'float', 'percent', 'money', 'currency'].includes(field.type)) { + current = field.w2field.clean(current) + } + // radio list + if (['radio'].includes(field.type)) { + let selected = query(el).closest('div').find('input:checked').get(0) + if (selected) { + let item = field.options.items[query(selected).data('index')] + current = item.id + } else { + current = null + } + } + // single checkbox + if (['toggle', 'checkbox'].includes(field.type)) { + current = el.checked + } + // check list + if (['check', 'checks'].indexOf(field.type) !== -1) { + current = [] + let selected = query(el).closest('div').find('input:checked') + if (selected.length > 0) { + selected.each(el => { + let item = field.options.items[query(el).data('index')] + current.push(item.id) + }) + } + if (!Array.isArray(previous)) previous = [] + } + // lists + let selected = el._w2field?.selected // drop downs and other w2field objects + if (['list', 'enum', 'file'].includes(field.type) && selected) { + // TODO: check when w2field is refactored + let nv = selected + let cv = previous + if (Array.isArray(nv)) { + current = [] + for (let i = 0; i < nv.length; i++) current[i] = w2utils.clone(nv[i]) // clone array + } + if (Array.isArray(cv)) { + previous = [] + for (let i = 0; i < cv.length; i++) previous[i] = w2utils.clone(cv[i]) // clone array + } + if (w2utils.isPlainObject(nv)) { + current = w2utils.clone(nv) // clone object + } + if (w2utils.isPlainObject(cv)) { + previous = w2utils.clone(cv) // clone object + } + } + // map, array + if (['map', 'array'].includes(field.type)) { + current = (field.type == 'map' ? {} : []) + field.$el.parent().find('.w2ui-map-field').each(div => { + let key = query(div).find('.w2ui-map.key').val() + let value = query(div).find('.w2ui-map.value').val() + if (field.type == 'map') { + current[key] = value + } else { + current.push(value) + } + }) + } + return { current, previous, original } // current - in input, previous - in form.record, original - before form change + } + setFieldValue(name, value) { + let field = this.get(name) + if (field == null) return + let el = field.el + switch (field.type) { + case 'toggle': + case 'checkbox': + el.checked = value ? true : false + break + case 'radio': { + value = value?.id ?? value + let inputs = query(el).closest('div').find('input') + let items = field.options.items + items.forEach((it, ind) => { + if (it.id === value) { // need exact match so to match empty string and 0 + inputs.filter(`[data-index="${ind}"]`).prop('checked', true) + } + }) + break + } + case 'check': + case 'checks': { + if (!Array.isArray(value)) { + if (value != null) { + value = [value] + } else { + value = [] + } + } + value = value.map(val => val?.id ?? val) // convert if array of objects + let inputs = query(el).closest('div').find('input') + let items = field.options.items + items.forEach((it, ind) => { + inputs.filter(`[data-index="${ind}"]`).prop('checked', value.includes(it.id) ? true : false) + }) + break + } + case 'list': + case 'combo': + let item = value + // find item in options.items, if any + if (item?.id == null && Array.isArray(field.options?.items)) { + field.options.items.forEach(it => { + if (it.id === value) item = it + }) + } + // if item is found in field.options, update it in the this.records + if (item != value) { + this.setValue(field.name, item) + } + if (field.type == 'list') { + field.w2field.selected = item + field.w2field.refresh() + } else { + field.el.value = item?.text ?? value + } + break + case 'enum': + case 'file': { + if (!Array.isArray(value)) { + value = value != null ? [value] : [] + } + let items = [...value] + // find item in options.items, if any + let updated = false + items.forEach((item, ind) => { + if (item?.id == null && Array.isArray(field.options.items)) { + field.options.items.forEach(it => { + if (it.id == item) { + items[ind] = it + updated = true + } + }) + } + }) + if (updated) { + this.setValue(field.name, items) + } + field.w2field.selected = items + field.w2field.refresh() + break + } + case 'map': + case 'array': { + // init map + if (field.type == 'map' && (value == null || !w2utils.isPlainObject(value))) { + this.setValue(field.field, {}) + value = this.getValue(field.field) + } + if (field.type == 'array' && (value == null || !Array.isArray(value))) { + this.setValue(field.field, []) + value = this.getValue(field.field) + } + let container = query(field.el).parent().find('.w2ui-map-container') + field.el.mapRefresh(value, container) + break + } + case 'div': + case 'custom': + query(el).html(value) + break + case 'html': + case 'empty': + break + default: + // regular text fields + el.value = value ?? '' + break + } + } + show() { + let effected = [] + for (let a = 0; a < arguments.length; a++) { + let fld = this.get(arguments[a]) + if (fld && fld.hidden) { + fld.hidden = false + effected.push(fld.field) + } + } + if (effected.length > 0) this.refresh.apply(this, effected) + this.updateEmptyGroups() + return effected + } + hide() { + let effected = [] + for (let a = 0; a < arguments.length; a++) { + let fld = this.get(arguments[a]) + if (fld && !fld.hidden) { + fld.hidden = true + effected.push(fld.field) + } + } + if (effected.length > 0) this.refresh.apply(this, effected) + this.updateEmptyGroups() + return effected + } + enable() { + let effected = [] + for (let a = 0; a < arguments.length; a++) { + let fld = this.get(arguments[a]) + if (fld && fld.disabled) { + fld.disabled = false + effected.push(fld.field) + } + } + if (effected.length > 0) this.refresh.apply(this, effected) + return effected + } + disable() { + let effected = [] + for (let a = 0; a < arguments.length; a++) { + let fld = this.get(arguments[a]) + if (fld && !fld.disabled) { + fld.disabled = true + effected.push(fld.field) + } + } + if (effected.length > 0) this.refresh.apply(this, effected) + return effected + } + updateEmptyGroups() { + // hide empty groups + query(this.box).find('.w2ui-group').each((group) =>{ + if (isHidden(query(group).find('.w2ui-field'))) { + query(group).hide() + } else { + query(group).show() + } + }) + function isHidden($els) { + let flag = true + $els.each((el) => { + if (el.style.display != 'none') flag = false + }) + return flag + } + } + change() { + Array.from(arguments).forEach((field) => { + let tmp = this.get(field) + if (tmp.$el) tmp.$el.change() + }) + } + reload(callBack) { + let url = (typeof this.url !== 'object' ? this.url : this.url.get) + if (url && this.recid != null) { + // this.clear(); + return this.request(callBack) // returns promise + } else { + // this.refresh(); // no need to refresh + if (typeof callBack === 'function') callBack() + return new Promise(resolve => { resolve() }) // resolved promise + } + } + clear() { + if (arguments.length != 0) { + Array.from(arguments).forEach((field) => { + let rec = this.record + String(field).split('.').map((fld, i, arr) => { + if (arr.length - 1 !== i) rec = rec[fld]; else delete rec[fld] + }) + this.refresh(field) + }) + } else { + this.recid = null + this.record = {} + this.original = null + this.refresh() + this.hideErrors() + } + } + error(msg) { + // let the management of the error outside of the form + let edata = this.trigger('error', { + target: this.name, + message: msg, + fetchCtrl: this.last.fetchCtrl, + fetchOptions: this.last.fetchOptions + }) + if (edata.isCancelled === true) return + // need a time out because message might be already up) + setTimeout(() => { this.message(msg) }, 1) + // event after + edata.finish() + } + message(options) { + return w2utils.message({ + owner: this, + box : this.box, + after: '.w2ui-form-header' + }, options) + } + confirm(options) { + return w2utils.confirm({ + owner: this, + box : this.box, + after: '.w2ui-form-header' + }, options) + } + validate(showErrors) { + if (showErrors == null) showErrors = true + // validate before saving + let errors = [] + for (let f = 0; f < this.fields.length; f++) { + let field = this.fields[f] + if (this.getValue(field.field) == null) this.setValue(field.field, '') + if (['int', 'float', 'currency', 'money'].indexOf(field.type) != -1) { + let val = this.getValue(field.field) + let min = field.options.min + let max = field.options.max + if (min != null && val < min) { + errors.push({ field: field, error: w2utils.lang('Should be more than ${min}', { min }) }) + } + if (max != null && val > max) { + errors.push({ field: field, error: w2utils.lang('Should be less than ${max}', { max }) }) + } + } + switch (field.type) { + case 'alphanumeric': + if (this.getValue(field.field) && !w2utils.isAlphaNumeric(this.getValue(field.field))) { + errors.push({ field: field, error: w2utils.lang('Not alpha-numeric') }) + } + break + case 'int': + if (this.getValue(field.field) && !w2utils.isInt(this.getValue(field.field))) { + errors.push({ field: field, error: w2utils.lang('Not an integer') }) + } + break + case 'percent': + case 'float': + if (this.getValue(field.field) && !w2utils.isFloat(this.getValue(field.field))) { + errors.push({ field: field, error: w2utils.lang('Not a float') }) + } + break + case 'currency': + case 'money': + if (this.getValue(field.field) && !w2utils.isMoney(this.getValue(field.field))) { + errors.push({ field: field, error: w2utils.lang('Not in money format') }) + } + break + case 'color': + case 'hex': + if (this.getValue(field.field) && !w2utils.isHex(this.getValue(field.field))) { + errors.push({ field: field, error: w2utils.lang('Not a hex number') }) + } + break + case 'email': + if (this.getValue(field.field) && !w2utils.isEmail(this.getValue(field.field))) { + errors.push({ field: field, error: w2utils.lang('Not a valid email') }) + } + break + case 'checkbox': + // convert true/false + if (this.getValue(field.field) == true) { + this.setValue(field.field, true) + } else { + this.setValue(field.field, false) + } + break + case 'date': + // format date before submit + if (!field.options.format) field.options.format = w2utils.settings.dateFormat + if (this.getValue(field.field) && !w2utils.isDate(this.getValue(field.field), field.options.format)) { + errors.push({ field: field, error: w2utils.lang('Not a valid date') + ': ' + field.options.format }) + } + break + case 'list': + case 'combo': + break + case 'enum': + break + } + // === check required - if field is '0' it should be considered not empty + let val = this.getValue(field.field) + if (field.hidden !== true && field.required + && !['div', 'custom', 'html', 'empty'].includes(field.type) + && (val == null || val === '' || (Array.isArray(val) && val.length === 0) + || (w2utils.isPlainObject(val) && Object.keys(val).length == 0))) { + errors.push({ field: field, error: w2utils.lang('Required field') }) + } + if (field.hidden !== true && field.options?.minLength > 0 + && !['enum', 'list', 'combo'].includes(field.type) // since minLength is used there for other purpose + && (val == null || val.length < field.options.minLength)) { + errors.push({ field: field, error: w2utils.lang('Field should be at least ${count} characters.', + { count: field.options.minLength })}) + } + } + // event before + let edata = this.trigger('validate', { target: this.name, errors: errors }) + if (edata.isCancelled === true) return + // show error + this.last.errors = errors + if (showErrors) this.showErrors() + // event after + edata.finish() + return errors + } + showErrors() { + // TODO: check edge cases + // -- scroll + // -- invisible pages + // -- form refresh + let errors = this.last.errors + if (errors.length <= 0) return + // show errors + this.goto(errors[0].field.page) + query(errors[0].field.$el).parents('.w2ui-field')[0].scrollIntoView({ block: 'nearest', inline: 'nearest' }) + // show errors + // show only for visible controls + errors.forEach(error => { + let opt = w2utils.extend({ + anchorClass: 'w2ui-error', + class: 'w2ui-light', + position: 'right|left', + hideOn: ['input'] + }, error.options) + if (error.field == null) return + let anchor = error.field.el + if (error.field.type === 'radio') { // for radio and checkboxes + anchor = query(error.field.el).closest('div').get(0) + } else if (['enum', 'file'].includes(error.field.type)) { + // TODO: check + // anchor = (error.field.el).data('w2field').helpers.multi + // $(fld).addClass('w2ui-error') + } + w2tooltip.show(w2utils.extend({ + anchor, + name: `${this.name}-${error.field.field}-error`, + html: error.error + }, opt)) + }) + // hide errors on scroll + query(errors[0].field.$el).parents('.w2ui-page') + .off('.hideErrors') + .on('scroll.hideErrors', (evt) => { this.hideErrors() }) + } + hideErrors() { + this.fields.forEach(field => { + w2tooltip.hide(`${this.name}-${field.field}-error`) + }) + } + getChanges() { + // TODO: not working on nested structures + let diff = {} + if (this.original != null && typeof this.original == 'object' && Object.keys(this.record).length !== 0) { + diff = doDiff(this.record, this.original, {}) + } + return diff + function doDiff(record, original, result) { + if (Array.isArray(record) && Array.isArray(original)) { + while (record.length < original.length) { + record.push(null) + } + } + for (let i in record) { + if (record[i] != null && typeof record[i] === 'object') { + result[i] = doDiff(record[i], original[i] || {}, {}) + if (!result[i] || (Object.keys(result[i]).length == 0 && Object.keys(original[i].length == 0))) delete result[i] + } else if (record[i] != original[i] || (record[i] == null && original[i] != null)) { // also catch field clear + result[i] = record[i] + } + } + return Object.keys(result).length != 0 ? result : null + } + } + getCleanRecord(strict) { + let data = w2utils.clone(this.record) + this.fields.forEach((fld) => { + if (['list', 'combo', 'enum'].indexOf(fld.type) != -1) { + let tmp = { nestedFields: true, record: data } + let val = this.getValue.call(tmp, fld.field) + if (w2utils.isPlainObject(val) && val.id != null) { // should be true if val.id === '' + this.setValue.call(tmp, fld.field, val.id) + } + if (Array.isArray(val)) { + val.forEach((item, ind) => { + if (w2utils.isPlainObject(item) && item.id) { + val[ind] = item.id + } + }) + } + } + if (fld.type == 'map') { + let tmp = { nestedFields: true, record: data } + let val = this.getValue.call(tmp, fld.field) + if (val._order) delete val._order + } + if (fld.type == 'file') { + let tmp = { nestedFields: true, record: data } + let val = this.getValue.call(tmp, fld.field) ?? [] + val.forEach(v => { + delete v.file + delete v.modified + }) + this.setValue.call(tmp, fld.field, val) + } + }) + // return only records present in description + if (strict === true) { + Object.keys(data).forEach((key) => { + if (!this.get(key)) delete data[key] + }) + } + return data + } + request(postData, callBack) { // if (1) param then it is call back if (2) then postData and callBack + let self = this + let resolve, reject + let responseProm = new Promise((res, rej) => { resolve = res; reject = rej }) + // check for multiple params + if (typeof postData === 'function') { + callBack = postData + postData = null + } + if (postData == null) postData = {} + if (!this.url || (typeof this.url === 'object' && !this.url.get)) return + // build parameters list + let params = {} + // add list params + params.action = 'get' + params.recid = this.recid + params.name = this.name + // append other params + w2utils.extend(params, this.postData) + w2utils.extend(params, postData) + // event before + let edata = this.trigger('request', { target: this.name, url: this.url, httpMethod: 'GET', + postData: params, httpHeaders: this.httpHeaders }) + if (edata.isCancelled === true) return + // default action + this.record = {} + this.original = null + // call server to get data + this.lock(w2utils.lang(this.msgRefresh)) + let url = edata.detail.url + if (typeof url === 'object' && url.get) url = url.get + if (this.last.fetchCtrl) try { this.last.fetchCtrl.abort() } catch (e) {} + // process url with routeData + if (Object.keys(this.routeData).length != 0) { + let info = w2utils.parseRoute(url) + if (info.keys.length > 0) { + for (let k = 0; k < info.keys.length; k++) { + if (this.routeData[info.keys[k].name] == null) continue + url = url.replace((new RegExp(':'+ info.keys[k].name, 'g')), this.routeData[info.keys[k].name]) + } + } + } + url = new URL(url, location) + let fetchOptions = w2utils.prepareParams(url, { + method: edata.detail.httpMethod, + headers: edata.detail.httpHeaders, + body: edata.detail.postData + }, this.dataType) + this.last.fetchCtrl = new AbortController() + fetchOptions.signal = this.last.fetchCtrl.signal + this.last.fetchOptions = fetchOptions + fetch(url, fetchOptions) + .catch(processError) + .then((resp) => { + if (resp?.status != 200) { + // if resp is undefined, it means request was aborted + if (resp) processError(resp) + return + } + resp.json() + .catch(processError) + .then(data => { + // event before + let edata = self.trigger('load', { + target: self.name, + fetchCtrl: this.last.fetchCtrl, + fetchOptions: this.last.fetchOptions, + data + }) + if (edata.isCancelled === true) return + // for backward compatibility + if (data.error == null && data.status === 'error') { + data.error = true + } + // if data.record is not present, then assume that entire response is the record + if (!data.record) { + Object.assign(data, { record: w2utils.clone(data) }) + } + // server response error, not due to network issues + if (data.error === true) { + self.error(w2utils.lang(data.message ?? this.msgServerError)) + } else { + self.record = w2utils.clone(data.record) + } + // event after + self.unlock() + edata.finish() + self.refresh() + self.setFocus() + // call back + if (typeof callBack === 'function') callBack(data) + resolve(data) + }) + }) + // event after + edata.finish() + return responseProm + function processError(response) { + if (response.name === 'AbortError') { + // request was aborted by the form + return + } + self.unlock() + // trigger event + let edata2 = self.trigger('error', { response, fetchCtrl: self.last.fetchCtrl, fetchOptions: self.last.fetchOptions }) + if (edata2.isCancelled === true) return + // default behavior + if (response.status && response.status != 200) { + self.error(response.status + ': ' + response.statusText) + } else { + console.log('ERROR: Server request failed.', response, '. ', + 'Expected Response:', { error: false, record: { field1: 1, field2: 'item' }}, + 'OR:', { error: true, message: 'Error description' }) + self.error(String(response)) + } + // event after + edata2.finish() + reject(response) + } + } + submit(postData, callBack) { + return this.save(postData, callBack) + } + save(postData, callBack) { + let self = this + let resolve, reject + let saveProm = new Promise((res, rej) => { resolve = res; reject = rej }) + // check for multiple params + if (typeof postData === 'function') { + callBack = postData + postData = null + } + // validation + let errors = self.validate(true) + if (errors.length !== 0) return + // submit save + if (postData == null) postData = {} + if (!self.url || (typeof self.url === 'object' && !self.url.save)) { + console.log('ERROR: Form cannot be saved because no url is defined.') + return + } + self.lock(w2utils.lang(self.msgSaving) + ' ') + // build parameters list + let params = {} + // add list params + params.action = 'save' + params.recid = self.recid + params.name = self.name + // append other params + w2utils.extend(params, self.postData) + w2utils.extend(params, postData) + params.record = w2utils.clone(self.record) + // event before + let edata = self.trigger('submit', { target: self.name, url: self.url, httpMethod: this.method ?? 'POST', + postData: params, httpHeaders: self.httpHeaders }) + if (edata.isCancelled === true) return + // default action + let url = edata.detail.url + if (typeof url === 'object' && url.save) url = url.save + if (self.last.fetchCtrl) self.last.fetchCtrl.abort() + // process url with routeData + if (Object.keys(self.routeData).length > 0) { + let info = w2utils.parseRoute(url) + if (info.keys.length > 0) { + for (let k = 0; k < info.keys.length; k++) { + if (self.routeData[info.keys[k].name] == null) continue + url = url.replace((new RegExp(':'+ info.keys[k].name, 'g')), self.routeData[info.keys[k].name]) + } + } + } + url = new URL(url, location) + let fetchOptions = w2utils.prepareParams(url, { + method: edata.detail.httpMethod, + headers: edata.detail.httpHeaders, + body: edata.detail.postData + }, this.dataType) + this.last.fetchCtrl = new AbortController() + fetchOptions.signal = this.last.fetchCtrl.signal + this.last.fetchOptions = fetchOptions + fetch(url, fetchOptions) + .catch(processError) + .then(resp => { + self.unlock() + if (resp?.status != 200) { + processError(resp ?? {}) + return + } + // parse server response + resp.json() + .catch(processError) + .then(data => { + // event before + let edata = self.trigger('save', { + target: self.name, + fetchCtrl: this.last.fetchCtrl, + fetchOptions: this.last.fetchOptions, + data + }) + if (edata.isCancelled === true) return + // server error, not due to network issues + if (data.error === true) { + self.error(w2utils.lang(data.message ?? this.msgServerError)) + } else { + self.original = null + } + // event after + edata.finish() + self.refresh() + // call back + if (typeof callBack === 'function') callBack(data) + resolve(data) + }) + }) + // event after + edata.finish() + return saveProm + function processError(response) { + if (response?.name === 'AbortError') { + // request was aborted by the form + return + } + self.unlock() + // trigger event + let edata2 = self.trigger('error', { response, fetchCtrl: self.last.fetchCtrl, fetchOptions: self.last.fetchOptions }) + if (edata2.isCancelled === true) return + // default behavior + if (response.status && response.status != 200) { + self.error(response.status + ': ' + response.statusText) + } else { + console.log('ERROR: Server request failed.', response, '. ', + 'Expected Response:', { error: false, record: { field1: 1, field2: 'item' }}, + 'OR:', { error: true, message: 'Error description' }) + self.error(String(response)) + } + // event after + edata2.finish() + reject() + } + } + lock(msg, showSpinner) { + let args = Array.from(arguments) + args.unshift(this.box) + w2utils.lock(...args) + } + unlock(speed) { + let box = this.box + w2utils.unlock(box, speed) + } + lockPage(page, msg, spinner) { + let $page = query(this.box).find('.page-' + page) + if ($page.length){ + // page found + w2utils.lock($page, msg, spinner) + return true + } + // page with this id not found! + return false + } + unlockPage(page, speed) { + let $page = query(this.box).find('.page-' + page) + if ($page.length) { + // page found + w2utils.unlock($page, speed) + return true + } + // page with this id not found! + return false + } + goto(page) { + if (this.page === page) return // already on this page + if (page != null) this.page = page + // if it was auto size, resize it + if (query(this.box).data('autoSize') === true) { + query(this.box).get(0).clientHeight = 0 + } + this.refresh() + } + generateHTML() { + let pages = [] // array for each page + let group = '' + let page + let column + let html + let tabindex + let tabindex_str + for (let f = 0; f < this.fields.length; f++) { + html = '' + tabindex = this.tabindexBase + f + 1 + tabindex_str = ' tabindex="'+ tabindex +'"' + let field = this.fields[f] + if (field.html == null) field.html = {} + if (field.options == null) field.options = {} + if (field.html.caption != null && field.html.label == null) { + console.log('NOTICE: form field.html.caption property is deprecated, please use field.html.label. Field ->', field) + field.html.label = field.html.caption + } + if (field.html.label == null) field.html.label = field.field + field.html = w2utils.extend({ label: '', span: 6, attr: '', text: '', style: '', page: 0, column: 0 }, field.html) + if (page == null) page = field.html.page + if (column == null) column = field.html.column + // input control + let input = `` + switch (field.type) { + case 'pass': + case 'password': + input = input.replace('type="text"', 'type="password"') + break + case 'checkbox': { + input = ` + ` + break + } + case 'check': + case 'checks': { + if (field.options.items == null && field.html.items != null) field.options.items = field.html.items + let items = field.options.items + input = '' + // normalized options + if (!Array.isArray(items)) items = [] + if (items.length > 0) { + items = w2utils.normMenu.call(this, items, field) + } + // generate + for (let i = 0; i < items.length; i++) { + input += ` + +
    ` + } + break + } + case 'radio': { + input = '' + // normalized options + if (field.options.items == null && field.html.items != null) field.options.items = field.html.items + let items = field.options.items + if (!Array.isArray(items)) items = [] + if (items.length > 0) { + items = w2utils.normMenu.call(this, items, field) + } + // generate + for (let i = 0; i < items.length; i++) { + input += ` + +
    ` + } + break + } + case 'select': { + input = `' + break + } + case 'textarea': + input = `` + break + case 'toggle': + input = ` +
    ` + break + case 'map': + case 'array': + field.html.key = field.html.key || {} + field.html.value = field.html.value || {} + field.html.tabindex_str = tabindex_str + input = '' + (field.html.text || '') + '' + + ''+ + '
    ' + break + case 'div': + case 'custom': + input = '
    '+ + (field && field.html && field.html.html ? field.html.html : '') + + '
    ' + break + case 'html': + case 'empty': + input = (field && field.html ? (field.html.html || '') + (field.html.text || '') : '') + break + } + if (group !== '') { + if (page != field.html.page || column != field.html.column || (field.html.group && (group != field.html.group))) { + pages[page][column] += '\n
    \n
    ' + group = '' + } + } + if (field.html.group && (group != field.html.group)) { + let collapsible = '' + if (field.html.groupCollapsible) { + collapsible = '' + } + html += '\n
    ' + + '\n
    ' + + collapsible + w2utils.lang(field.html.group) + '
    \n' + + '
    ' + group = field.html.group + } + if (field.html.anchor == null) { + let span = (field.html.span != null ? 'w2ui-span'+ field.html.span : '') + if (field.html.span == -1) span = 'w2ui-span-none' + let label = '' + w2utils.lang(field.type != 'checkbox' ? field.html.label : field.html.text) +'' + if (!field.html.label) label = '' + html += '\n
    '+ + '\n '+ label + + ((field.type === 'empty') ? input : '\n
    '+ input + (field.type != 'array' && field.type != 'map' ? w2utils.lang(field.type != 'checkbox' ? field.html.text : '') : '') + '
    ') + + '\n
    ' + } else { + pages[field.html.page].anchors = pages[field.html.page].anchors || {} + pages[field.html.page].anchors[field.html.anchor] = '
    '+ + ((field.type === 'empty') ? input : '
    '+ w2utils.lang(field.type != 'checkbox' ? field.html.label : field.html.text, true) + input + w2utils.lang(field.type != 'checkbox' ? field.html.text : '') + '
    ') + + '
    ' + } + if (pages[field.html.page] == null) pages[field.html.page] = {} + if (pages[field.html.page][field.html.column] == null) pages[field.html.page][field.html.column] = '' + pages[field.html.page][field.html.column] += html + page = field.html.page + column = field.html.column + } + if (group !== '') pages[page][column] += '\n
    \n
    ' + if (this.tabs.tabs) { + for (let i = 0; i < this.tabs.tabs.length; i++) if (pages[i] == null) pages[i] = [] + } + // buttons if any + let buttons = '' + if (Object.keys(this.actions).length > 0) { + buttons += '\n
    ' + tabindex = this.tabindexBase + this.fields.length + 1 + for (let a in this.actions) { // it is an object + let act = this.actions[a] + let info = { text: '', style: '', 'class': '' } + if (w2utils.isPlainObject(act)) { + if (act.text == null && act.caption != null) { + console.log('NOTICE: form action.caption property is deprecated, please use action.text. Action ->', act) + act.text = act.caption + } + if (act.text) info.text = act.text + if (act.style) info.style = act.style + if (act.class) info.class = act.class + } else { + info.text = a + if (['save', 'update', 'create'].indexOf(a.toLowerCase()) !== -1) info.class = 'w2ui-btn-blue'; else info.class = '' + } + buttons += '\n ' + tabindex++ + } + buttons += '\n
    ' + } + html = '' + for (let p = 0; p < pages.length; p++){ + html += '
    ' + if (!pages[p]) { + console.log(`ERROR: Page ${p} does not exist`) + return false + } + if (pages[p].before) { + html += pages[p].before + } + html += '
    ' + Object.keys(pages[p]).sort().forEach((c, ind) => { + if (c == parseInt(c)) { + html += '
    ' + (pages[p][c] || '') + '\n
    ' + } + }) + html += '\n
    ' + if (pages[p].after) { + html += pages[p].after + } + html += '\n
    ' + // process page anchors + if (pages[p].anchors) { + Object.keys(pages[p].anchors).forEach((key, ind) => { + html = html.replace(key, pages[p].anchors[key]) + }) + } + } + html += buttons + return html + } + toggleGroup(groupName, show) { + let el = query(this.box).find('.w2ui-group-title[data-group="' + w2utils.base64encode(groupName) + '"]') + if (el.length === 0) return + let el_next = query(el.prop('nextElementSibling')) + if (typeof show === 'undefined') { + show = (el_next.css('display') == 'none') + } + if (show) { + el_next.show() + el.find('span').addClass('w2ui-icon-collapse').removeClass('w2ui-icon-expand') + } else { + el_next.hide() + el.find('span').addClass('w2ui-icon-expand').removeClass('w2ui-icon-collapse') + } + } + action(action, event) { + let act = this.actions[action] + let click = act + if (w2utils.isPlainObject(act) && act.onClick) click = act.onClick + // event before + let edata = this.trigger('action', { target: action, action: act, originalEvent: event }) + if (edata.isCancelled === true) return + // default actions + if (typeof click === 'function') click.call(this, event) + // event after + edata.finish() + } + resize() { + let self = this + // event before + let edata = this.trigger('resize', { target: this.name }) + if (edata.isCancelled === true) return + // default behaviour + let header = query(this.box).find(':scope > div .w2ui-form-header') + let toolbar = query(this.box).find(':scope > div .w2ui-form-toolbar') + let tabs = query(this.box).find(':scope > div .w2ui-form-tabs') + let page = query(this.box).find(':scope > div .w2ui-page') + let dpage = query(this.box).find(':scope > div .w2ui-page.page-'+ this.page + ' > div') + let buttons = query(this.box).find(':scope > div .w2ui-buttons') + // if no height, calculate it + let { headerHeight, tbHeight, tabsHeight } = resizeElements() + if (this.autosize) { // we don't need autosize every time + let cHeight = query(this.box).get(0).clientHeight + if (cHeight === 0 || query(this.box).data('autosize') == 'yes') { + query(this.box).css({ + height: headerHeight + tbHeight + tabsHeight + 15 // 15 is extra height + + (page.length > 0 ? w2utils.getSize(dpage, 'height') : 0) + + (buttons.length > 0 ? w2utils.getSize(buttons, 'height') : 0) + + 'px' + }) + query(this.box).data('autosize', 'yes') + } + resizeElements() + } + // event after + edata.finish() + function resizeElements() { + let headerHeight = (self.header !== '' ? w2utils.getSize(header, 'height') : 0) + let tbHeight = (Array.isArray(self.toolbar?.items) && self.toolbar?.items?.length > 0) + ? w2utils.getSize(toolbar, 'height') + : 0 + let tabsHeight = (Array.isArray(self.tabs?.tabs) && self.tabs?.tabs?.length > 0) + ? w2utils.getSize(tabs, 'height') + : 0 + // resize elements + toolbar.css({ top: headerHeight + 'px' }) + tabs.css({ top: headerHeight + tbHeight + 'px' }) + page.css({ + top: headerHeight + tbHeight + tabsHeight + 'px', + bottom: (buttons.length > 0 ? w2utils.getSize(buttons, 'height') : 0) + 'px' + }) + // return some params + return { headerHeight, tbHeight, tabsHeight } + } + } + refresh() { + let time = Date.now() + let self = this + if (!this.box) return + if (!this.isGenerated || !query(this.box).html()) return + // event before + let edata = this.trigger('refresh', { target: this.name, page: this.page, field: arguments[0], fields: arguments }) + if (edata.isCancelled === true) return + let fields = Array.from(this.fields.keys()) + if (arguments.length > 0) { + fields = Array.from(arguments) + .map((fld, ind) => { + if (typeof fld != 'string') console.log('ERROR: Arguments in refresh functions should be field names') + return this.get(fld, true) // get index of field + }) + .filter((fld, ind) => { + if (fld != null) return true; else return false + }) + } else { + // update field.page with page it belongs too + query(this.box).find('input, textarea, select').each(el => { + let name = (query(el).attr('name') != null ? query(el).attr('name') : query(el).attr('id')) + let field = this.get(name) + if (field) { + // find page + let div = query(el).closest('.w2ui-page') + if (div.length > 0) { + for (let i = 0; i < 100; i++) { + if (div.hasClass('page-'+i)) { field.page = i; break } + } + } + } + }) + // default action + query(this.box).find('.w2ui-page').hide() + query(this.box).find('.w2ui-page.page-' + this.page).show() + query(this.box).find('.w2ui-form-header').html(w2utils.lang(this.header)) + // refresh tabs if needed + if (typeof this.tabs === 'object' && Array.isArray(this.tabs.tabs) && this.tabs.tabs.length > 0) { + query(this.box).find('#form_'+ this.name +'_tabs').show() + this.tabs.active = this.tabs.tabs[this.page].id + this.tabs.refresh() + } else { + query(this.box).find('#form_'+ this.name +'_tabs').hide() + } + // refresh tabs if needed + if (typeof this.toolbar === 'object' && Array.isArray(this.toolbar.items) && this.toolbar.items.length > 0) { + query(this.box).find('#form_'+ this.name +'_toolbar').show() + this.toolbar.refresh() + } else { + query(this.box).find('#form_'+ this.name +'_toolbar').hide() + } + } + // refresh values of fields + for (let f = 0; f < fields.length; f++) { + let field = this.fields[fields[f]] + if (field.name == null && field.field != null) field.name = field.field + if (field.field == null && field.name != null) field.field = field.name + field.$el = query(this.box).find(`[name='${String(field.name).replace(/\\/g, '\\\\')}']`) + field.el = field.$el.get(0) + if (field.el) field.el.id = field.name + // TODO: check + if (field.w2field) { + field.w2field.reset() + } + field.$el + .off('.w2form') + .on('change.w2form', function(event) { + let value = self.getFieldValue(field.field) + // clear error class + if (['enum', 'file'].includes(field.type)) { + let helper = field.el._w2field?.helpers?.multi + query(helper).removeClass('w2ui-error') + } + if (this._previous != null) { + value.previous = this._previous + delete this._previous + } + // event before + let edata2 = self.trigger('change', { target: this.name, field: this.name, value, originalEvent: event }) + if (edata2.isCancelled === true) return + // default behavior + self.setValue(this.name, value.current) + // event after + edata2.finish() + }) + .on('input.w2form', function(event) { + // remember original + if (self.original == null) { + if (Object.keys(self.record).length > 0) { + self.original = w2utils.clone(self.record) + } else { + self.original = {} + } + } + let value = self.getFieldValue(field.field) + // save previous for change event + if (this._previous == null) { + this._previous = value.previous + } + // event before + let edata2 = self.trigger('input', { target: self.name, value, originalEvent: event }) + if (edata2.isCancelled === true) return + // default action + self.setValue(this.name, value.current) + // event after + edata2.finish() + }) + // required + if (field.required) { + field.$el.closest('.w2ui-field').addClass('w2ui-required') + } else { + field.$el.closest('.w2ui-field').removeClass('w2ui-required') + } + // disabled + if (field.disabled != null) { + if (field.disabled) { + if (field.$el.data('tabIndex') == null) { + field.$el.data('tabIndex', field.$el.prop('tabIndex')) + } + field.$el + .prop('readOnly', true) + .prop('disabled', true) + .prop('tabIndex', -1) + .closest('.w2ui-field') + .addClass('w2ui-disabled') + } else { + field.$el + .prop('readOnly', false) + .prop('disabled', false) + .prop('tabIndex', field.$el.data('tabIndex') ?? field.$el.prop('tabIndex') ?? 0) + .closest('.w2ui-field') + .removeClass('w2ui-disabled') + } + } + // hidden + let tmp = field.el + if (!tmp) tmp = query(this.box).find('#' + field.field) + if (field.hidden) { + query(tmp).closest('.w2ui-field').hide() + } else { + query(tmp).closest('.w2ui-field').show() + } + } + // attach actions on buttons + query(this.box).find('button, input[type=button]').each(el => { + query(el).off('click').on('click', function(event) { + let action = this.value + if (this.id) action = this.id + if (this.name) action = this.name + self.action(action, event) + }) + }) + // init controls with record + for (let f = 0; f < fields.length; f++) { + let field = this.fields[fields[f]] + if (!field.el) continue + if (!field.$el.hasClass('w2ui-input')) field.$el.addClass('w2ui-input') + field.type = String(field.type).toLowerCase() + if (!field.options) field.options = {} + // list type + if (this.LIST_TYPES.includes(field.type)) { + let items = field.options.items + if (items == null) field.options.items = [] + field.options.items = w2utils.normMenu.call(this, items, field) + } + // HTML select + if (field.type == 'select') { + // generate options + let items = field.options.items + let options = '' + items.forEach(item => { + options += `` + }) + field.$el.html(options) + } + // w2fields + if (this.W2FIELD_TYPES.includes(field.type)) { + field.w2field = field.w2field + ?? new w2field(w2utils.extend({}, field.options, { type: field.type })) + field.w2field.render(field.el) + } + // map and arrays + if (['map', 'array'].includes(field.type)) { + // need closure + (function (obj, field) { + let keepFocus + field.el.mapAdd = function(field, div, cnt) { + let attr = (field.disabled ? ' readOnly ' : '') + (field.html.tabindex_str || '') + let html = ` +
    + ${field.type == 'map' + ? ` + ${field.html.key.text || ''} + ` + : '' + } + + ${field.html.value.text || ''} +
    ` + div.append(html) + } + field.el.mapRefresh = function(map, div) { + // generate options + let keys, $k, $v + if (field.type == 'map') { + if (!w2utils.isPlainObject(map)) map = {} + if (map._order == null) map._order = Object.keys(map) + keys = map._order + } + if (field.type == 'array') { + if (!Array.isArray(map)) map = [] + keys = map.map((item, ind) => { return ind }) + } + // delete extra fields (including empty one) + let all = div.find('.w2ui-map-field') + for (let i = all.length-1; i >= keys.length; i--) { + div.find(`div[data-index='${i}']`).remove() + } + for (let ind = 0; ind < keys.length; ind++) { + let key = keys[ind] + let fld = div.find(`div[data-index='${ind}']`) + // add if does not exists + if (fld.length == 0) { + field.el.mapAdd(field, div, ind) + fld = div.find(`div[data-index='${ind}']`) + } + fld.attr('data-key', key) + $k = fld.find('.w2ui-map.key') + $v = fld.find('.w2ui-map.value') + let val = map[key] + if (field.type == 'array') { + let tmp = map.filter((it) => { return it.key == key ? true : false}) + if (tmp.length > 0) val = tmp[0].value + } + $k.val(key) + $v.val(val) + if (field.disabled === true || field.disabled === false) { + $k.prop('readOnly', field.disabled ? true : false) + $v.prop('readOnly', field.disabled ? true : false) + } + } + let cnt = keys.length + let curr = div.find(`div[data-index='${cnt}']`) + // if not disabled - add next if needed + if (curr.length === 0 && (!$k || $k.val() != '' || $v.val() != '') + && !($k && ($k.prop('readOnly') === true || $k.prop('disabled') === true)) + ) { + field.el.mapAdd(field, div, cnt) + } + if (field.disabled === true || field.disabled === false) { + curr.find('.key').prop('readOnly', field.disabled ? true : false) + curr.find('.value').prop('readOnly', field.disabled ? true : false) + } + // attach events + let container = query(field.el).get(0)?.nextSibling // should be div + query(container).find('input.w2ui-map') + .off('.mapChange') + .on('keyup.mapChange', function(event) { + let $div = query(event.target).closest('.w2ui-map-field') + let next = $div.get(0).nextElementSibling + let prev = $div.get(0).previousElementSibling + if (event.keyCode == 13) { + let el = keepFocus ?? next + if (el instanceof HTMLElement) { + let inp = query(el).find('input') + if (inp.length > 0) { + inp.get(0).focus() + } + } + keepFocus = undefined + } + let className = query(event.target).hasClass('key') ? 'key' : 'value' + if (event.keyCode == 38 && prev) { // up key + query(prev).find(`input.${className}`).get(0).select() + event.preventDefault() + } + if (event.keyCode == 40 && next) { // down key + query(next).find(`input.${className}`).get(0).select() + event.preventDefault() + } + }) + .on('keydown.mapChange', function(event) { + if (event.keyCode == 38 || event.keyCode == 40) { + event.preventDefault() + } + }) + .on('input.mapChange', function(event) { + let fld = query(event.target).closest('div') + let cnt = fld.data('index') + let next = fld.get(0).nextElementSibling + // if last one, add new empty + if (fld.find('input').val() != '' && !next) { + field.el.mapAdd(field, div, parseInt(cnt) + 1) + } else if (fld.find('input').val() == '' && next) { + let isEmpty = true + query(next).find('input').each(el => { + if (el.value != '') isEmpty = false + }) + if (isEmpty) { + query(next).remove() + } + } + }) + .on('change.mapChange', function(event) { + // remember original + if (self.original == null) { + if (Object.keys(self.record).length > 0) { + self.original = w2utils.clone(self.record) + } else { + self.original = {} + } + } + // event before + let { current, previous, original } = self.getFieldValue(field.field) + let $cnt = query(event.target).closest('.w2ui-map-container') + if (field.type == 'map') current._order = [] + $cnt.find('.w2ui-map.key').each(el => { current._order.push(el.value) }) + let edata = self.trigger('change', { target: field.field, field: field.field, originalEvent: event, + value: { current, previous, original } + }) + if (edata.isCancelled === true) { + return + } + // delete empty + if (field.type == 'map') { + current._order = current._order.filter(k => k !== '') + delete current[''] + } + if (field.type == 'array') { + current = current.filter(k => k !== '') + } + if (query(event.target).parent().find('input').val() == '') { + keepFocus = event.target + } + self.setValue(field.field, current) + field.el.mapRefresh(current, div) + // event after + edata.finish() + }) + } + })(this, field) + } + // set value to HTML input field + this.setFieldValue(field.field, this.getValue(field.name)) + } + // event after + edata.finish() + this.resize() + return Date.now() - time + } + render(box) { + let time = Date.now() + let self = this + if (typeof box == 'string') box = query(box).get(0) + // event before + let edata = this.trigger('render', { target: this.name, box: box ?? this.box }) + if (edata.isCancelled === true) return + // default action + if (box != null) { + // clean previous box + if (query(this.box).find('#form_'+ this.name +'_form').length > 0) { + query(this.box).removeAttr('name') + .removeClass('w2ui-reset w2ui-form') + .html('') + } + this.box = box + } + if (!this.isGenerated && !this.formHTML) return + if (!this.box) return + // render form + let html = '
    ' + + (this.header !== '' ? '
    ' + w2utils.lang(this.header) + '
    ' : '') + + ' ' + + ' ' + + this.formHTML + + '
    ' + query(this.box).attr('name', this.name) + .addClass('w2ui-reset w2ui-form') + .html(html) + if (query(this.box).length > 0) query(this.box)[0].style.cssText += this.style + w2utils.bindEvents(query(this.box).find('.w2ui-eaction'), this) + // init toolbar regardless it is defined or not + if (typeof this.toolbar.render !== 'function') { + this.toolbar = new w2toolbar(w2utils.extend({}, this.toolbar, { name: this.name +'_toolbar', owner: this })) + this.toolbar.on('click', function(event) { + let edata = self.trigger('toolbar', { target: event.target, originalEvent: event }) + if (edata.isCancelled === true) return + // no default action + edata.finish() + }) + } + if (typeof this.toolbar === 'object' && typeof this.toolbar.render === 'function') { + this.toolbar.render(query(this.box).find('#form_'+ this.name +'_toolbar')[0]) + } + // init tabs regardless it is defined or not + if (typeof this.tabs.render !== 'function') { + this.tabs = new w2tabs(w2utils.extend({}, this.tabs, { name: this.name +'_tabs', owner: this, active: this.tabs.active })) + this.tabs.on('click', function(event) { + self.goto(this.get(event.target, true)) + }) + } + if (typeof this.tabs === 'object' && typeof this.tabs.render === 'function') { + this.tabs.render(query(this.box).find('#form_'+ this.name +'_tabs')[0]) + if (this.tabs.active) this.tabs.click(this.tabs.active) + } + // event after + edata.finish() + // after render actions + this.resize() + let url = (typeof this.url !== 'object' ? this.url : this.url.get) + if (url && this.recid != null) { + this.request().catch(error => this.refresh()) // even if there was error, still need refresh + } else { + this.refresh() + } + // observe div resize + this.last.observeResize = new ResizeObserver(() => { this.resize() }) + this.last.observeResize.observe(this.box) + // focus on load + if (this.focus != -1) { + let setCount = 0 + let setFocus = () => { + if (query(self.box).find('input, select, textarea').length > 0) { + self.setFocus() + } else { + setCount++ + if (setCount < 20) setTimeout(setFocus, 50) // 1 sec max + } + } + setFocus() + } + return Date.now() - time + } + setFocus(focus) { + if (typeof focus === 'undefined'){ + // no argument - use form's focus property + focus = this.focus + } + let $input + // focus field by index + if (w2utils.isInt(focus)){ + if (focus < 0) { + return + } + let inputs = query(this.box) + .find('div:not(.w2ui-field-helper) > input, select, textarea, div > label:nth-child(1) > [type=radio]') + .filter(':not(.file-input)') + // find visible (offsetParent == null for any element is not visible) + while (inputs[focus].offsetParent == null && inputs.length >= focus) { + focus++ + } + if (inputs[focus]) { + $input = query(inputs[focus]) + } + } else if (typeof focus === 'string') { + // focus field by name + $input = query(this.box).find(`[name='${focus}']`) + } + if ($input.length > 0){ + $input.get(0).focus() + } + return $input + } + destroy() { + // event before + let edata = this.trigger('destroy', { target: this.name }) + if (edata.isCancelled === true) return + // clean up + if (typeof this.toolbar === 'object' && this.toolbar.destroy) this.toolbar.destroy() + if (typeof this.tabs === 'object' && this.tabs.destroy) this.tabs.destroy() + if (query(this.box).find('#form_'+ this.name +'_tabs').length > 0) { + query(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-form') + .html('') + } + this.last.observeResize?.disconnect() + delete w2ui[this.name] + // event after + edata.finish() + } +} +/** + * Part of w2ui 2.0 library + * - Dependencies: mQuery, w2utils, w2base, w2tooltip, w2color, w2menu, w2date + * + * == TODO == + * - upload (regular files) + * - BUG with prefix/postfix and arrows (test in different contexts) + * - multiple date selection + * - month selection, year selections + * - MultiSelect - Allow Copy/Paste for single and multi values + * - add routeData to list/enum + * - ENUM, LIST: should have same as grid (limit, offset, search, sort) + * - ENUM, LIST: should support wild chars + * - add selection of predefined times (used for appointments) + * - options.items - can be an array + * - options.msgNoItems - can be a function + * - REMOTE fields + * + * == 2.0 changes + * - removed jQuery dependency + * - enum options.autoAdd + * - [numeric, date] - options.autoCorrect to enforce range and validity + * - silent only left for files, removed form the rest + * - remote source response items => records or just an array + * - deprecated "success" field for remote source response + * - CSP - fixed inline events + * - remove clear, use reset instead + * - options.msgSearch + * - options.msgNoItems + */ + +class w2field extends w2base { + constructor(type, options) { + super() + // sanitization + if (typeof type == 'string' && options == null) { + options = { type: type } + } + if (typeof type == 'object' && options == null) { + options = w2utils.clone(type) + } + if (typeof type == 'string' && typeof options == 'object') { + options.type = type + } + options.type = String(options.type).toLowerCase() + this.el = options.el ?? null + this.selected = null + this.helpers = {} // object or helper elements + this.type = options.type ?? 'text' + this.options = w2utils.clone(options) + this.onClick = options.onClick ?? null + this.onAdd = options.onAdd ?? null + this.onNew = options.onNew ?? null + this.onRemove = options.onRemove ?? null + this.onMouseEnter= options.onMouseEnter ?? null + this.onMouseLeave= options.onMouseLeave ?? null + this.onScroll = options.onScroll ?? null + this.tmp = {} // temp object + // clean up some options + delete this.options.type + delete this.options.onClick + delete this.options.onMouseEnter + delete this.options.onMouseLeave + delete this.options.onScroll + if (this.el) { + this.render(this.el) + } + } + render(el) { + if (!(el instanceof HTMLElement)) { + console.log('ERROR: Cannot init w2field on empty subject') + return + } + if (el._w2field) { + el._w2field.reset() + } else { + el._w2field = this + } + this.el = el + this.init() + } + init() { + let options = this.options + let defaults + // only for INPUT or TEXTAREA + if (!['INPUT', 'TEXTAREA'].includes(this.el.tagName.toUpperCase())) { + console.log('ERROR: w2field could only be applied to INPUT or TEXTAREA.', this.el) + return + } + switch (this.type) { + case 'text': + case 'int': + case 'float': + case 'money': + case 'currency': + case 'percent': + case 'alphanumeric': + case 'bin': + case 'hex': + defaults = { + min: null, + max: null, + step: 1, + autoFormat: true, + autoCorrect: true, + currencyPrefix: w2utils.settings.currencyPrefix, + currencySuffix: w2utils.settings.currencySuffix, + currencyPrecision: w2utils.settings.currencyPrecision, + decimalSymbol: w2utils.settings.decimalSymbol, + groupSymbol: w2utils.settings.groupSymbol, + arrow: false, + keyboard: true, + precision: null, + prefix: '', + suffix: '' + } + this.options = w2utils.extend({}, defaults, options) + options = this.options // since object is re-created, need to re-assign + options.numberRE = new RegExp('['+ options.groupSymbol + ']', 'g') + options.moneyRE = new RegExp('['+ options.currencyPrefix + options.currencySuffix + options.groupSymbol +']', 'g') + options.percentRE = new RegExp('['+ options.groupSymbol + '%]', 'g') + // no keyboard support needed + if (['text', 'alphanumeric', 'hex', 'bin'].includes(this.type)) { + options.arrow = false + options.keyboard = false + } + break + case 'color': + defaults = { + prefix : '#', + suffix : `
     
    `, + arrow : false, + advanced : null, // open advanced by default + transparent : true + } + this.options = w2utils.extend({}, defaults, options) + options = this.options // since object is re-created, need to re-assign + break + case 'date': + defaults = { + format : w2utils.settings.dateFormat, // date format + keyboard : true, + autoCorrect : true, + start : null, + end : null, + blockDates : [], // array of blocked dates + blockWeekdays : [], // blocked weekdays 0 - sunday, 1 - monday, etc + colored : {}, // ex: { '3/13/2022': 'bg-color|text-color' } + btnNow : true + } + this.options = w2utils.extend({ type: 'date' }, defaults, options) + options = this.options // since object is re-created, need to re-assign + if (query(this.el).attr('placeholder') == null) { + query(this.el).attr('placeholder', options.format) + } + break + case 'time': + defaults = { + format : w2utils.settings.timeFormat, + keyboard : true, + autoCorrect : true, + start : null, + end : null, + btnNow : true, + noMinutes : false + } + this.options = w2utils.extend({ type: 'time' }, defaults, options) + options = this.options // since object is re-created, need to re-assign + if (query(this.el).attr('placeholder') == null) { + query(this.el).attr('placeholder', options.format) + } + break + case 'datetime': + defaults = { + format : w2utils.settings.dateFormat + '|' + w2utils.settings.timeFormat, + keyboard : true, + autoCorrect : true, + start : null, + end : null, + startTime : null, + endTime : null, + blockDates : [], // array of blocked dates + blockWeekdays : [], // blocked weekdays 0 - sunday, 1 - monday, etc + colored : {}, // ex: { '3/13/2022': 'bg-color|text-color' } + btnNow : true, + noMinutes : false + } + this.options = w2utils.extend({ type: 'datetime' }, defaults, options) + options = this.options // since object is re-created, need to re-assign + if (query(this.el).attr('placeholder') == null) { + query(this.el).attr('placeholder', options.placeholder || options.format) + } + break + case 'list': + case 'combo': + defaults = { + items : [], + selected : {}, + url : null, // url to pull data from // TODO: implement + recId : null, // map retrieved data from url to id, can be string or function + recText : null, // map retrieved data from url to text, can be string or function + method : null, // default httpMethod + debounce : 250, // number of ms to wait before sending server call on search + postData : {}, + minLength : 1, // min number of chars when trigger search + cacheMax : 250, + maxDropHeight : 350, // max height for drop down menu + maxDropWidth : null, // if null then auto set + minDropWidth : null, // if null then auto set + match : 'begins', // ['contains', 'is', 'begins', 'ends'] + icon : null, + iconStyle : '', + align : 'both', // same width as control + altRows : true, // alternate row color + renderDrop : null, // render function for drop down item + compare : null, // compare function for filtering + filter : true, // weather to filter at all + hideSelected : false, // hide selected item from drop down + prefix : '', + suffix : '', + msgNoItems : 'No matches', + msgSearch : 'Type to search...', + openOnFocus : false, // if to show overlay onclick or when typing + markSearch : false, + onSearch : null, // when search needs to be performed + onRequest : null, // when request is submitted + onLoad : null, // when data is received + onError : null // when data fails to load due to server error or other failure modes + } + if (typeof options.items == 'function') { + options._items_fun = options.items + } + // need to be first + options.items = w2utils.normMenu.call(this, options.items) + if (this.type === 'list') { + // defaults.search = (options.items && options.items.length >= 10 ? true : false); + query(this.el).addClass('w2ui-select') + // if simple value - look it up + if (!w2utils.isPlainObject(options.selected) && Array.isArray(options.items)) { + options.items.forEach(item => { + if (item && item.id === options.selected) { + options.selected = w2utils.clone(item) + } + }) + } + } + options = w2utils.extend({}, defaults, options) + this.options = options + if (!w2utils.isPlainObject(options.selected)) options.selected = {} + this.selected = options.selected + query(this.el) + .attr('autocapitalize', 'off') + .attr('autocomplete', 'off') + .attr('autocorrect', 'off') + .attr('spellcheck', 'false') + if (options.selected.text != null) { + query(this.el).val(options.selected.text) + } + break + case 'enum': + defaults = { + items : [], // id, text, tooltip, icon + selected : [], + max : 0, // max number of selected items, 0 - unlimited + url : null, // not implemented + recId : null, // map retrieved data from url to id, can be string or function + recText : null, // map retrieved data from url to text, can be string or function + debounce : 250, // number of ms to wait before sending server call on search + method : null, // default httpMethod + postData : {}, + minLength : 1, // min number of chars when trigger search + cacheMax : 250, + maxItemWidth : 250, // max width for a single item + maxDropHeight : 350, // max height for drop down menu + maxDropWidth : null, // if null then auto set + match : 'contains', // ['contains', 'is', 'begins', 'ends'] + align : '', // align drop down related to search field + altRows : true, // alternate row color + openOnFocus : false, // if to show overlay onclick or when typing + markSearch : false, + renderDrop : null, // render function for drop down item + renderItem : null, // render selected item + compare : null, // compare function for filtering + filter : true, // alias for compare + hideSelected : true, // hide selected item from drop down + style : '', // style for container div + msgNoItems : 'No matches', + msgSearch : 'Type to search...', + onSearch : null, // when search needs to be performed + onRequest : null, // when request is submitted + onLoad : null, // when data is received + onError : null, // when data fails to load due to server error or other failure modes + onClick : null, // when an item is clicked + onAdd : null, // when an item is added + onNew : null, // when new item should be added + onRemove : null, // when an item is removed + onMouseEnter : null, // when an item is mouse over + onMouseLeave : null, // when an item is mouse out + onScroll : null // when div with selected items is scrolled + } + options = w2utils.extend({}, defaults, options, { suffix: '' }) + if (typeof options.items == 'function') { + options._items_fun = options.items + } + options.items = w2utils.normMenu.call(this, options.items) + options.selected = w2utils.normMenu.call(this, options.selected) + this.options = options + if (!Array.isArray(options.selected)) options.selected = [] + this.selected = options.selected + break + case 'file': + defaults = { + selected : [], + max : 0, + maxSize : 0, // max size of all files, 0 - unlimited + maxFileSize : 0, // max size of a single file, 0 -unlimited + maxItemWidth : 250, // max width for a single item + maxDropHeight : 350, // max height for drop down menu + maxDropWidth : null, // if null then auto set + readContent : true, // if true, it will readAsDataURL content of the file + silent : true, + align : 'both', // same width as control + altRows : true, // alternate row color + renderItem : null, // render selected item + style : '', // style for container div + onClick : null, // when an item is clicked + onAdd : null, // when an item is added + onRemove : null, // when an item is removed + onMouseEnter : null, // when an item is mouse over + onMouseLeave : null // when an item is mouse out + } + options = w2utils.extend({}, defaults, options) + this.options = options + if (!Array.isArray(options.selected)) options.selected = [] + this.selected = options.selected + if (query(this.el).attr('placeholder') == null) { + query(this.el).attr('placeholder', w2utils.lang('Attach files by dragging and dropping or Click to Select')) + } + break + } + // attach events + query(this.el) + .css('box-sizing', 'border-box') + .addClass('w2field w2ui-input') + .off('.w2field') + .on('change.w2field', (event) => { this.change(event) }) + .on('click.w2field', (event) => { this.click(event) }) + .on('focus.w2field', (event) => { this.focus(event) }) + .on('blur.w2field', (event) => { if (this.type !== 'list') this.blur(event) }) + .on('keydown.w2field', (event) => { this.keyDown(event) }) + .on('keyup.w2field', (event) => { this.keyUp(event) }) + // suffix and prefix need to be after styles + this.addPrefix() // only will add if needed + this.addSuffix() // only will add if needed + this.addSearch() + this.addMultiSearch() + // this.refresh() // do not call refresh, on change will trigger refresh (for list at list) + // format initial value + this.change(new Event('change')) + } + get() { + let ret + if (['list', 'enum', 'file'].indexOf(this.type) !== -1) { + ret = this.selected + } else { + ret = query(this.el).val() + } + return ret + } + set(val, append) { + if (['list', 'enum', 'file'].indexOf(this.type) !== -1) { + if (this.type !== 'list' && append) { + if (!Array.isArray(this.selected)) this.selected = [] + this.selected.push(val) + // update selected array in overlay + let overlay = w2menu.get(this.el.id + '_menu') + if (overlay) overlay.options.selected = this.selected + query(this.el).trigger('input').trigger('change') + } else { + if (val == null) val = [] + let it = (this.type === 'enum' && !Array.isArray(val) ? [val] : val) + this.selected = it + query(this.el).trigger('input').trigger('change') + } + this.refresh() + } else { + query(this.el).val(val) + } + } + setIndex(ind, append) { + if (['list', 'enum'].indexOf(this.type) !== -1) { + let items = this.options.items + if (items && items[ind]) { + if (this.type == 'list') { + this.selected = items[ind] + } + if (this.type == 'enum') { + if (!append) this.selected = [] + this.selected.push(items[ind]) + } + let overlay = w2menu.get(this.el.id + '_menu') + if (overlay) overlay.options.selected = this.selected + query(this.el).trigger('input').trigger('change') + this.refresh() + return true + } + } + return false + } + refresh() { + let options = this.options + let time = Date.now() + let styles = getComputedStyle(this.el) + // enum + if (this.type == 'list') { + query(this.el).parent().css('white-space', 'nowrap') // needs this for arrow always to appear on the right side + // hide focus and show text + if (this.helpers.prefix) this.helpers.prefix.hide() + if (!this.helpers.search) return + // if empty show no icon + if (this.selected == null && options.icon) { + options.prefix = ` + + ` + this.addPrefix() + } else { + options.prefix = '' + this.addPrefix() + } + // focus helper + let focus = query(this.helpers.search_focus) + let icon = query(focus[0].previousElementSibling) + focus.css({ outline: 'none' }) + if (focus.val() === '') { + focus.css('opacity', 0) + icon.css('opacity', 0) + if (this.selected?.id) { + let text = this.selected.text + let ind = this.findItemIndex(options.items, this.selected.id) + if (text != null) { + query(this.el) + .val(w2utils.lang(text)) + .data({ + selected: text, + selectedIndex: ind[0] + }) + } + } else { + this.el.value = '' + query(this.el).removeData('selected selectedIndex') + } + } else { + focus.css('opacity', 1) + icon.css('opacity', 1) + query(this.el).val('') + setTimeout(() => { + if (this.helpers.prefix) this.helpers.prefix.hide() + if (options.icon) { + focus.css('margin-left', '17px') + query(this.helpers.search).find('.w2ui-icon-search') + .addClass('show-search') + } else { + focus.css('margin-left', '0px') + query(this.helpers.search).find('.w2ui-icon-search') + .removeClass('show-search') + } + }, 1) + } + // if readonly or disabled + if (query(this.el).prop('readOnly') || query(this.el).prop('disabled')) { + setTimeout(() => { + if (this.helpers.prefix) query(this.helpers.prefix).css('opacity', '0.6') + if (this.helpers.suffix) query(this.helpers.suffix).css('opacity', '0.6') + }, 1) + } else { + setTimeout(() => { + if (this.helpers.prefix) query(this.helpers.prefix).css('opacity', '1') + if (this.helpers.suffix) query(this.helpers.suffix).css('opacity', '1') + }, 1) + } + } + let div = this.helpers.multi + if (['enum', 'file'].includes(this.type) && div) { + let html = '' + if (Array.isArray(this.selected)) { + this.selected.forEach((it, ind) => { + if (it == null) return + html += ` +
    + ${ + typeof options.renderItem === 'function' + ? options.renderItem(it, ind, `
      
    `) + : ` + ${it.icon ? `` : ''} +
      
    + ${(this.type === 'enum' ? it.text : it.name) ?? it.id ?? it } + ${it.size ? ` - ${w2utils.formatSize(it.size)}` : ''} + ` + } +
    ` + }) + } + let ul = div.find('.w2ui-multi-items') + if (options.style) { + div.attr('style', div.attr('style') + ';' + options.style) + } + query(this.el).css('z-index', '-1') + if (query(this.el).prop('readOnly') || query(this.el).prop('disabled')) { + setTimeout(() => { + div[0].scrollTop = 0 // scroll to the top + div.addClass('w2ui-readonly') + .find('.li-item').css('opacity', '0.9') + .parent().find('.li-search').hide() + .find('input').prop('readOnly', true) + .closest('.w2ui-multi-items') + .find('.w2ui-list-remove').hide() + }, 1) + } else { + setTimeout(() => { + div.removeClass('w2ui-readonly') + .find('.li-item').css('opacity', '1') + .parent().find('.li-search').show() + .find('input').prop('readOnly', false) + .closest('.w2ui-multi-items') + .find('.w2ui-list-remove').show() + }, 1) + } + // clean + if (this.selected?.length > 0) { + query(this.el).attr('placeholder', '') + } + div.find('.w2ui-enum-placeholder').remove() + ul.find('.li-item').remove() + // add new list + if (html !== '') { + ul.prepend(html) + } else if (query(this.el).attr('placeholder') != null && div.find('input').val() === '') { + let style = w2utils.stripSpaces(` + padding-top: ${styles['padding-top']}; + padding-left: ${styles['padding-left']}; + box-sizing: ${styles['box-sizing']}; + line-height: ${styles['line-height']}; + font-size: ${styles['font-size']}; + font-family: ${styles['font-family']}; + `) + div.prepend(`
    ${query(this.el).attr('placeholder')}
    `) + } + // ITEMS events + div.off('.w2item') + .on('scroll.w2item', (event) => { + let edata = this.trigger('scroll', { target: this.el, originalEvent: event }) + if (edata.isCancelled === true) return + // hide tooltip if any + w2tooltip.hide(this.el.id + '_preview') + // event after + edata.finish() + }) + .find('.li-item') + .on('click.w2item', (event) => { + let target = query(event.target).closest('.li-item') + let index = target.attr('index') + let item = this.selected[index] + if (query(target).hasClass('li-search')) return + event.stopPropagation() + let edata + // default behavior + if (query(event.target).hasClass('w2ui-list-remove')) { + if (query(this.el).prop('readOnly') || query(this.el).prop('disabled')) return + // trigger event + edata = this.trigger('remove', { target: this.el, originalEvent: event, item }) + if (edata.isCancelled === true) return + // default behavior + this.selected.splice(index, 1) + query(this.el).trigger('input').trigger('change') + query(event.target).remove() + } else { + // trigger event + edata = this.trigger('click', { target: this.el, originalEvent: event.originalEvent, item }) + if (edata.isCancelled === true) return + // if file - show image preview + let preview = item.tooltip + if (this.type === 'file') { + if ((/image/i).test(item.type)) { // image + preview = ` +
    + +
    ` + } + preview += ` +
    +
    ${w2utils.lang('Name')}:
    +
    ${item.name}
    +
    ${w2utils.lang('Size')}:
    +
    ${w2utils.formatSize(item.size)}
    +
    ${w2utils.lang('Type')}:
    +
    ${item.type}
    +
    ${w2utils.lang('Modified')}:
    +
    ${w2utils.date(item.modified)}
    +
    ` + } + if (preview) { + let name = this.el.id + '_preview' + w2tooltip.show({ + name, + anchor: target.get(0), + html: preview, + hideOn: ['doc-click'], + class: '' + }) + .show((event) => { + let $img = query(`#w2overlay-${name} img`) + $img.on('load', function (event) { + let w = this.clientWidth + let h = this.clientHeight + if (w < 300 & h < 300) return + if (w >= h && w > 300) query(this).css('width', '300px') + if (w < h && h > 300) query(this).css('height', '300px') + }) + .on('error', function (event) { + this.style.display = 'none' + }) + }) + } + edata.finish() + } + }) + .on('mouseenter.w2item', (event) => { + let target = query(event.target).closest('.li-item') + if (query(target).hasClass('li-search')) return + let item = this.selected[query(event.target).attr('index')] + // trigger event + let edata = this.trigger('mouseEnter', { target: this.el, originalEvent: event, item }) + if (edata.isCancelled === true) return + // event after + edata.finish() + }) + .on('mouseleave.w2item', (event) => { + let target = query(event.target).closest('.li-item') + if (query(target).hasClass('li-search')) return + let item = this.selected[query(event.target).attr('index')] + // trigger event + let edata = this.trigger('mouseLeave', { target: this.el, originalEvent: event, item }) + if (edata.isCancelled === true) return + // event after + edata.finish() + }) + // update size for enum, hide for file + if (this.type === 'enum') { + let search = this.helpers.multi.find('input') + search.css({ width: '15px' }) + } else { + this.helpers.multi.find('.li-search').hide() + } + this.resize() + } + return Date.now() - time + } + // resizing width of list, enum, file controls + resize() { + let width = this.el.clientWidth + // let height = this.el.clientHeight + // if (this.tmp.current_width == width && height > 0) return + let styles = getComputedStyle(this.el) + let focus = this.helpers.search + let multi = this.helpers.multi + let suffix = this.helpers.suffix + let prefix = this.helpers.prefix + // resize helpers + if (focus) { + query(focus).css('width', width) + } + if (multi) { + query(multi).css('width', width - parseInt(styles['margin-left'], 10) - parseInt(styles['margin-right'], 10)) + } + if (suffix) { + this.addSuffix() + } + if (prefix) { + this.addPrefix() + } + // enum or file + let div = this.helpers.multi + if (['enum', 'file'].includes(this.type) && div) { + // adjust height + query(this.el).css('height', 'auto') + let cntHeight = query(div).find(':scope div.w2ui-multi-items').get(0).clientHeight + 5 + if (cntHeight < 20) cntHeight = 20 + // max height + if (cntHeight > this.tmp['max-height']) { + cntHeight = this.tmp['max-height'] + } + // min height + if (cntHeight < this.tmp['min-height']) { + cntHeight = this.tmp['min-height'] + } + let inpHeight = w2utils.getSize(this.el, 'height') - 2 + if (inpHeight > cntHeight) cntHeight = inpHeight + query(div).css({ + 'height': cntHeight + 'px', + overflow: (cntHeight == this.tmp['max-height'] ? 'auto' : 'hidden') + }) + query(div).css('height', cntHeight + 'px') + query(this.el).css({ 'height': cntHeight + 'px' }) + } + // remember width + this.tmp.current_width = width + } + reset() { + // restore paddings + if (this.tmp != null) { + query(this.el).css('height', 'auto') + Array('padding-left', 'padding-right', 'background-color', 'border-color').forEach(prop => { + if (this.tmp && this.tmp['old-'+ prop] != null) { + query(this.el).css(prop, this.tmp['old-' + prop]) + delete this.tmp['old-' + prop] + } + }) + // remove resize watcher + clearInterval(this.tmp.sizeTimer) + } + // remove events and (data) + query(this.el) + .val(this.clean(query(this.el).val())) + .removeClass('w2field') + .removeData('selected selectedIndex') + .off('.w2field') // remove only events added by w2field + // remove helpers + Object.keys(this.helpers).forEach(key => { + query(this.helpers[key]).remove() + }) + this.helpers = {} + } + clean(val) { + // issue #499 + if (typeof val === 'number'){ + return val + } + let options = this.options + val = String(val).trim() + // clean + if (['int', 'float', 'money', 'currency', 'percent'].includes(this.type)) { + if (typeof val === 'string') { + if (options.autoFormat) { + if (['money', 'currency'].includes(this.type)) { + val = String(val).replace(options.moneyRE, '') + } + if (this.type === 'percent') { + val = String(val).replace(options.percentRE, '') + } + if (['int', 'float'].includes(this.type)) { + val = String(val).replace(options.numberRE, '') + } + } + val = val.replace(/\s+/g, '') + .replace(new RegExp(options.groupSymbol, 'g'), '') + .replace(options.decimalSymbol, '.') + } + if (val !== '' && w2utils.isFloat(val)) val = Number(val); else val = '' + } + return val + } + format(val) { + let options = this.options + // auto format numbers or money + if (options.autoFormat && val !== '') { + switch (this.type) { + case 'money': + case 'currency': + val = w2utils.formatNumber(val, options.currencyPrecision, true) + if (val !== '') val = options.currencyPrefix + val + options.currencySuffix + break + case 'percent': + val = w2utils.formatNumber(val, options.precision, true) + if (val !== '') val += '%' + break + case 'float': + val = w2utils.formatNumber(val, options.precision, true) + break + case 'int': + val = w2utils.formatNumber(val, 0, true) + break + } + // if default group symbol does not match - replase it + let group = parseInt(1000).toLocaleString(w2utils.settings.locale, { useGrouping: true }).slice(1, 2) + if (group !== this.options.groupSymbol) { + val = val.replaceAll(group, this.options.groupSymbol) + } + } + return val + } + change(event) { + // numeric + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(this.type) !== -1) { + // check max/min + let val = query(this.el).val() + let new_val = this.format(this.clean(query(this.el).val())) + // if was modified + if (val !== '' && val != new_val) { + query(this.el).val(new_val) + // cancel event + event.stopPropagation() + event.preventDefault() + return false + } + } + // color + if (this.type === 'color') { + let color = query(this.el).val() + if (color.substr(0, 3).toLowerCase() !== 'rgb') { + color = '#' + color + let len = query(this.el).val().length + if (len !== 8 && len !== 6 && len !== 3) color = '' + } + let next = query(this.el).get(0).nextElementSibling + query(next).find('div').css('background-color', color) + if (query(this.el).hasClass('has-focus')) { + this.updateOverlay() + } + } + // list, enum + if (['list', 'enum', 'file'].indexOf(this.type) !== -1) { + this.refresh() + } + // date, time + if (['date', 'time', 'datetime'].indexOf(this.type) !== -1) { + // convert linux timestamps + let tmp = parseInt(this.el.value) + if (w2utils.isInt(this.el.value) && tmp > 3000) { + if (this.type === 'time') tmp = w2utils.formatTime(new Date(tmp), this.options.format) + if (this.type === 'date') tmp = w2utils.formatDate(new Date(tmp), this.options.format) + if (this.type === 'datetime') tmp = w2utils.formatDateTime(new Date(tmp), this.options.format) + query(this.el).val(tmp).trigger('input').trigger('change') + } + } + } + click(event) { + // lists + if (['list', 'combo', 'enum'].includes(this.type)) { + if (!query(this.el).hasClass('has-focus')) { + this.focus(event) + } + if (this.type == 'combo') { + this.updateOverlay() + } + // since list has separate search input, in order to keep the overlay open, need to stop + if (this.type == 'list') { + this.updateOverlay() + event.stopPropagation() + } + } + // other fields with drops + if (['date', 'time', 'datetime', 'color'].includes(this.type)) { + this.updateOverlay() + } + } + focus(event) { + if (this.type == 'list' && document.activeElement == this.el) { + this.helpers.search_focus.focus() + return + } + // color, date, time + if (['color', 'date', 'time', 'datetime'].indexOf(this.type) !== -1) { + if (query(this.el).prop('readOnly') || query(this.el).prop('disabled')) return + this.updateOverlay() + } + // menu + if (['list', 'combo', 'enum'].indexOf(this.type) !== -1) { + if (query(this.el).prop('readOnly') || query(this.el).prop('disabled')) { + // still add focus + query(this.el).addClass('has-focus') + return + } + // regenerate items + if (typeof this.options._items_fun == 'function') { + this.options.items = w2utils.normMenu.call(this, this.options._items_fun) + } + if (this.helpers.search) { + let search = this.helpers.search_focus + search.value = '' + search.select() + } + if (this.type == 'enum') { + // file control in particular need to receive focus after file select + let search = query(this.el.previousElementSibling).find('.li-search input').get(0) + if (document.activeElement !== search) { + search.focus() + } + } + this.resize() + // update overlay if needed + if (event.showMenu !== false && (this.options.openOnFocus !== false || query(this.el).hasClass('has-focus'))) { + setTimeout(() => { this.updateOverlay() }, 100) // execute at the end of event loop + } + } + if (this.type == 'file') { + let prev = query(this.el).get(0).previousElementSibling + query(prev).addClass('has-focus') + } + query(this.el).addClass('has-focus') + } + blur(event) { + let val = query(this.el).val().trim() + query(this.el).removeClass('has-focus') + if (['int', 'float', 'money', 'currency', 'percent'].includes(this.type)) { + if (val !== '') { + let newVal = val + let error = '' + if (!this.isStrValid(val)) { // validity is also checked in blur + newVal = '' + } else { + let rVal = this.clean(val) + if (this.options.min != null && rVal < this.options.min) { + newVal = this.options.min + error = `Should be >= ${this.options.min}` + } + if (this.options.max != null && rVal > this.options.max) { + newVal = this.options.max + error = `Should be <= ${this.options.max}` + } + } + if (this.options.autoCorrect) { + query(this.el).val(newVal).trigger('input').trigger('change') + if (error) { + w2tooltip.show({ + name: this.el.id + '_error', + anchor: this.el, + html: error + }) + setTimeout(() => { w2tooltip.hide(this.el.id + '_error') }, 3000) + } + } + } + } + // date or time + if (['date', 'time', 'datetime'].includes(this.type) && this.options.autoCorrect) { + if (val !== '') { + let check = this.type == 'date' ? w2utils.isDate : + (this.type == 'time' ? w2utils.isTime : w2utils.isDateTime) + if (!w2date.inRange(this.el.value, this.options) + || !check.bind(w2utils)(this.el.value, this.options.format)) { + // if not in range or wrong value - clear it + query(this.el).val('').trigger('input').trigger('change') + } + } + } + // clear search input + if (this.type === 'enum') { + query(this.helpers.multi).find('input').val('').css('width', '15px') + } + if (this.type == 'file') { + let prev = this.el.previousElementSibling + query(prev).removeClass('has-focus') + } + if (this.type === 'list') { + this.el.value = this.selected?.text ?? '' + } + } + keyDown(event, extra) { + let options = this.options + let key = event.keyCode || (extra && extra.keyCode) + let cancel = false + let val, inc, daymil, dt, newValue, newDT + // ignore wrong pressed key + if (['int', 'float', 'money', 'currency', 'percent', 'hex', 'bin', 'color', 'alphanumeric'].includes(this.type)) { + if (!event.metaKey && !event.ctrlKey && !event.altKey) { + if (!this.isStrValid(event.key ?? '1', true) && // valid & is not arrows, dot, comma, etc keys + ![9, 8, 13, 27, 37, 38, 39, 40, 46].includes(event.keyCode)) { + event.preventDefault() + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true + return false + } + } + } + // numeric + if (['int', 'float', 'money', 'currency', 'percent'].includes(this.type)) { + if (!options.keyboard || query(this.el).prop('readOnly') || query(this.el).prop('disabled')) return + val = parseFloat(query(this.el).val().replace(options.moneyRE, '')) || 0 + inc = options.step + if (event.ctrlKey || event.metaKey) inc = options.step * 10 + switch (key) { + case 38: // up + if (event.shiftKey) break // no action if shift key is pressed + newValue = (val + inc <= options.max || options.max == null ? Number((val + inc).toFixed(12)) : options.max) + query(this.el).val(newValue).trigger('input').trigger('change') + cancel = true + break + case 40: // down + if (event.shiftKey) break // no action if shift key is pressed + newValue = (val - inc >= options.min || options.min == null ? Number((val - inc).toFixed(12)) : options.min) + query(this.el).val(newValue).trigger('input').trigger('change') + cancel = true + break + } + if (cancel) { + event.preventDefault() + this.moveCaret2end() + } + } + // date/datetime + if (['date', 'datetime'].includes(this.type)) { + if (!options.keyboard || query(this.el).prop('readOnly') || query(this.el).prop('disabled')) return + let is = (this.type == 'date' ? w2utils.isDate : w2utils.isDateTime).bind(w2utils) + let format = (this.type == 'date' ? w2utils.formatDate : w2utils.formatDateTime).bind(w2utils) + daymil = 24*60*60*1000 + inc = 1 + if (event.ctrlKey || event.metaKey) inc = 10 // by month + dt = is(query(this.el).val(), options.format, true) + if (!dt) { dt = new Date(); daymil = 0 } + switch (key) { + case 38: // up + if (event.shiftKey) break // no action if shift key is pressed + if (inc == 10) { + dt.setMonth(dt.getMonth() + 1) + } else { + dt.setTime(dt.getTime() + daymil) + } + newDT = format(dt.getTime(), options.format) + query(this.el).val(newDT).trigger('input').trigger('change') + cancel = true + break + case 40: // down + if (event.shiftKey) break // no action if shift key is pressed + if (inc == 10) { + dt.setMonth(dt.getMonth() - 1) + } else { + dt.setTime(dt.getTime() - daymil) + } + newDT = format(dt.getTime(), options.format) + query(this.el).val(newDT).trigger('input').trigger('change') + cancel = true + break + } + if (cancel) { + event.preventDefault() + this.moveCaret2end() + this.updateOverlay() + } + } + // time + if (this.type === 'time') { + if (!options.keyboard || query(this.el).prop('readOnly') || query(this.el).prop('disabled')) return + inc = (event.ctrlKey || event.metaKey ? 60 : 1) + val = query(this.el).val() + let time = w2date.str2min(val) || w2date.str2min((new Date()).getHours() + ':' + ((new Date()).getMinutes() - 1)) + switch (key) { + case 38: // up + if (event.shiftKey) break // no action if shift key is pressed + time += inc + cancel = true + break + case 40: // down + if (event.shiftKey) break // no action if shift key is pressed + time -= inc + cancel = true + break + } + if (cancel) { + event.preventDefault() + query(this.el).val(w2date.min2str(time)).trigger('input').trigger('change') + this.moveCaret2end() + } + } + // list/enum + if (['list', 'enum'].includes(this.type)) { + switch (key) { + case 8: // delete + case 46: // backspace + if (this.type == 'list') { + let search = query(this.helpers.search_focus) + if (search.val() == '') { + this.selected = null + w2menu.hide(this.el.id + '_menu') + query(this.el).val('').trigger('input').trigger('change') + } + } else { + let search = query(this.helpers.multi).find('input') + if (search.val() == '') { + w2menu.hide(this.el.id + '_menu') + this.selected.pop() + // update selected array in overlay + let overlay = w2menu.get(this.el.id + '_menu') + if (overlay) overlay.options.selected = this.selected + this.refresh() + } + } + break + case 9: // tab key + case 16: // shift key (when shift+tab) + break + case 27: // escape + w2menu.hide(this.el.id + '_menu') + this.refresh() + break + default: { + // intentionally blank + } + } + } + } + keyUp(event) { + if (this.type == 'list') { + let search = query(this.helpers.search_focus) + if (search.val() !== '') { + query(this.el).attr('placeholder', '') + } else { + query(this.el).attr('placeholder', this.tmp.pholder) + } + if (event.keyCode == 13) { + setTimeout(() => { + search.val('') + w2menu.hide(this.el.id + '_menu') + this.refresh() + }, 1) + } + // if arrows are clicked, it will show overlay + if ([38, 40].includes(event.keyCode) && !this.tmp.overlay.overlay.displayed) { + this.updateOverlay() + } + this.refresh() + } + if (this.type == 'combo') { + this.updateOverlay() + } + if (this.type == 'enum') { + let search = this.helpers.multi.find('input') + let styles = getComputedStyle(search.get(0)) + let width = w2utils.getStrWidth(search.val(), + `font-family: ${styles['font-family']}; font-size: ${styles['font-size']};`) + search.css({ width: (width + 15) + 'px' }) + this.resize() + // if arrows are clicked, it will show overlay + if ([38, 40].includes(event.keyCode) && !this.tmp.overlay?.overlay?.displayed) { + this.updateOverlay() + } + } + } + findItemIndex(items, id, parents) { + let inds = [] + if (!parents) parents = [] + if (['list', 'combo', 'enum'].includes(this.type) && this.options.url) { + // remove source, so get it from overlay + let overlay = w2menu.get(this.el.id + '_menu') + if (overlay) { + items = overlay.options.items + this.options.items = items + } + } + items.forEach((item, ind) => { + if (item.id === id) { + inds = parents.concat([ind]) + this.options.index = [ind] + } + if (inds.length == 0 && item.items && item.items.length > 0) { + parents.push(ind) + inds = this.findItemIndex(item.items, id, parents) + parents.pop() + } + }) + return inds + } + updateOverlay(indexOnly) { + let options = this.options + let params + // color + if (this.type === 'color') { + if (query(this.el).prop('readOnly') || query(this.el).prop('disabled')) return + w2color.show(w2utils.extend({ + name: this.el.id + '_color', + anchor: this.el, + transparent: options.transparent, + advanced: options.advanced, + color: this.el.value, + liveUpdate: true + }, this.options)) + .select(event => { + let color = event.detail.color + query(this.el).val(color).trigger('input').trigger('change') + }) + .liveUpdate(event => { + let color = event.detail.color + query(this.helpers.suffix).find(':scope > div').css('background-color', '#' + color) + }) + } + // list + if (['list', 'combo', 'enum'].includes(this.type)) { + let el = this.el + let input = this.el + if (this.type === 'enum') { + el = this.helpers.multi.get(0) + input = query(el).find('input').get(0) + } + if (this.type === 'list') { + let sel = this.selected + if (w2utils.isPlainObject(sel) && Object.keys(sel).length > 0) { + let ind = this.findItemIndex(options.items, sel.id) + if (ind.length > 0) { + options.index = ind + } + } + input = this.helpers.search_focus + } + if (query(this.el).hasClass('has-focus') && !this.el.readOnly && !this.el.disabled) { + params = w2utils.extend({}, options, { + name: this.el.id + '_menu', + anchor: input, + selected: this.selected, + search: false, + render: options.renderDrop, + anchorClass: '', + offsetY: 5, + maxHeight: options.maxDropHeight, // TODO: check + maxWidth: options.maxDropWidth, // TODO: check + minWidth: options.minDropWidth // TODO: check + }) + this.tmp.overlay = w2menu.show(params) + .select(event => { + if (['list', 'combo'].includes(this.type)) { + this.selected = event.detail.item + query(input).val('') + query(this.el).val(this.selected.text).trigger('input').trigger('change') + this.focus({ showMenu: false }) + } else { + let selected = this.selected + let newItem = event.detail?.item + if (newItem) { + // trigger event + let edata = this.trigger('add', { target: this.el, item: newItem, originalEvent: event }) + if (edata.isCancelled === true) return + // default behavior + if (selected.length >= options.max && options.max > 0) selected.pop() + delete newItem.hidden + selected.push(newItem) + query(this.el).trigger('input').trigger('change') + query(this.helpers.multi).find('input').val('') + // updaet selected array in overlays + let overlay = w2menu.get(this.el.id + '_menu') + if (overlay) overlay.options.selected = this.selected + // event after + edata.finish() + } + } + }) + } + } + // date + if (['date', 'time', 'datetime'].includes(this.type)) { + if (query(this.el).prop('readOnly') || query(this.el).prop('disabled')) return + w2date.show(w2utils.extend({ + name: this.el.id + '_date', + anchor: this.el, + value: this.el.value, + }, this.options)) + .select(event => { + let date = event.detail.date + if (date != null) { + query(this.el).val(date).trigger('input').trigger('change') + } + }) + } + } + /* + * INTERNAL FUNCTIONS + */ + isStrValid(ch, loose) { + let isValid = true + switch (this.type) { + case 'int': + if (loose && ['-', this.options.groupSymbol].includes(ch)) { + isValid = true + } else { + isValid = w2utils.isInt(ch.replace(this.options.numberRE, '')) + } + break + case 'percent': + ch = ch.replace(/%/g, '') + case 'float': + if (loose && ['-', '', this.options.decimalSymbol, this.options.groupSymbol].includes(ch)) { + isValid = true + } else { + isValid = w2utils.isFloat(ch.replace(this.options.numberRE, '')) + } + break + case 'money': + case 'currency': + if (loose && ['-', this.options.decimalSymbol, this.options.groupSymbol, this.options.currencyPrefix, + this.options.currencySuffix].includes(ch)) { + isValid = true + } else { + isValid = w2utils.isFloat(ch.replace(this.options.moneyRE, '')) + } + break + case 'bin': + isValid = w2utils.isBin(ch) + break + case 'color': + case 'hex': + isValid = w2utils.isHex(ch) + break + case 'alphanumeric': + isValid = w2utils.isAlphaNumeric(ch) + break + } + return isValid + } + addPrefix() { + if (!this.options.prefix) { + return + } + let helper + let styles = getComputedStyle(this.el) + if (this.tmp['old-padding-left'] == null) { + this.tmp['old-padding-left'] = styles['padding-left'] + } + // remove if already displayed + if (this.helpers.prefix) query(this.helpers.prefix).remove() + query(this.el).before(`
    ${this.options.prefix}
    `) + helper = query(this.el).get(0).previousElementSibling + query(helper) + .css({ + 'color' : styles.color, + 'font-family' : styles['font-family'], + 'font-size' : styles['font-size'], + 'height' : this.el.clientHeight + 'px', + 'padding-top' : styles['padding-top'], + 'padding-bottom' : styles['padding-bottom'], + 'padding-left' : this.tmp['old-padding-left'], + 'padding-right' : 0, + 'margin-top' : (parseInt(styles['margin-top'], 10) + 2) + 'px', + 'margin-bottom' : (parseInt(styles['margin-bottom'], 10) + 1) + 'px', + 'margin-left' : styles['margin-left'], + 'margin-right' : 0, + 'z-index' : 1, + }) + // only if visible + query(this.el).css('padding-left', helper.clientWidth + 'px !important') + // remember helper + this.helpers.prefix = helper + } + addSuffix() { + if (!this.options.suffix && !this.options.arrow) { + return + } + let helper + let self = this + let styles = getComputedStyle(this.el) + if (this.tmp['old-padding-right'] == null) { + this.tmp['old-padding-right'] = styles['padding-right'] + } + let pr = parseInt(styles['padding-right'] || 0) + if (this.options.arrow) { + // remove if already displayed + if (this.helpers.arrow) query(this.helpers.arrow).remove() + // add fresh + query(this.el).after( + '
     '+ + '
    '+ + '
    '+ + '
    '+ + '
    '+ + '
    '+ + '
    '+ + '
    ') + helper = query(this.el).get(0).nextElementSibling + query(helper).css({ + 'color' : styles.color, + 'font-family' : styles['font-family'], + 'font-size' : styles['font-size'], + 'height' : this.el.clientHeight + 'px', + 'padding' : 0, + 'margin-top' : (parseInt(styles['margin-top'], 10) + 1) + 'px', + 'margin-bottom' : 0, + 'border-left' : '1px solid silver', + 'width' : '16px', + 'transform' : 'translateX(-100%)' + }) + .on('mousedown', function(event) { + if (query(event.target).hasClass('arrow-up')) { + self.keyDown(event, { keyCode: 38 }) + } + if (query(event.target).hasClass('arrow-down')) { + self.keyDown(event, { keyCode: 40 }) + } + }) + pr += helper.clientWidth // width of the control + query(this.el).css('padding-right', pr + 'px !important') + this.helpers.arrow = helper + } + if (this.options.suffix !== '') { + // remove if already displayed + if (this.helpers.suffix) query(this.helpers.suffix).remove() + // add fresh + query(this.el).after(`
    ${this.options.suffix}
    `) + helper = query(this.el).get(0).nextElementSibling + query(helper) + .css({ + 'color' : styles.color, + 'font-family' : styles['font-family'], + 'font-size' : styles['font-size'], + 'height' : this.el.clientHeight + 'px', + 'padding-top' : styles['padding-top'], + 'padding-bottom' : styles['padding-bottom'], + 'padding-left' : 0, + 'padding-right' : styles['padding-right'], + 'margin-top' : (parseInt(styles['margin-top'], 10) + 2) + 'px', + 'margin-bottom' : (parseInt(styles['margin-bottom'], 10) + 1) + 'px', + 'transform' : 'translateX(-100%)' + }) + query(this.el).css('padding-right', helper.clientWidth + 'px !important') + this.helpers.suffix = helper + } + } + // Only used for list + addSearch() { + if (this.type !== 'list') return + // clean up & init + if (this.helpers.search) query(this.helpers.search).remove() + // remember original tabindex + let tabIndex = parseInt(query(this.el).attr('tabIndex')) + if (!isNaN(tabIndex) && tabIndex !== -1) this.tmp['old-tabIndex'] = tabIndex + if (this.tmp['old-tabIndex']) tabIndex = this.tmp['old-tabIndex'] + if (tabIndex == null || isNaN(tabIndex)) tabIndex = 0 + // if there is id, add to search with "_search" + let searchId = '' + if (query(this.el).attr('id') != null) { + searchId = 'id="' + query(this.el).attr('id') + '_search"' + } + // build helper + let html = ` +
    + + +
    ` + query(this.el).attr('tabindex', -1).before(html) + let helper = query(this.el).get(0).previousElementSibling + this.helpers.search = helper + this.helpers.search_focus = query(helper).find('input').get(0) + let styles = getComputedStyle(this.el) + query(helper).css({ + width : this.el.clientWidth + 'px', + 'margin-top' : styles['margin-top'], + 'margin-left' : styles['margin-left'], + 'margin-bottom' : styles['margin-bottom'], + 'margin-right' : styles['margin-right'] + }) + .find('input') + .css({ + cursor : 'default', + width : '100%', + opacity : 1, + padding : styles.padding, + margin : styles.margin, + border : '1px solid transparent', + 'background-color' : 'transparent' + }) + // INPUT events + query(helper).find('input') + .off('.helper') + .on('focus.helper', event => { + query(event.target).val('') + this.tmp.pholder = query(this.el).attr('placeholder') ?? '' + this.focus(event) + event.stopPropagation() + }) + .on('blur.helper', event => { + query(event.target).val('') + if (this.tmp.pholder != null) query(this.el).attr('placeholder', this.tmp.pholder) + this.blur(event) + event.stopPropagation() + }) + .on('keydown.helper', event => { this.keyDown(event) }) + .on('keyup.helper', event => { this.keyUp(event) }) + // MAIN div + query(helper).on('click', event => { + query(event.target).find('input').focus() + }) + } + // Used in enum/file + addMultiSearch() { + if (!['enum', 'file'].includes(this.type)) { + return + } + // clean up & init + query(this.helpers.multi).remove() + // build helper + let html = '' + let styles = getComputedStyle(this.el) + let margin = w2utils.stripSpaces(` + margin-top: 0px; + margin-bottom: 0px; + margin-left: ${styles['margin-left']}; + margin-right: ${styles['margin-right']}; + width: ${(w2utils.getSize(this.el, 'width') - parseInt(styles['margin-left'], 10) + - parseInt(styles['margin-right'], 10))}px; + `) + if (this.tmp['min-height'] == null) { + let min = this.tmp['min-height'] = parseInt((styles['min-height'] != 'none' ? styles['min-height'] : 0) || 0) + let current = parseInt(styles.height) + this.tmp['min-height'] = Math.max(min, current) + } + if (this.tmp['max-height'] == null && styles['max-height'] != 'none') { + this.tmp['max-height'] = parseInt(styles['max-height']) + } + // if there is id, add to search with "_search" + let searchId = '' + if (query(this.el).attr('id') != null) { + searchId = `id="${query(this.el).attr('id')}_search"` + } + // remember original tabindex + let tabIndex = parseInt(query(this.el).attr('tabIndex')) + if (!isNaN(tabIndex) && tabIndex !== -1) this.tmp['old-tabIndex'] = tabIndex + if (this.tmp['old-tabIndex']) tabIndex = this.tmp['old-tabIndex'] + if (tabIndex == null || isNaN(tabIndex)) tabIndex = 0 + if (this.type === 'enum') { + html = ` +
    +
    + +
    +
    ` + } + if (this.type === 'file') { + html = ` +
    +
    + +
    +
    + +
    +
    ` + } + // old bg and border + this.tmp['old-background-color'] = styles['background-color'] + this.tmp['old-border-color'] = styles['border-color'] + query(this.el) + .before(html) + .css({ + 'border-color': 'transparent', + 'background-color': 'transparent' + }) + let div = query(this.el.previousElementSibling) + this.helpers.multi = div + query(this.el).attr('tabindex', -1) + // click anywhere on the field + div.on('click', event => { this.focus(event) }) + // search field + div.find('input:not(.file-input)') + .on('click', event => { this.click(event) }) + .on('focus', event => { this.focus(event) }) + .on('blur', event => { this.blur(event) }) + .on('keydown', event => { this.keyDown(event) }) + .on('keyup', event => { this.keyUp(event) }) + // file input + if (this.type === 'file') { + div.find('input.file-input') + .off('.drag') + .on('click.drag', (event) => { + event.stopPropagation() + if (query(this.el).prop('readOnly') || query(this.el).prop('disabled')) return + this.focus(event) + }) + .on('dragenter.drag', (event) => { + if (query(this.el).prop('readOnly') || query(this.el).prop('disabled')) return + div.addClass('w2ui-file-dragover') + }) + .on('dragleave.drag', (event) => { + if (query(this.el).prop('readOnly') || query(this.el).prop('disabled')) return + div.removeClass('w2ui-file-dragover') + }) + .on('drop.drag', (event) => { + if (query(this.el).prop('readOnly') || query(this.el).prop('disabled')) return + div.removeClass('w2ui-file-dragover') + let files = Array.from(event.dataTransfer.files) + files.forEach(file => { this.addFile(file) }) + this.focus(event) + // cancel to stop browser behaviour + event.preventDefault() + event.stopPropagation() + }) + .on('dragover.drag', (event) => { + // cancel to stop browser behaviour + event.preventDefault() + event.stopPropagation() + }) + .on('change.drag', (event) => { + if (typeof event.target.files !== 'undefined') { + Array.from(event.target.files).forEach(file => { this.addFile(file) }) + } + this.focus(event) + }) + } + this.refresh() + } + addFile(file) { + let options = this.options + let selected = this.selected + let newItem = { + name : file.name, + type : file.type, + modified : file.lastModifiedDate, + size : file.size, + content : null, + file : file + } + let size = 0 + let cnt = 0 + let errors = [] + if (Array.isArray(selected)) { + selected.forEach(item => { + if (item.name == file.name && item.size == file.size) { + errors.push(w2utils.lang('The file "${name}" (${size}) is already added.', { + name: file.name, size: w2utils.formatSize(file.size) })) + } + size += item.size + cnt++ + }) + } + if (options.maxFileSize !== 0 && newItem.size > options.maxFileSize) { + errors.push(w2utils.lang('Maximum file size is ${size}', { size: w2utils.formatSize(options.maxFileSize) })) + } + if (options.maxSize !== 0 && size + newItem.size > options.maxSize) { + errors.push(w2utils.lang('Maximum total size is ${size}', { size: w2utils.formatSize(options.maxSize) })) + } + if (options.max !== 0 && cnt >= options.max) { + errors.push(w2utils.lang('Maximum number of files is ${count}', { count: options.max })) + } + // trigger event + let edata = this.trigger('add', { target: this.el, file: newItem, total: cnt, totalSize: size, errors }) + if (edata.isCancelled === true) return + // if errors and not silent + if (options.silent !== true && errors.length > 0) { + w2tooltip.show({ + anchor: this.el, + html: 'Errors: ' + errors.join('
    ') + }) + console.log('ERRORS (while adding files): ', errors) + return + } + // check params + selected.push(newItem) + // read file as base64 + if (typeof FileReader !== 'undefined' && options.readContent === true) { + let reader = new FileReader() + let self = this + // need a closure + reader.onload = (function onload() { + return function closure(event) { + let fl = event.target.result + let ind = fl.indexOf(',') + newItem.content = fl.substr(ind + 1) + self.refresh() + query(self.el).trigger('input').trigger('change') + // event after + edata.finish() + } + })() + reader.readAsDataURL(file) + } else { + this.refresh() + query(this.el).trigger('input').trigger('change') + edata.finish() + } + } + // move cursror to end + moveCaret2end() { + setTimeout(() => { + this.el.setSelectionRange(this.el.value.length, this.el.value.length) + }, 0) + } +} +export { + w2ui, w2utils, query, w2locale, w2event, w2base, + w2popup, w2alert, w2confirm, w2prompt, Dialog, + w2tooltip, w2menu, w2color, w2date, Tooltip, + w2toolbar, w2sidebar, w2tabs, w2layout, w2grid, w2form, w2field +} \ No newline at end of file diff --git a/src/resources/w2ui-2.0/w2ui-2.0.es6.min.js b/src/resources/w2ui-2.0/w2ui-2.0.es6.min.js new file mode 100644 index 0000000..8cde217 --- /dev/null +++ b/src/resources/w2ui-2.0/w2ui-2.0.es6.min.js @@ -0,0 +1,486 @@ +/* w2ui 2.0.0 (4/26/2023, 10:40:17 AM) (c) http://w2ui.com, vitmalina@gmail.com */ +class w2event{constructor(e,t){Object.assign(this,{type:t.type??null,detail:t,owner:e,target:t.target??null,phase:t.phase??"before",object:t.object??null,execute:null,isStopped:!1,isCancelled:!1,onComplete:null,listeners:[]}),delete t.type,delete t.target,delete t.object,this.complete=new Promise((e,t)=>{this._resolve=e,this._reject=t}),this.complete.catch(()=>{})}finish(e){e&&w2utils.extend(this.detail,e),this.phase="after",this.owner.trigger.call(this.owner,this)}done(e){this.listeners.push(e)}preventDefault(){this._reject(),this.isCancelled=!0}stopPropagation(){this.isStopped=!0}}class w2base{constructor(e){if(this.activeEvents=[],this.listeners=[],void 0!==e){if(!w2utils.checkName(e))return;w2ui[e]=this}this.debug=!1}on(e,r){return(e="string"==typeof e?e.split(/[,\s]+/):[e]).forEach(e=>{var t,i,s,l="string"==typeof e?e:e.type+":"+e.execute+"."+e.scope;"string"==typeof e&&([i,t]=e.split("."),[i,s]=i.replace(":complete",":after").replace(":done",":after").split(":"),e={type:i,execute:s??"before",scope:t}),(e=w2utils.extend({type:null,execute:"before",onComplete:null},e)).type?r?(Array.isArray(this.listeners)||(this.listeners=[]),this.listeners.push({name:l,edata:e,handler:r}),this.debug&&console.log("w2base: add event",{name:l,edata:e,handler:r})):console.log("ERROR: You must specify event handler function when calling .on() method of "+this.name):console.log("ERROR: You must specify event type when calling .on() method of "+this.name)}),this}off(e,r){return(e="string"==typeof e?e.split(/[,\s]+/):[e]).forEach(i=>{var e,t,s,l="string"==typeof i?i:i.type+":"+i.execute+"."+i.scope;if("string"==typeof i&&([t,e]=i.split("."),[t,s]=t.replace(":complete",":after").replace(":done",":after").split(":"),i={type:t||"*",execute:s||"",scope:e||""}),(i=w2utils.extend({type:null,execute:null,onComplete:null},i)).type||i.scope){r=r||null;let t=0;this.listeners=this.listeners.filter(e=>"*"!==i.type&&i.type!==e.edata.type||""!==i.execute&&i.execute!==e.edata.execute||""!==i.scope&&i.scope!==e.edata.scope||null!=i.handler&&i.handler!==e.edata.handler||(t++,!1)),this.debug&&console.log(`w2base: remove event (${t})`,{name:l,edata:i,handler:r})}else console.log("ERROR: You must specify event type when calling .off() method of "+this.name)}),this}trigger(e,i){if(1==arguments.length?i=e:(i.type=e,i.target=i.target??this),w2utils.isPlainObject(i)&&"after"==i.phase){if(!(i=this.activeEvents.find(e=>e.type==i.type&&e.target==i.target)))return void console.log(`ERROR: Cannot find even handler for "${i.type}" on "${i.target}".`);console.log("NOTICE: This syntax \"edata.trigger({ phase: 'after' })\" is outdated. Use edata.finish() instead.")}else i instanceof w2event||(i=new w2event(this,i),this.activeEvents.push(i));let s,t,l;Array.isArray(this.listeners)||(this.listeners=[]),this.debug&&console.log(`w2base: trigger "${i.type}:${i.phase}"`,i);for(let e=this.listeners.length-1;0<=e;e--){let t=this.listeners[e];if(!(null==t||t.edata.type!==i.type&&"*"!==t.edata.type||t.edata.target!==i.target&&null!=t.edata.target||t.edata.execute!==i.phase&&"*"!==t.edata.execute&&"*"!==t.edata.phase)&&(Object.keys(t.edata).forEach(e=>{null==i[e]&&null!=t.edata[e]&&(i[e]=t.edata[e])}),s=[],l=new RegExp(/\((.*?)\)/).exec(String(t.handler).split("=>")[0]),2===(s=l?l[1].split(/\s*,\s*/):s).length?(t.handler.call(this,i.target,i),this.debug&&console.log(" - call (old)",t.handler)):(t.handler.call(this,i),this.debug&&console.log(" - call",t.handler)),!0===i.isStopped||!0===i.stop))return i}e="on"+i.type.substr(0,1).toUpperCase()+i.type.substr(1);if(!("before"===i.phase&&"function"==typeof this[e]&&(t=this[e],s=[],l=new RegExp(/\((.*?)\)/).exec(String(t).split("=>")[0]),2===(s=l?l[1].split(/\s*,\s*/):s).length?(t.call(this,i.target,i),this.debug&&console.log(" - call: on[Event] (old)",t)):(t.call(this,i),this.debug&&console.log(" - call: on[Event]",t)),!0===i.isStopped||!0===i.stop)||null!=i.object&&"before"===i.phase&&"function"==typeof i.object[e]&&(t=i.object[e],s=[],l=new RegExp(/\((.*?)\)/).exec(String(t).split("=>")[0]),2===(s=l?l[1].split(/\s*,\s*/):s).length?(t.call(this,i.target,i),this.debug&&console.log(" - call: edata.object (old)",t)):(t.call(this,i),this.debug&&console.log(" - call: edata.object",t)),!0===i.isStopped||!0===i.stop)||"after"!==i.phase)){"function"==typeof i.onComplete&&i.onComplete.call(this,i);for(let e=0;e{this[t]=e})}static _fragment(e){let i=document.createElement("template");return i.innerHTML=e,i.content.childNodes.forEach(e=>{var t=Query._scriptConvert(e);t!=e&&i.content.replaceChild(t,e)}),i.content}static _scriptConvert(e){let t=e=>{var t=e.ownerDocument.createElement("script"),i=(t.text=e.text,e.attributes);for(let e=0;e{e.parentNode.replaceChild(t(e),e)}),e}static _fixProp(e){var t={cellpadding:"cellPadding",cellspacing:"cellSpacing",class:"className",colspan:"colSpan",contenteditable:"contentEditable",for:"htmlFor",frameborder:"frameBorder",maxlength:"maxLength",readonly:"readOnly",rowspan:"rowSpan",tabindex:"tabIndex",usemap:"useMap"};return t[e]||e}_insert(l,i){let r=[],a=this.length;if(!(a<1)){let e=this;if("string"==typeof i)this.each(e=>{var t=Query._fragment(i);r.push(...t.childNodes),e[l](t)});else if(i instanceof Query){let s=1==a;i.each(i=>{this.each(e=>{var t=s?i:i.cloneNode(!0);r.push(t),e[l](t),Query._scriptConvert(t)})}),s||i.remove()}else{if(!(i instanceof Node))throw new Error(`Incorrect argument for "${l}(html)". It expects one string argument.`);this.each(e=>{var t=1===a?i:Query._fragment(i.outerHTML);r.push(...1===a?[i]:t.childNodes),e[l](t)}),1{e=Array.from(e.querySelectorAll(t));0{(e===t||"string"==typeof t&&e.matches&&e.matches(t)||"function"==typeof t&&t(e))&&i.push(e)}),new Query(i,this.context,this)}next(){let t=[];return this.each(e=>{e=e.nextElementSibling;e&&t.push(e)}),new Query(t,this.context,this)}prev(){let t=[];return this.each(e=>{e=e.previousElementSibling;e&&t.push(e)}),new Query(t,this.context,this)}shadow(e){let t=[];this.each(e=>{e.shadowRoot&&t.push(e.shadowRoot)});var i=new Query(t,this.context,this);return e?i.find(e):i}closest(t){let i=[];return this.each(e=>{e=e.closest(t);e&&i.push(e)}),new Query(i,this.context,this)}host(t){let i=[],s=e=>e.parentNode?s(e.parentNode):e,l=e=>{e=s(e);i.push(e.host||e),e.host&&t&&l(e.host)};return this.each(e=>{l(e)}),new Query(i,this.context,this)}parent(e){return this.parents(e,!0)}parents(e,t){let i=[],s=e=>{if(-1==i.indexOf(e)&&i.push(e),!t&&e.parentNode)return s(e.parentNode)};this.each(e=>{e.parentNode&&s(e.parentNode)});var l=new Query(i,this.context,this);return e?l.filter(e):l}add(e){e=e instanceof Query?e.nodes:Array.isArray(e)?e:[e];return new Query(this.nodes.concat(e),this.context,this)}each(i){return this.nodes.forEach((e,t)=>{i(e,t,this)}),this}append(e){return this._insert("append",e)}prepend(e){return this._insert("prepend",e)}after(e){return this._insert("after",e)}before(e){return this._insert("before",e)}replace(e){return this._insert("replaceWith",e)}remove(){return this.each(e=>{e.remove()}),this}css(e,t){let s=e;var i,l=arguments.length;return 0===l||1===l&&"string"==typeof e?this[0]?(l=this[0].style,"string"==typeof e?(i=l.getPropertyPriority(e),l.getPropertyValue(e)+(i?"!"+i:"")):Object.fromEntries(this[0].style.cssText.split(";").filter(e=>!!e).map(e=>e.split(":").map(e=>e.trim())))):void 0:("object"!=typeof e&&((s={})[e]=t),this.each((i,e)=>{Object.keys(s).forEach(e=>{var t=String(s[e]).toLowerCase().includes("!important")?"important":"";i.style.setProperty(e,String(s[e]).replace(/\!important/i,""),t)})}),this)}addClass(e){return this.toggleClass(e,!0),this}removeClass(e){return this.toggleClass(e,!1),this}toggleClass(t,s){return"string"==typeof t&&(t=t.split(/[,\s]+/)),this.each(i=>{let e=t;(e=null==e&&!1===s?Array.from(i.classList):e).forEach(t=>{if(""!==t){let e=null!=s?s?"add":"remove":"toggle";i.classList[e](t)}})}),this}hasClass(e){if(null==(e="string"==typeof e?e.split(/[,\s]+/):e)&&0{i=i||e.every(e=>Array.from(t.classList??[]).includes(e))}),i}on(e,s,l){"function"==typeof s&&(l=s,s=void 0);let r;return s?.delegate&&(r=s.delegate,delete s.delegate),(e=e.split(/[,\s]+/)).forEach(e=>{let[t,i]=String(e).toLowerCase().split(".");if(r){let i=l;l=e=>{var t=query(e.target).parents(r);0{this._save(e,"events",[{event:t,scope:i,callback:l,options:s}]),e.addEventListener(t,l,s)})}),this}off(e,t,r){return"function"==typeof t&&(r=t,t=void 0),(e=(e??"").split(/[,\s]+/)).forEach(e=>{let[s,l]=String(e).toLowerCase().split(".");this.each(t=>{if(Array.isArray(t._mQuery?.events))for(let e=t._mQuery.events.length-1;0<=e;e--){var i=t._mQuery.events[e];null==l||""===l?i.event!=s&&""!==s||i.callback!=r&&null!=r||(t.removeEventListener(i.event,i.callback,i.options),t._mQuery.events.splice(e,1)):i.event!=s&&""!==s||i.scope!=l||(t.removeEventListener(i.event,i.callback,i.options),t._mQuery.events.splice(e,1))}})}),this}trigger(e,t){let i;return i=e instanceof Event||e instanceof CustomEvent?e:new(["click","dblclick","mousedown","mouseup","mousemove"].includes(e)?MouseEvent:["keydown","keyup","keypress"].includes(e)?KeyboardEvent:Event)(e,t),this.each(e=>{e.dispatchEvent(i)}),this}attr(t,i){if(void 0===i&&"string"==typeof t)return this[0]?this[0].getAttribute(t):void 0;{let e={};return"object"==typeof t?e=t:e[t]=i,this.each(i=>{Object.entries(e).forEach(([e,t])=>{i.setAttribute(e,t)})}),this}}removeAttr(){return this.each(t=>{Array.from(arguments).forEach(e=>{t.removeAttribute(e)})}),this}prop(t,i){if(void 0===i&&"string"==typeof t)return this[0]?this[0][t]:void 0;{let e={};return"object"==typeof t?e=t:e[t]=i,this.each(i=>{Object.entries(e).forEach(([e,t])=>{e=Query._fixProp(e);i[e]=t,"innerHTML"==e&&Query._scriptConvert(i)})}),this}}removeProp(){return this.each(t=>{Array.from(arguments).forEach(e=>{delete t[Query._fixProp(e)]})}),this}data(i,t){if(i instanceof Object)Object.entries(i).forEach(e=>{this.data(e[0],e[1])});else{if(i&&-1!=i.indexOf("-")&&console.error(`Key "${i}" contains "-" (dash). Dashes are not allowed in property names. Use camelCase instead.`),!(arguments.length<2))return this.each(e=>{null!=t?e.dataset[i]=t instanceof Object?JSON.stringify(t):t:delete e.dataset[i]}),this;if(this[0]){let t=Object.assign({},this[0].dataset);return Object.keys(t).forEach(e=>{if(t[e].startsWith("[")||t[e].startsWith("{"))try{t[e]=JSON.parse(t[e])}catch(e){}}),i?t[i]:t}}}removeData(e){return"string"==typeof e&&(e=e.split(/[,\s]+/)),this.each(t=>{e.forEach(e=>{delete t.dataset[e]})}),this}show(){return this.toggle(!0)}hide(){return this.toggle(!1)}toggle(r){return this.each(e=>{var t,i=e.style.display,s=getComputedStyle(e).display,l="none"==i||"none"==s;!l||null!=r&&!0!==r||(t=e instanceof HTMLTableRowElement?"table-row":e instanceof HTMLTableCellElement?"table-cell":"block",e.style.display=e._mQuery?.prevDisplay??(i==s&&"none"!=s?"":t),this._save(e,"prevDisplay",null)),l||null!=r&&!1!==r||("none"!=s&&this._save(e,"prevDisplay",s),e.style.setProperty("display","none"))})}empty(){return this.html("")}html(e){return this.prop("innerHTML",e)}text(e){return this.prop("textContent",e)}val(e){return this.prop("value",e)}change(){return this.trigger("change")}click(){return this.trigger("click")}}let query=function(e,t){if("function"!=typeof e)return new Query(e,t);"complete"==document.readyState?e():window.addEventListener("load",e)},w2ui=(query.html=e=>{e=Query._fragment(e);return query(e.children,e)},query.version=Query.version,{});class Utils{constructor(){this.version="2.0.x",this.tmp={},this.settings=this.extend({},{dataType:"HTTPJSON",dateStartYear:1950,dateEndYear:2030,macButtonOrder:!1,warnNoPhrase:!1},w2locale,{phrases:null}),this.i18nCompare=Intl.Collator().compare,this.hasLocalStorage=function(){var e="w2ui_test";try{return localStorage.setItem(e,e),localStorage.removeItem(e),!0}catch(e){return!1}}(),this.isMac=/Mac/i.test(navigator.platform),this.isMobile=/(iphone|ipod|ipad|mobile|android)/i.test(navigator.userAgent),this.isIOS=/(iphone|ipod|ipad)/i.test(navigator.platform),this.isAndroid=/(android)/i.test(navigator.userAgent),this.isSafari=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),this.formatters={number(e,t){return 20'+w2utils.formatDate(i,t)+""},datetime(e,t){if(""===t&&(t=w2utils.settings.datetimeFormat),null==e||0===e||""===e)return"";let i=w2utils.isDateTime(e,t,!0);return''+w2utils.formatDateTime(i,t)+""},time(e,t){if(""===t&&(t=w2utils.settings.timeFormat),null==e||0===e||""===e)return"";let i=w2utils.isDateTime(e,t="h24"===(t="h12"===t?"hh:mi pm":t)?"h24:mi":t,!0);return''+w2utils.formatTime(e,t)+""},timestamp(e,t){if(""===t&&(t=w2utils.settings.datetimeFormat),null==e||0===e||""===e)return"";let i=w2utils.isDateTime(e,t,!0);return(i=!1===i?w2utils.isDate(e,t,!0):i).toString?i.toString():""},gmt(e,t){if(""===t&&(t=w2utils.settings.datetimeFormat),null==e||0===e||""===e)return"";let i=w2utils.isDateTime(e,t,!0);return(i=!1===i?w2utils.isDate(e,t,!0):i).toUTCString?i.toUTCString():""},age(e,t){if(null==e||0===e||""===e)return"";let i=w2utils.isDateTime(e,null,!0);return''+w2utils.age(e)+(t?" "+t:"")+""},interval(e,t){return null==e||0===e||""===e?"":w2utils.interval(e)+(t?" "+t:"")},toggle(e,t){return e?"Yes":""},password(t,e){let i="";for(let e=0;ei||!this.isInt(e[0])||2'+(r=l==e?this.lang("Yesterday"):r)+""}formatSize(e){var t;return this.isFloat(e)&&""!==e?0===(e=parseFloat(e))?0:(t=parseInt(Math.floor(Math.log(e)/Math.log(1024))),(Math.floor(e/Math.pow(1024,t)*10)/10).toFixed(0===t?0:1)+" "+(["Bt","KB","MB","GB","TB","PB","EB","ZB"][t]||"??")):""}formatNumber(e,t,i){return null==e||""===e||"object"==typeof e?"":(i={minimumFractionDigits:parseInt(t),maximumFractionDigits:parseInt(t),useGrouping:!!i},(null==t||t<0)&&(i.minimumFractionDigits=0,i.maximumFractionDigits=20),parseFloat(e).toLocaleString(this.settings.locale,i))}formatDate(e,t){if(t=t||this.settings.dateFormat,""===e||null==e||"object"==typeof e&&!e.getMonth)return"";let i=new Date(e);var s,l;return this.isInt(e)&&(i=new Date(Number(e))),"Invalid Date"===String(i)?"":(e=i.getFullYear(),s=i.getMonth(),l=i.getDate(),t.toLowerCase().replace("month",this.settings.fullmonths[s]).replace("mon",this.settings.shortmonths[s]).replace(/yyyy/g,("000"+e).slice(-4)).replace(/yyy/g,("000"+e).slice(-4)).replace(/yy/g,("0"+e).slice(-2)).replace(/(^|[^a-z$])y/g,"$1"+e).replace(/mm/g,("0"+(s+1)).slice(-2)).replace(/dd/g,("0"+l).slice(-2)).replace(/th/g,1==l?"st":"th").replace(/th/g,2==l?"nd":"th").replace(/th/g,3==l?"rd":"th").replace(/(^|[^a-z$])m/g,"$1"+(s+1)).replace(/(^|[^a-z$])d/g,"$1"+l))}formatTime(e,t){if(t=t||this.settings.timeFormat,""===e||null==e||"object"==typeof e&&!e.getMonth)return"";let i=new Date(e);if(this.isInt(e)&&(i=new Date(Number(e))),this.isTime(e)&&(e=this.isTime(e,!0),(i=new Date).setHours(e.hours),i.setMinutes(e.minutes)),"Invalid Date"===String(i))return"";let s="am",l=i.getHours();e=i.getHours();let r=i.getMinutes(),a=i.getSeconds();return r<10&&(r="0"+r),a<10&&(a="0"+a),-1===t.indexOf("am")&&-1===t.indexOf("pm")||(12<=l&&(s="pm"),12{i[t]=this.stripSpaces(e)}):(i=this.extend({},i),Object.keys(i).forEach(e=>{i[e]=this.stripSpaces(i[e])}))}return i}stripTags(i){if(null!=i)switch(typeof i){case"number":break;case"string":i=String(i).replace(/<(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*>/gi,"");break;case"object":Array.isArray(i)?(i=this.extend([],i)).forEach((e,t)=>{i[t]=this.stripTags(e)}):(i=this.extend({},i),Object.keys(i).forEach(e=>{i[e]=this.stripTags(i[e])}))}return i}encodeTags(i){if(null!=i)switch(typeof i){case"number":break;case"string":i=String(i).replace(/&/g,"&").replace(/>/g,">").replace(/{i[t]=this.encodeTags(e)}):(i=this.extend({},i),Object.keys(i).forEach(e=>{i[e]=this.encodeTags(i[e])}))}return i}decodeTags(i){if(null!=i)switch(typeof i){case"number":break;case"string":i=String(i).replace(/>/g,">").replace(/</g,"<").replace(/"/g,'"').replace(/&/g,"&");break;case"object":Array.isArray(i)?(i=this.extend([],i)).forEach((e,t)=>{i[t]=this.decodeTags(e)}):(i=this.extend({},i),Object.keys(i).forEach(e=>{i[e]=this.decodeTags(i[e])}))}return i}escapeId(e){return""===e||null==e?"":(e+"").replace(/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,(e,t)=>t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e)}unescapeId(e){return""===e||null==e?"":e.replace(/\\[\da-fA-F]{1,6}[\x20\t\r\n\f]?|\\([^\r\n\f])/g,(e,t)=>{e="0x"+e.slice(1)-65536;return t||(e<0?String.fromCharCode(65536+e):String.fromCharCode(e>>10|55296,1023&e|56320))})}base64encode(e){return btoa(e)}base64decode(e){return atob(e)}async sha256(e){e=(new TextEncoder).encode(e);return crypto.subtle.digest("SHA-256",e).then(e=>{return Array.from(new Uint8Array(e)).map(e=>e.toString(16).padStart(2,"0")).join("")})}transition(r,a,n,o){return new Promise((e,t)=>{var i=getComputedStyle(r);let s=parseInt(i.width),l=parseInt(i.height);if(r&&a){switch(r.parentNode.style.cssText+="perspective: 900px; overflow: hidden;",r.style.cssText+="; position: absolute; z-index: 1019; backface-visibility: hidden",a.style.cssText+="; position: absolute; z-index: 1020; backface-visibility: hidden",n){case"slide-left":r.style.cssText+="overflow: hidden; transform: translate3d(0, 0, 0)",a.style.cssText+="overflow: hidden; transform: translate3d("+s+"px, 0, 0)",query(a).show(),setTimeout(()=>{a.style.cssText+="transition: 0.5s; transform: translate3d(0, 0, 0)",r.style.cssText+="transition: 0.5s; transform: translate3d(-"+s+"px, 0, 0)"},1);break;case"slide-right":r.style.cssText+="overflow: hidden; transform: translate3d(0, 0, 0)",a.style.cssText+="overflow: hidden; transform: translate3d(-"+s+"px, 0, 0)",query(a).show(),setTimeout(()=>{a.style.cssText+="transition: 0.5s; transform: translate3d(0px, 0, 0)",r.style.cssText+="transition: 0.5s; transform: translate3d("+s+"px, 0, 0)"},1);break;case"slide-down":r.style.cssText+="overflow: hidden; z-index: 1; transform: translate3d(0, 0, 0)",a.style.cssText+="overflow: hidden; z-index: 0; transform: translate3d(0, 0, 0)",query(a).show(),setTimeout(()=>{a.style.cssText+="transition: 0.5s; transform: translate3d(0, 0, 0)",r.style.cssText+="transition: 0.5s; transform: translate3d(0, "+l+"px, 0)"},1);break;case"slide-up":r.style.cssText+="overflow: hidden; transform: translate3d(0, 0, 0)",a.style.cssText+="overflow: hidden; transform: translate3d(0, "+l+"px, 0)",query(a).show(),setTimeout(()=>{a.style.cssText+="transition: 0.5s; transform: translate3d(0, 0, 0)",r.style.cssText+="transition: 0.5s; transform: translate3d(0, 0, 0)"},1);break;case"flip-left":r.style.cssText+="overflow: hidden; transform: rotateY(0deg)",a.style.cssText+="overflow: hidden; transform: rotateY(-180deg)",query(a).show(),setTimeout(()=>{a.style.cssText+="transition: 0.5s; transform: rotateY(0deg)",r.style.cssText+="transition: 0.5s; transform: rotateY(180deg)"},1);break;case"flip-right":r.style.cssText+="overflow: hidden; transform: rotateY(0deg)",a.style.cssText+="overflow: hidden; transform: rotateY(180deg)",query(a).show(),setTimeout(()=>{a.style.cssText+="transition: 0.5s; transform: rotateY(0deg)",r.style.cssText+="transition: 0.5s; transform: rotateY(-180deg)"},1);break;case"flip-down":r.style.cssText+="overflow: hidden; transform: rotateX(0deg)",a.style.cssText+="overflow: hidden; transform: rotateX(180deg)",query(a).show(),setTimeout(()=>{a.style.cssText+="transition: 0.5s; transform: rotateX(0deg)",r.style.cssText+="transition: 0.5s; transform: rotateX(-180deg)"},1);break;case"flip-up":r.style.cssText+="overflow: hidden; transform: rotateX(0deg)",a.style.cssText+="overflow: hidden; transform: rotateX(-180deg)",query(a).show(),setTimeout(()=>{a.style.cssText+="transition: 0.5s; transform: rotateX(0deg)",r.style.cssText+="transition: 0.5s; transform: rotateX(180deg)"},1);break;case"pop-in":r.style.cssText+="overflow: hidden; transform: translate3d(0, 0, 0)",a.style.cssText+="overflow: hidden; transform: translate3d(0, 0, 0); transform: scale(.8); opacity: 0;",query(a).show(),setTimeout(()=>{a.style.cssText+="transition: 0.5s; transform: scale(1); opacity: 1;",r.style.cssText+="transition: 0.5s;"},1);break;case"pop-out":r.style.cssText+="overflow: hidden; transform: translate3d(0, 0, 0); transform: scale(1); opacity: 1;",a.style.cssText+="overflow: hidden; transform: translate3d(0, 0, 0); opacity: 0;",query(a).show(),setTimeout(()=>{a.style.cssText+="transition: 0.5s; opacity: 1;",r.style.cssText+="transition: 0.5s; transform: scale(1.7); opacity: 0;"},1);break;default:r.style.cssText+="overflow: hidden; transform: translate3d(0, 0, 0)",a.style.cssText+="overflow: hidden; translate3d(0, 0, 0); opacity: 0;",query(a).show(),setTimeout(()=>{a.style.cssText+="transition: 0.5s; opacity: 1;",r.style.cssText+="transition: 0.5s"},1)}setTimeout(()=>{"slide-down"===n&&(query(r).css("z-index","1019"),query(a).css("z-index","1020")),a&&query(a).css({opacity:"1"}).css({transition:"",transform:""}),r&&query(r).css({opacity:"1"}).css({transition:"",transform:""}),"function"==typeof o&&o(),e()},500)}else console.log("ERROR: Cannot do transition when one of the divs is null")})}lock(l,r={}){if(null!=l){"string"==typeof r&&(r={msg:r}),arguments[2]&&(r.spinner=arguments[2]),r=this.extend({spinner:!1},r),l?.[0]instanceof Node&&(l=Array.isArray(l)?l:l.get()),r.msg||0===r.msg||(r.msg=""),this.unlock(l);var a=query(l).get(0);let e=a.scrollWidth,t=a.scrollHeight,i=("BODY"==a.tagName&&(e
    `+'
    '),query(l).find(".w2ui-lock"));a=query(l).find(".w2ui-lock-msg"),l=(r.msg||a.css({"background-color":"transparent","background-image":"none",border:"0px","box-shadow":"none"}),!0===r.spinner&&(r.msg=`
    `+r.msg),r.msg?a.html(r.msg).css("display","block"):a.remove(),null!=r.opacity&&i.css("opacity",r.opacity),i.css({display:"block"}),r.bgColor&&i.css({"background-color":r.bgColor}),getComputedStyle(i.get(0)));let s=l.opacity??.15;i.on("mousedown",function(){"function"==typeof r.onClick?r.onClick():i.css({transition:".2s",opacity:1.5*s})}).on("mouseup",function(){"function"!=typeof r.onClick&&i.css({transition:".2s",opacity:s})}).on("mousewheel",function(e){e&&(e.stopPropagation(),e.preventDefault())})}}unlock(e,t){var i;null!=e&&(clearTimeout(e._prevUnlock),e?.[0]instanceof Node&&(e=Array.isArray(e)?e:e.get()),this.isInt(t)&&0{query(e).find(".w2ui-lock").remove()},t)):query(e).find(".w2ui-lock").remove(),query(e).find(".w2ui-lock-msg").remove())}message(r,s){let e,t,l;var i=()=>{var e=query(r?.box).find(".w2ui-message");0!=e.length&&"function"==typeof(s=e.get(0)._msg_options||{})?.close&&s.close()};let a=e=>{var t,i=e.box._msg_prevFocus;query(r.box).find(".w2ui-message").length<=1?r.owner?r.owner.unlock(r.param,150):this.unlock(r.box,150):query(r.box).find(`#w2ui-message-${r.owner?.name}-`+(e.msgIndex-1)).css("z-index",1500),i?0<(t=query(i).closest(".w2ui-message")).length?t.get(0)._msg_options.setFocus(i):i.focus():"function"==typeof r.owner?.focus&&r.owner.focus(),query(e.box).remove(),0===e.msgIndex&&(c.css("z-index",e.tmp.zIndex),query(r.box).css("overflow",e.tmp.overflow)),e.trigger&&l.finish()};if("object"!=typeof(s="string"!=typeof s&&"number"!=typeof s?s:{width:String(s).length<300?350:550,height:String(s).length<300?170:250,text:String(s)}))return void i();null!=s.text&&(s.body=`
    ${s.text}
    `),null==s.width&&(s.width=350),null==s.height&&(s.height=170),null==s.hideOn&&(s.hideOn=["esc"]),null==s.on&&(h=s,s=new w2base,w2utils.extend(s,h)),s.on("open",e=>{w2utils.bindEvents(query(s.box).find(".w2ui-eaction"),s),query(e.detail.box).find("button, input, textarea, [name=hidden-first]").off(".message").on("keydown.message",function(e){27==e.keyCode&&s.hideOn.includes("esc")&&(s.cancelAction?s.action(s.cancelAction):s.close())}),setTimeout(()=>s.setFocus(s.focus),300)}),s.off(".prom");let n={self:s,action(e){return s.on("action.prom",e),n},close(e){return s.on("close.prom",e),n},open(e){return s.on("open.prom",e),n},then(e){return s.on("open:after.prom",e),n}},o=(null==s.actions&&null==s.buttons&&null==s.html&&(s.actions={Ok(e){e.detail.self.close()}}),s.off(".buttons"),null!=s.actions&&(s.buttons="",Object.keys(s.actions).forEach(e=>{var t=s.actions[e];let i=e;"function"==typeof t&&(s.buttons+=``),"object"==typeof t&&(s.buttons+=``,i=Array.isArray(s.actions)?t.text:e),"string"==typeof t&&(s.buttons+=``,i=t),"string"==typeof i&&(i=i[0].toLowerCase()+i.substr(1).replace(/\s+/g,"")),n[i]=function(t){return s.on("action.buttons",e=>{e.detail.action[0].toLowerCase()+e.detail.action.substr(1).replace(/\s+/g,"")==i&&t(e)}),n}})),Array("html","body","buttons").forEach(e=>{s[e]=String(s[e]??"").trim()}),""===s.body&&""===s.buttons||(s.html=` +
    ${s.body||""}
    +
    ${s.buttons||""}
    + `),getComputedStyle(query(r.box).get(0)));var h=parseFloat(o.width),d=parseFloat(o.height);let u=0,c=(0h&&(s.width=h-10),s.height>d-u&&(s.height=d-10-u),s.originalWidth=s.width,s.originalHeight=s.height,parseInt(s.width)<0&&(s.width=h+s.width),parseInt(s.width)<10&&(s.width=10),parseInt(s.height)<0&&(s.height=d+s.height-u),parseInt(s.height)<10&&(s.height=10),s.originalHeight<0&&(s.height=d+s.originalHeight-u),s.originalWidth<0&&(s.width=h+2*s.originalWidth),query(r.box).find(r.after));return s.tmp||(s.tmp={zIndex:c.css("z-index"),overflow:o.overflow}),""===s.html&&""===s.body&&""===s.buttons?i():(s.msgIndex=query(r.box).find(".w2ui-message").length,0===s.msgIndex&&"function"==typeof this.lock&&(query(r.box).css("overflow","hidden"),r.owner?r.owner.lock(r.param):this.lock(r.box)),query(r.box).find(".w2ui-message").css("z-index",1390),c.css("z-index",1501),d=` +
    + + ${s.html} + +
    `,0{!0===(l=s.trigger("open",{target:this.name,box:s.box,self:s})).isCancelled?(query(r.box).find(`#w2ui-message-${r.owner?.name}-`+s.msgIndex).remove(),0===s.msgIndex&&(c.css("z-index",s.tmp.zIndex),query(r.box).css("overflow",s.tmp.overflow))):query(s.box).css({transition:"0.3s",transform:"translateY(0px)"})},0),t=setTimeout(()=>{query(r.box).find(`#w2ui-message-${r.owner?.name}-`+s.msgIndex).removeClass("animating").css({transition:"0s"}),l.finish()},300)),s.action=(e,t)=>{let i=s.actions[e];i instanceof Object&&i.onClick&&(i=i.onClick);e=s.trigger("action",{target:this.name,action:e,self:s,originalEvent:t,value:s.input?s.input.value:null});!0!==e.isCancelled&&("function"==typeof i&&i(e),e.finish())},s.close=()=>{!0!==(l=s.trigger("close",{target:"self",box:s.box,self:s})).isCancelled&&(clearTimeout(t),query(s.box).hasClass("animating")?(clearTimeout(e),a(s)):(query(s.box).addClass("w2ui-closing animating").css({transition:"0.15s",transform:"translateY(-"+s.height+"px)"}),0!==s.msgIndex&&query(r.box).find(`#w2ui-message-${r.owner?.name}-`+(s.msgIndex-1)).css("z-index",1499),e=setTimeout(()=>{a(s)},150)))},s.setFocus=e=>{var t=query(r.box).find(".w2ui-message").length-1;let s=query(r.box).find(`#w2ui-message-${r.owner?.name}-`+t),l="input, button, select, textarea, [contentEditable], .w2ui-input";(null!=e?isNaN(e)?s.find(l).filter(e).get(0):s.find(l).get(e):s.find("[name=hidden-first]").get(0))?.focus(),query(r.box).find(".w2ui-message").find(l+",[name=hidden-first],[name=hidden-last]").off(".keep-focus"),query(s).find(l+",[name=hidden-first],[name=hidden-last]").on("blur.keep-focus",function(e){setTimeout(()=>{var e=document.activeElement,t=0{if("object"==typeof i&&(i=(s=i).text),(s=s||{}).where=s.where??document.body,s.timeout=s.timeout??15e3,"function"==typeof this.tmp.notify_resolve&&(this.tmp.notify_resolve(),query(this.tmp.notify_where).find("#w2ui-notify").remove()),this.tmp.notify_resolve=t,this.tmp.notify_where=s.where,clearTimeout(this.tmp.notify_timer),i){if("object"==typeof s.actions){let t={};Object.keys(s.actions).forEach(e=>{t[e]=`${e}`}),i=this.execTemplate(i,t)}var e=` +
    +
    + ${i} + +
    +
    `;query(s.where).append(e),query(s.where).find("#w2ui-notify").find(".w2ui-notify-close").on("click",e=>{query(s.where).find("#w2ui-notify").remove(),t()}),s.actions&&query(s.where).find("#w2ui-notify .w2ui-notify-link").on("click",e=>{e=query(e.target).attr("value");s.actions[e](),query(s.where).find("#w2ui-notify").remove(),t()}),0{query(s.where).find("#w2ui-notify").remove(),t()},s.timeout))}})}confirm(e,t){w2utils.normButtons(t="string"==typeof t?{text:t}:t,{yes:"Yes",no:"No"});e=w2utils.message(e,t);return e&&e.action(e=>{e.detail.self.close()}),e}normButtons(i,s){i.actions=i.actions??{};var e=Object.keys(s);return e.forEach(t=>{var e=i["btn_"+t];e&&(s[t]={text:w2utils.lang(e.text??""),class:e.class??"",style:e.style??"",attrs:e.attrs??""},delete i["btn_"+t]),Array("text","class","style","attrs").forEach(e=>{i[t+"_"+e]&&("string"==typeof s[t]&&(s[t]={text:s[t]}),s[t][e]=i[t+"_"+e],delete i[t+"_"+e])})}),e.includes("yes")&&e.includes("no")&&(w2utils.settings.macButtonOrder?w2utils.extend(i.actions,{no:s.no,yes:s.yes}):w2utils.extend(i.actions,{yes:s.yes,no:s.no})),e.includes("ok")&&e.includes("cancel")&&(w2utils.settings.macButtonOrder?w2utils.extend(i.actions,{cancel:s.cancel,ok:s.ok}):w2utils.extend(i.actions,{ok:s.ok,cancel:s.cancel})),i}getSize(e,t){let i=0;if(0<(e=query(e)).length){e=e[0];var s=getComputedStyle(e);switch(t){case"width":i=parseFloat(s.width),"auto"===s.width&&(i=0);break;case"height":i=parseFloat(s.height),"auto"===s.height&&(i=0);break;default:i=parseFloat(s[t]??0)||0}}return i}getStrWidth(e,t){query("body").append(` +
    + ${this.encodeTags(e)} +
    `);t=query("#_tmp_width")[0].clientWidth;return query("#_tmp_width").remove(),t}execTemplate(e,i){return"string"==typeof e&&i&&"object"==typeof i?e.replace(/\${([^}]+)?}/g,function(e,t){return i[t]||t}):e}marker(e,s,l={onlyFirst:!1,wholeWord:!1}){Array.isArray(s)||(s=null!=s&&""!==s?[s]:[]);let r=l.wholeWord;query(e).each(t=>{for(var e=t,i=/\((.|\n|\r)*)\<\/span\>/gi;-1!==e.innerHTML.indexOf('{e=(e="string"!=typeof e?String(e):e).replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&").replace(/&/g,"&").replace(//g,"<");e=new RegExp((r?"\\b":"")+e+(r?"\\b":"")+"(?!([^<]+)?>)","i"+(l.onlyFirst?"":"g"));t.innerHTML=t.innerHTML.replace(e,e=>''+e+"")})})}lang(e,t){if(!e||null==this.settings.phrases||"string"!=typeof e||"<=>=".includes(e))return this.execTemplate(e,t);let i=this.settings.phrases[e];return null==i?(i=e,this.settings.warnNoPhrase&&(this.settings.missing||(this.settings.missing={}),this.settings.missing[e]="---",this.settings.phrases[e]="---",console.log(`Missing translation for "%c${e}%c", see %c w2utils.settings.phrases %c with value "---"`,"color: orange","","color: #999",""))):"---"!==i||this.settings.warnNoPhrase||(i=e),"---"===i&&(i=`---`),this.execTemplate(i,t)}locale(l,i,r){return new Promise((s,t)=>{if(Array.isArray(l)){this.settings.phrases={};let i=[],t={};l.forEach((e,t)=>{5===e.length&&(e="locale/"+e.toLowerCase()+".json",l[t]=e),i.push(this.locale(e,!0,!1))}),void Promise.allSettled(i).then(e=>{e.forEach(e=>{e.value&&(t[e.value.file]=e.value.data)}),l.forEach(e=>{this.settings=this.extend({},this.settings,t[e])}),s()})}else(l=l||"en-us")instanceof Object?this.settings=this.extend({},this.settings,w2locale,l):(5===l.length&&(l="locale/"+l.toLowerCase()+".json"),fetch(l,{method:"GET"}).then(e=>e.json()).then(e=>{!0!==r&&(this.settings=i?this.extend({},this.settings,e):this.extend({},this.settings,w2locale,{phrases:{}},e)),s({file:l,data:e})}).catch(e=>{console.log("ERROR: Cannot load locale "+l),t(e)}))})}scrollBarSize(){return this.tmp.scrollBarSize||(query("body").append(` +
    +
    1
    +
    + `),this.tmp.scrollBarSize=100-query("#_scrollbar_width > div")[0].clientWidth,query("#_scrollbar_width").remove()),this.tmp.scrollBarSize}checkName(e){return null==e?(console.log('ERROR: Property "name" is required but not supplied.'),!1):null!=w2ui[e]?(console.log(`ERROR: Object named "${e}" is already registered as w2ui.${e}.`),!1):!!this.isAlphaNumeric(e)||(console.log('ERROR: Property "name" has to be alpha-numeric (a-z, 0-9, dash and underscore).'),!1)}checkUniqueId(t,i,s,l){Array.isArray(i)||(i=[i]);let r=!0;return i.forEach(e=>{e.id===t&&(console.log(`ERROR: The item id="${t}" is not unique within the ${s} "${l}".`,i),r=!1)}),r}encodeParams(t,i=""){let s="";return Object.keys(t).forEach(e=>{""!=s&&(s+="&"),"object"==typeof t[e]?s+=this.encodeParams(t[e],i+e+(i?"]":"")+"["):s+=""+i+e+(i?"]":"")+"="+t[e]}),s}parseRoute(e){let a=[];e=e.replace(/\/\(/g,"(?:/").replace(/\+/g,"__plus__").replace(/(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?/g,(e,t,i,s,l,r)=>(a.push({name:s,optional:!!r}),t=t||"",(r?"":t)+"(?:"+(r?t:"")+(i||"")+(l||(i?"([^/.]+?)":"([^/]+?)"))+")"+(r||""))).replace(/([\/.])/g,"\\$1").replace(/__plus__/g,"(.+)").replace(/\*/g,"(.*)");return{path:new RegExp("^"+e+"$","i"),keys:a}}getCursorPosition(e){if(null==e)return null;let t=0;var i,s=e.ownerDocument||e.document,l=s.defaultView||s.parentWindow;let r;return["INPUT","TEXTAREA"].includes(e.tagName)?t=e.selectionStart:l.getSelection?0<(r=l.getSelection()).rangeCount&&((i=(l=r.getRangeAt(0)).cloneRange()).selectNodeContents(e),i.setEnd(l.endContainer,l.endOffset),t=i.toString().length):(r=s.selection)&&"Control"!==r.type&&(l=r.createRange(),(i=s.body.createTextRange()).moveToElementText(e),i.setEndPoint("EndToEnd",l),t=i.text.length),t}setCursorPosition(s,l,t){if(null!=s){var r=document.createRange();let i,e=window.getSelection();if(["INPUT","TEXTAREA"].includes(s.tagName))s.setSelectionRange(l,t??l);else{for(let t=0;t").replace(/&/g,"&").replace(/"/g,'"').replace(/ /g," "):e).length){(i=(i=s.childNodes[t]).childNodes&&0i.length&&(l=i.length),r.setStart(i,l),t?r.setEnd(i,t):r.collapse(!0),e.removeAllRanges(),e.addRange(r))}}}parseColor(e){if("string"!=typeof e)return null;let t={};if(3===(e="#"===(e=e.trim().toUpperCase())[0]?e.substr(1):e).length)t={r:parseInt(e[0]+e[0],16),g:parseInt(e[1]+e[1],16),b:parseInt(e[2]+e[2],16),a:1};else if(6===e.length)t={r:parseInt(e.substr(0,2),16),g:parseInt(e.substr(2,2),16),b:parseInt(e.substr(4,2),16),a:1};else if(8===e.length)t={r:parseInt(e.substr(0,2),16),g:parseInt(e.substr(2,2),16),b:parseInt(e.substr(4,2),16),a:Math.round(parseInt(e.substr(6,2),16)/255*100)/100};else if(4{s[t]=this.clone(e,i)}):this.isPlainObject(e)?(s={},Object.assign(s,e),i.exclude&&i.exclude.forEach(e=>{delete s[e]}),Object.keys(s).forEach(e=>{s[e]=this.clone(s[e],i),void 0===s[e]&&delete s[e]})):e instanceof Function&&!i.functions||e instanceof Node&&!i.elements||e instanceof Event&&!i.events||(s=e),s}extend(i,s){if(Array.isArray(i)){if(!Array.isArray(s))throw new Error("Arrays can be extended with arrays only");i.splice(0,i.length),s.forEach(e=>{i.push(this.clone(e))})}else{if(i instanceof Node||i instanceof Event)throw new Error("HTML elmenents and events cannot be extended");if(i&&"object"==typeof i&&null!=s){if("object"!=typeof s)throw new Error("Object can be extended with other objects only.");Object.keys(s).forEach(e=>{var t;null!=i[e]&&"object"==typeof i[e]&&null!=s[e]&&"object"==typeof s[e]?(t=this.clone(s[e]),i[e]instanceof Node||i[e]instanceof Event?i[e]=t:(Array.isArray(i[e])&&this.isPlainObject(t)&&(i[e]={}),this.extend(i[e],t))):i[e]=this.clone(s[e])})}else if(null!=s)throw new Error("Object is not extendable, only {} or [] can be extended.")}if(2{"string"==typeof e||"number"==typeof e?i[t]={id:e,text:String(e)}:null!=e?(null!=e.caption&&null==e.text&&(e.text=e.caption),null!=e.text&&null==e.id&&(e.id=e.text),null==e.text&&null!=e.id&&(e.text=e.id)):i[t]={id:null,text:"null"}}),i):"function"==typeof i?(e=i.call(this,i,e),w2utils.normMenu.call(this,e)):"object"==typeof i?Object.keys(i).map(e=>({id:e,text:i[e]})):void 0}prepareParams(i,e,t){t=t??w2utils.settings.dataType;let s=e.body;switch(t){case"HTTPJSON":s={request:s},["PUT","DELETE"].includes(e.method)&&(e.method="POST"),l();break;case"HTTP":["PUT","DELETE"].includes(e.method)&&(e.method="POST"),l();break;case"RESTFULL":["PUT","DELETE"].includes(e.method)?e.headers["Content-Type"]="application/json":l();break;case"JSON":"GET"==e.method?(s={request:s},l()):(e.headers["Content-Type"]="application/json",e.method="POST")}return e.body="string"==typeof e.body?e.body:JSON.stringify(e.body),e;function l(){Object.keys(s).forEach(e=>{let t=s[e];"object"==typeof t&&(t=JSON.stringify(t)),i.searchParams.append(e,t)}),delete e.body}}bindEvents(e,r){0!=e.length&&(e?.[0]instanceof Node&&(e=Array.isArray(e)?e:e.get()),query(e).each(s=>{let l=query(s).data();Object.keys(l).forEach(i=>{if(-1!=["click","dblclick","mouseenter","mouseleave","mouseover","mouseout","mousedown","mousemove","mouseup","contextmenu","focus","focusin","focusout","blur","input","change","keydown","keyup","keypress"].indexOf(String(i).toLowerCase())){let e=l[i],t=(e="string"==typeof e?e.split("|").map(e=>{"null"===(e="undefined"===(e="false"===(e="true"===e?!0:e)?!1:e)?void 0:e)&&(e=null);var t=["'",'"',"`"];return e="string"==typeof(e=parseFloat(e)==e?parseFloat(e):e)&&t.includes(e[0])&&t.includes(e[e.length-1])?e.substring(1,e.length-1):e}):e)[0];e=e.slice(1),query(s).off(i+".w2utils-bind").on(i+".w2utils-bind",function(i){switch(t){case"alert":alert(e[0]);break;case"stop":i.stopPropagation();break;case"prevent":i.preventDefault();break;case"stopPrevent":return i.stopPropagation(),i.preventDefault(),!1;default:if(null==r[t])throw new Error(`Cannot dispatch event as the method "${t}" does not exist.`);r[t].apply(r,e.map((e,t)=>{switch(String(e).toLowerCase()){case"event":return i;case"this":return this;default:return e}}))}})}})}))}debounce(t,i=250){let s;return(...e)=>{clearTimeout(s),s=setTimeout(()=>{t(...e)},i)}}}var w2utils=new Utils;class Dialog extends w2base{constructor(){super(),this.defaults={title:"",text:"",body:"",buttons:"",width:450,height:250,focus:null,actions:null,style:"",speed:.3,modal:!1,maximized:!1,keyboard:!0,showClose:!0,showMax:!1,transition:null,openMaximized:!1,moved:!1},this.name="popup",this.status="closed",this.onOpen=null,this.onClose=null,this.onMax=null,this.onMin=null,this.onToggle=null,this.onKeydown=null,this.onAction=null,this.onMove=null,this.tmp={},this.handleResize=e=>{this.options.moved||this.center(void 0,void 0,!0)}}open(s){let l=this;"closing"!=this.status&&!query("#w2ui-popup").hasClass("animating")||this.close(!0);var e=this.options;null!=(s=["string","number"].includes(typeof s)?w2utils.extend({title:"Notification",body:`
    ${s}
    `,actions:{Ok(){l.close()}},cancelAction:"ok"},arguments[1]??{}):s).text&&(s.body=`
    ${s.text}
    `),s=Object.assign({},this.defaults,e,{title:"",body:""},s,{maximized:!1}),this.options=s,0===query("#w2ui-popup").length&&(this.off("*"),Object.keys(this).forEach(e=>{e.startsWith("on")&&"on"!=e&&(this[e]=null)})),Object.keys(s).forEach(e=>{e.startsWith("on")&&"on"!=e&&s[e]&&(this[e]=s[e])}),s.width=parseInt(s.width),s.height=parseInt(s.height);let r,t,i;var{top:a,left:n}=this.center();let o={self:this,action(e){return l.on("action.prom",e),o},close(e){return l.on("close.prom",e),o},then(e){return l.on("open:after.prom",e),o}};if(null==s.actions||s.buttons||(s.buttons="",Object.keys(s.actions).forEach(e=>{var t=s.actions[e];let i=e;"function"==typeof t&&(s.buttons+=``),"object"==typeof t&&(s.buttons+=``,i=Array.isArray(s.actions)?t.text:e),"string"==typeof t&&(s.buttons+=``,i=t),"string"==typeof i&&(i=i[0].toLowerCase()+i.substr(1).replace(/\s+/g,"")),o[i]=function(t){return l.on("action.buttons",e=>{e.detail.action[0].toLowerCase()+e.detail.action.substr(1).replace(/\s+/g,"")==i&&t(e)}),o}})),0===query("#w2ui-popup").length){if(!0===(r=this.trigger("open",{target:"popup",present:!1})).isCancelled)return;this.status="opening",w2utils.lock(document.body,{opacity:.3,onClick:s.modal?null:()=>{this.close()}});let e="";s.showClose&&(e+=`
    + +
    `),s.showMax&&(e+=`
    + +
    `);n=` + left: ${n}px; + top: ${a}px; + width: ${parseInt(s.width)}px; + height: ${parseInt(s.height)}px; + transition: ${s.speed}s + `;t=`
    `,query("body").append(t),query("#w2ui-popup")[0]._w2popup={self:this,created:new Promise(e=>{this._promCreated=e}),opened:new Promise(e=>{this._promOpened=e}),closing:new Promise(e=>{this._promClosing=e}),closed:new Promise(e=>{this._promClosed=e})},n=`${s.title?"":"top: 0px !important;"} `+(s.buttons?"":"bottom: 0px !important;"),t=` + +
    ${e}
    +
    +
    +
    +
    +
    +
    + + `,query("#w2ui-popup").html(t),s.title&&query("#w2ui-popup .w2ui-popup-title").append(w2utils.lang(s.title)),s.buttons&&query("#w2ui-popup .w2ui-popup-buttons").append(s.buttons),s.body&&query("#w2ui-popup .w2ui-popup-body").append(s.body),setTimeout(()=>{query("#w2ui-popup").css("transition",s.speed+"s").removeClass("w2ui-anim-open"),w2utils.bindEvents("#w2ui-popup .w2ui-eaction",this),query("#w2ui-popup").find(".w2ui-popup-body").show(),this._promCreated()},1),clearTimeout(this._timer),this._timer=setTimeout(()=>{this.status="open",l.setFocus(s.focus),r.finish(),this._promOpened(),query("#w2ui-popup").removeClass("animating")},1e3*s.speed)}else{if(!0===(r=this.trigger("open",{target:"popup",present:!0})).isCancelled)return;this.status="opening",null!=e&&(e.maximized||e.width==s.width&&e.height==s.height||this.resize(s.width,s.height),s.prevSize=s.width+"px:"+s.height+"px",s.maximized=e.maximized);a=query("#w2ui-popup .w2ui-box").get(0).cloneNode(!0);query(a).removeClass("w2ui-box").addClass("w2ui-box-temp").find(".w2ui-popup-body").empty().append(s.body),query("#w2ui-popup .w2ui-box").after(a),s.buttons?(query("#w2ui-popup .w2ui-popup-buttons").show().html("").append(s.buttons),query("#w2ui-popup .w2ui-popup-body").removeClass("w2ui-popup-no-buttons"),query("#w2ui-popup .w2ui-box, #w2ui-popup .w2ui-box-temp").css("bottom","")):(query("#w2ui-popup .w2ui-popup-buttons").hide().html(""),query("#w2ui-popup .w2ui-popup-body").addClass("w2ui-popup-no-buttons"),query("#w2ui-popup .w2ui-box, #w2ui-popup .w2ui-box-temp").css("bottom","0px")),s.title?(query("#w2ui-popup .w2ui-popup-title").show().html((s.showClose?`
    + +
    `:"")+(s.showMax?`
    + +
    `:"")).append(s.title),query("#w2ui-popup .w2ui-popup-body").removeClass("w2ui-popup-no-title"),query("#w2ui-popup .w2ui-box, #w2ui-popup .w2ui-box-temp").css("top","")):(query("#w2ui-popup .w2ui-popup-title").hide().html(""),query("#w2ui-popup .w2ui-popup-body").addClass("w2ui-popup-no-title"),query("#w2ui-popup .w2ui-box, #w2ui-popup .w2ui-box-temp").css("top","0px"));let t=query("#w2ui-popup .w2ui-box")[0],i=query("#w2ui-popup .w2ui-box-temp")[0];query("#w2ui-popup").addClass("animating"),w2utils.transition(t,i,s.transition,()=>{query(t).remove(),query(i).removeClass("w2ui-box-temp").addClass("w2ui-box");var e=query(i).find(".w2ui-popup-body");1==e.length&&(e[0].style.cssText=s.style,e.show()),l.setFocus(s.focus),query("#w2ui-popup").removeClass("animating")}),this.status="open",r.finish(),w2utils.bindEvents("#w2ui-popup .w2ui-eaction",this),query("#w2ui-popup").find(".w2ui-popup-body").show()}return s.openMaximized&&this.max(),s._last_focus=document.activeElement,s.keyboard&&query(document.body).on("keydown",e=>{this.keydown(e)}),query(window).on("resize",this.handleResize),i={resizing:!1,mvMove:function(e){1==i.resizing&&(e=e||window.event,i.div_x=e.screenX-i.x,i.div_y=e.screenY-i.y,!0!==(e=l.trigger("move",{target:"popup",div_x:i.div_x,div_y:i.div_y,originalEvent:e})).isCancelled)&&(query("#w2ui-popup").css({transition:"none",transform:"translate3d("+i.div_x+"px, "+i.div_y+"px, 0px)"}),l.options.moved=!0,e.finish())},mvStop:function(e){1!=i.resizing||(e=e||window.event,l.status="open",i.div_x=e.screenX-i.x,i.div_y=e.screenY-i.y,query("#w2ui-popup").css({left:i.pos_x+i.div_x+"px",top:i.pos_y+i.div_y+"px"}).css({transition:"none",transform:"translate3d(0px, 0px, 0px)"}),i.resizing=!1,query(document.body).off(".w2ui-popup"),i.isLocked)||l.unlock()}},query("#w2ui-popup .w2ui-popup-title").on("mousedown",function(e){var t;l.options.maximized||(e=(e=e)||window.event,l.status="moving",t=query("#w2ui-popup").get(0).getBoundingClientRect(),Object.assign(i,{resizing:!0,isLocked:1==query("#w2ui-popup > .w2ui-lock").length,x:e.screenX,y:e.screenY,pos_x:t.x,pos_y:t.y}),i.isLocked||l.lock({opacity:0}),query(document.body).on("mousemove.w2ui-popup",i.mvMove).on("mouseup.w2ui-popup",i.mvStop),e.stopPropagation?e.stopPropagation():e.cancelBubble=!0,e.preventDefault&&e.preventDefault())}),o}load(s){return new Promise((i,e)=>{if(null==(s="string"==typeof s?{url:s}:s).url)console.log("ERROR: The url is not defined."),e("The url is not defined");else{this.status="loading";let[e,t]=String(s.url).split("#");e&&fetch(e).then(e=>e.text()).then(e=>{i(this.template(e,t,s))})}})}template(t,e,i={}){let s;try{s=query(t)}catch(e){s=query.html(t)}return e&&(s=s.filter("#"+e)),Object.assign(i,{width:parseInt(query(s).css("width")),height:parseInt(query(s).css("height")),title:query(s).find("[rel=title]").html(),body:query(s).find("[rel=body]").html(),buttons:query(s).find("[rel=buttons]").html(),style:query(s).find("[rel=body]").get(0).style.cssText}),this.open(i)}action(e,t){let i=this.options.actions[e];i instanceof Object&&i.onClick&&(i=i.onClick);e=this.trigger("action",{action:e,target:"popup",self:this,originalEvent:t,value:this.input?this.input.value:null});!0!==e.isCancelled&&("function"==typeof i&&i.call(this,t),e.finish())}keydown(e){var t;this.options&&!this.options.keyboard||!0!==(t=this.trigger("keydown",{target:"popup",originalEvent:e})).isCancelled&&(27===e.keyCode&&(e.preventDefault(),0==query("#w2ui-popup .w2ui-message").length)&&(this.options.cancelAction?this.action(this.options.cancelAction):this.close()),t.finish())}close(e){let t=this.trigger("close",{target:"popup"});var i;!0!==t.isCancelled&&(i=()=>{query("#w2ui-popup").remove(),this.options._last_focus&&0{e.finish()},1e3*this.options.speed+50))}max(){if(!0!==this.options.maximized){let e=this.trigger("max",{target:"popup"});var t;!0!==e.isCancelled&&(this.status="resizing",t=query("#w2ui-popup").get(0).getBoundingClientRect(),this.options.prevSize=t.width+":"+t.height,this.resize(1e4,1e4,()=>{this.status="open",this.options.maximized=!0,e.finish()}))}}min(){if(!0===this.options.maximized){var t=this.options.prevSize.split(":");let e=this.trigger("min",{target:"popup"});!0!==e.isCancelled&&(this.status="resizing",this.options.maximized=!1,this.resize(parseInt(t[0]),parseInt(t[1]),()=>{this.status="open",this.options.prevSize=null,e.finish()}))}}clear(){query("#w2ui-popup .w2ui-popup-title").html(""),query("#w2ui-popup .w2ui-popup-body").html(""),query("#w2ui-popup .w2ui-popup-buttons").html("")}reset(){this.open(this.defaults)}message(e){return w2utils.message({owner:this,box:query("#w2ui-popup").get(0),after:".w2ui-popup-title"},e)}confirm(e){return w2utils.confirm({owner:this,box:query("#w2ui-popup"),after:".w2ui-popup-title"},e)}setFocus(e){let s=query("#w2ui-popup"),l="input, button, select, textarea, [contentEditable], .w2ui-input";null!=e?(isNaN(e)?s.find(l).filter(e).get(0):s.find(l).get(e))?.focus():(e=s.find("[name=hidden-first]").get(0))&&e.focus(),query(s).find(l+",[name=hidden-first],[name=hidden-last]").off(".keep-focus").on("blur.keep-focus",function(e){setTimeout(()=>{var e=document.activeElement,t=0{s.resizeMessages()},10);setTimeout(()=>{clearInterval(n),s.resizeMessages(),"function"==typeof i&&i()},1e3*this.options.speed+50)}resizeMessages(){query("#w2ui-popup .w2ui-message").each(e=>{var t=e._msg_options,i=query("#w2ui-popup"),s=(parseInt(t.width)<10&&(t.width=10),parseInt(t.height)<10&&(t.height=10),i[0].getBoundingClientRect()),i=parseInt(i.find(".w2ui-popup-title")[0].clientHeight),l=parseInt(s.width),s=parseInt(s.height);t.width=t.originalWidth,t.width>l-10&&(t.width=l-10),t.height=t.originalHeight,t.height>s-i-5&&(t.height=s-i-5),t.originalHeight<0&&(t.height=s+t.originalHeight-i),t.originalWidth<0&&(t.width=l+2*t.originalWidth),query(e).css({left:(l-t.width)/2+"px",width:t.width+"px",height:t.height+"px"})})}}function w2alert(e,t,i){let s;t={title:w2utils.lang(t??"Notification"),body:`
    ${e}
    `,showClose:!1,actions:["Ok"],cancelAction:"ok"};return(s=0{"function"==typeof e.detail.self?.close&&e.detail.self.close(),"function"==typeof i&&i()}),s}function w2confirm(e,t,i){let s,l=e;return(l=["string","number"].includes(typeof l)?{msg:l}:l).msg&&(l.body=`
    ${l.msg}
    `,delete l.msg),w2utils.extend(l,{title:w2utils.lang(t??"Confirmation"),showClose:!1,modal:!0,cancelAction:"no"}),w2utils.normButtons(l,{yes:"Yes",no:"No"}),(s=0{"function"==typeof e.detail.self?.close&&e.detail.self.close(),"function"==typeof i&&i(e.detail.action)}),s}function w2prompt(e,t,i){let s,l=e;return(l=["string","number"].includes(typeof l)?{label:l}:l).label&&(l.focus=0,l.body=l.textarea?`
    +
    ${l.label}
    + +
    `:`
    + + +
    `),w2utils.extend(l,{title:w2utils.lang(t??"Notification"),showClose:!1,modal:!0,cancelAction:"cancel"}),w2utils.normButtons(l,{ok:"Ok",cancel:"Cancel"}),(s=0{e=e.detail.box||query("#w2ui-popup .w2ui-popup-body").get(0);w2utils.bindEvents(query(e).find("#w2prompt"),{keydown(e){27==e.keyCode&&e.stopPropagation()},change(e){var t=s.self.trigger("change",{target:"prompt",originalEvent:e});!0!==t.isCancelled&&(13==e.keyCode&&e.ctrlKey&&s.self.action("Ok",e),27==e.keyCode&&s.self.action("Cancel",e),t.finish())}}),query(e).find(".w2ui-eaction").trigger("keyup")}).on("action:after.prompt",e=>{"function"==typeof e.detail.self?.close&&e.detail.self.close(),"function"==typeof i&&i(e.detail.action)}),s}let w2popup=new Dialog;class Tooltip{static active={};constructor(){this.defaults={name:null,html:"",style:"",class:"",position:"top|bottom",align:"",anchor:null,anchorClass:"",anchorStyle:"",autoShow:!1,autoShowOn:null,autoHideOn:null,arrowSize:8,margin:0,margin:1,screenMargin:2,autoResize:!0,offsetX:0,offsetY:0,maxWidth:null,maxHeight:null,watchScroll:null,watchResize:null,hideOn:null,onThen:null,onShow:null,onHide:null,onUpdate:null,onMove:null}}static observeRemove=new MutationObserver(e=>{let t=0;Object.keys(Tooltip.active).forEach(e=>{e=Tooltip.active[e];e.displayed&&(e.anchor&&e.anchor.isConnected?t++:e.hide())}),0===t&&Tooltip.observeRemove.disconnect()});trigger(e,t){var i;if(2==arguments.length&&(i=e,(e=t).type=i),e.overlay)return e.overlay.trigger(e);console.log("ERROR: cannot find overlay where to trigger events")}get(e){return 0==arguments.length?Object.keys(Tooltip.active):!0===e?Tooltip.active:Tooltip.active[e.replace(/[\s\.#]/g,"_")]}attach(t,s){let l,r,a=this;if(0!=arguments.length){1==arguments.length&&t.anchor?t=(l=t).anchor:2===arguments.length&&"string"==typeof s?s=(l={anchor:t,html:s}).html:2===arguments.length&&null!=s&&"object"==typeof s&&(s=(l=s).html),l=w2utils.extend({},this.defaults,l||{}),!(s=!s&&l.text?l.text:s)&&l.html&&(s=l.html),delete l.anchor;let e=l.name||t.id;t!=document&&t!=document.body||(t=document.body,e="context-menu"),e||(e="noname-"+Object.keys(Tooltip.active).length,console.log("NOTICE: name property is not defined for tooltip, could lead to too many instances")),e=e.replace(/[\s\.#]/g,"_"),Tooltip.active[e]?((r=Tooltip.active[e]).prevOptions=r.options,r.options=l,r.anchor=t,r.prevOptions.html==r.options.html&&r.prevOptions.class==r.options.class&&r.prevOptions.style==r.options.style||(r.needsUpdate=!0),l=r.options):(r=new w2base,Object.assign(r,{id:"w2overlay-"+e,name:e,options:l,anchor:t,displayed:!1,tmp:{observeResize:new ResizeObserver(()=>{this.resize(r.name)})},hide(){a.hide(e)}}),Tooltip.active[e]=r),Object.keys(r.options).forEach(e=>{var t=r.options[e];e.startsWith("on")&&"function"==typeof t&&(r[e]=t,delete r.options[e])}),!0===l.autoShow&&(l.autoShowOn=l.autoShowOn??"mouseenter",l.autoHideOn=l.autoHideOn??"mouseleave",l.autoShow=!1),l.autoShowOn&&(s="autoShow-"+r.name,query(t).off("."+s).on(l.autoShowOn+"."+s,e=>{a.show(r.name),e.stopPropagation()}),delete l.autoShowOn),l.autoHideOn&&(s="autoHide-"+r.name,query(t).off("."+s).on(l.autoHideOn+"."+s,e=>{a.hide(r.name),e.stopPropagation()}),delete l.autoHideOn),r.off(".attach");let i={overlay:r,then:t=>(r.on("show:after.attach",e=>{t(e)}),i),show:t=>(r.on("show.attach",e=>{t(e)}),i),hide:t=>(r.on("hide.attach",e=>{t(e)}),i),update:t=>(r.on("update.attach",e=>{t(e)}),i),move:t=>(r.on("move.attach",e=>{t(e)}),i)};return i}}update(e,t){var i=Tooltip.active[e];i?(i.needsUpdate=!0,i.options.html=t,this.show(e)):console.log(`Tooltip "${e}" is not displayed. Cannot update it.`)}show(i){if(i instanceof HTMLElement||i instanceof Object){let e=i,t=(i instanceof HTMLElement&&((e=arguments[1]||{}).anchor=i),this.attach(e));return query(t.overlay.anchor).off(".autoShow-"+t.overlay.name).off(".autoHide-"+t.overlay.name),setTimeout(()=>{this.show(t.overlay.name),this.initControls&&this.initControls(t.overlay)},1),t}let t,r=this,a=Tooltip.active[i.replace(/[\s\.#]/g,"_")];if(a){let l=a.options;if(!a||a.displayed&&!a.needsUpdate)this.resize(a?.name);else{var s=l.position.split("|"),s=["top","bottom"].includes(s[0]);let e="both"==l.align&&s?"":"white-space: nowrap;";if(l.maxWidth&&w2utils.getStrWidth(l.html,"")>l.maxWidth&&(e="width: "+l.maxWidth+"px; white-space: inherit; overflow: auto;"),e+=" max-height: "+(l.maxHeight||window.innerHeight-40)+"px;",""!==l.html&&null!=l.html){if(a.box){if(!0===(t=this.trigger("update",{target:i,overlay:a})).isCancelled)return void(a.prevOptions&&(a.options=a.prevOptions,delete a.prevOptions));query(a.box).find(".w2ui-overlay-body").attr("style",(l.style||"")+"; "+e).removeClass().addClass("w2ui-overlay-body "+l.class).html(l.html)}else{if(!0===(t=this.trigger("show",{target:i,overlay:a})).isCancelled)return;query("body").append(``),a.box=query("#"+w2utils.escapeId(a.id))[0],a.displayed=!0;s=query(a.anchor).data("tooltipName")??[];s.push(i),query(a.anchor).data("tooltipName",s),w2utils.bindEvents(a.box,{}),a.tmp.originalCSS="",0{r.hide(a.name)},i=query(a.anchor),s="tooltip-"+a.name;query("body").off("."+s),l.hideOn.includes("doc-click")&&(["INPUT","TEXTAREA"].includes(a.anchor.tagName)&&i.off(`.${s}-doc`).on(`click.${s}-doc`,e=>{e.stopPropagation()}),query("body").on("click."+s,t));l.hideOn.includes("focus-change")&&query("body").on("focusin."+s,e=>{document.activeElement!=a.anchor&&r.hide(a.name)});["INPUT","TEXTAREA"].includes(a.anchor.tagName)&&(i.off("."+s),l.hideOn.forEach(e=>{-1==["doc-click","focus-change"].indexOf(e)&&i.on(e+"."+s,{once:!0},t)}))}{var n=document.body;let e="tooltip-"+a.name,t=n;"BODY"==n.tagName&&(t=n.ownerDocument);query(t).off("."+e).on("scroll."+e,e=>{Object.assign(a.tmp,{scrollLeft:n.scrollLeft,scrollTop:n.scrollTop}),r.resize(a.name)})}return query(a.box).show(),a.tmp.observeResize.observe(a.box),Tooltip.observeRemove.observe(document.body,{subtree:!0,childList:!0}),query(a.box).css("opacity",1).find(".w2ui-overlay-body").html(l.html),setTimeout(()=>{query(a.box).css({"pointer-events":"auto"}).data("ready","yes")},100),delete a.needsUpdate,a.box.overlay=a,t&&t.finish(),{overlay:a}}r.hide(i)}}}hide(e){let i;if(0==arguments.length)Object.keys(Tooltip.active).forEach(e=>{this.hide(e)});else if(e instanceof HTMLElement)(query(e).data("tooltipName")??[]).forEach(e=>{this.hide(e)});else if("string"==typeof e&&(e=e.replace(/[\s\.#]/g,"_"),i=Tooltip.active[e]),i&&i.box){delete Tooltip.active[e];e=this.trigger("hide",{target:e,overlay:i});if(!0!==e.isCancelled){var s="tooltip-"+i.name;i.tmp.observeResize?.disconnect(),i.options.watchScroll&&query(i.options.watchScroll).off(".w2scroll-"+i.name);let t=0;Object.keys(Tooltip.active).forEach(e=>{Tooltip.active[e].displayed&&t++}),0==t&&Tooltip.observeRemove.disconnect(),query("body").off("."+s),query(document).off("."+s),i.box.remove(),i.box=null,i.displayed=!1;var l=query(i.anchor).data("tooltipName")??[];-1!=l.indexOf(i.name)&&l.splice(l.indexOf(i.name),1),0==l.length?query(i.anchor).removeData("tooltipName"):query(i.anchor).data("tooltipName",l),i.anchor.style.cssText=i.tmp.originalCSS,query(i.anchor).off("."+s).removeClass(i.options.anchorClass),e.finish()}}}resize(i){if(0==arguments.length)Object.keys(Tooltip.active).forEach(e=>{e=Tooltip.active[e];e.displayed&&this.resize(e.name)});else{var s=Tooltip.active[i.replace(/[\s\.#]/g,"_")];let t=this.getPosition(s.name);var l=t.left+"x"+t.top;let e;s.tmp.lastPos!=l&&(e=this.trigger("move",{target:i,overlay:s,pos:t})),query(s.box).css({left:t.left+"px",top:t.top+"px"}).then(e=>{null!=t.width&&e.css("width",t.width+"px").find(".w2ui-overlay-body").css("width","100%"),null!=t.height&&e.css("height",t.height+"px").find(".w2ui-overlay-body").css("height","100%")}).find(".w2ui-overlay-body").removeClass("w2ui-arrow-right w2ui-arrow-left w2ui-arrow-top w2ui-arrow-bottom").addClass(t.arrow.class).closest(".w2ui-overlay").find("style").text(t.arrow.style),s.tmp.lastPos!=l&&e&&(s.tmp.lastPos=l,e.finish())}}getPosition(e){let g=Tooltip.active[e.replace(/[\s\.#]/g,"_")];if(g&&g.box){let t=g.options;(g.tmp.resizedY||g.tmp.resizedX)&&query(g.box).css({width:"",height:"",scroll:"auto"});var e=w2utils.scrollBarSize(),y=!(document.body.scrollWidth==document.body.clientWidth),w=!(document.body.scrollHeight==document.body.clientHeight);let i={width:window.innerWidth-(w?e:0),height:window.innerHeight-(y?e:0)};var b,v=("auto"==t.position?"top|bottom|right|left":t.position).split("|");let s=["top","bottom"].includes(v[0]),l=g.box.getBoundingClientRect(),r=g.anchor.getBoundingClientRect(),a=(g.anchor==document.body&&({x,y:_,width:q,height:C}=t.originalEvent,r={left:x-2,top:_-4,width:q,height:C,arrow:"none"}),t.arrowSize),n=("none"==r.arrow&&(a=0),{top:r.top,bottom:i.height-(r.top+r.height)-+(y?e:0),left:r.left,right:i.width-(r.left+r.width)+(w?e:0)});l.width<22&&(l.width=22),l.height<14&&(l.height=14);let o,h,d,u,c="",p={offset:0,class:"",style:`#${g.id} { --tip-size: ${a}px; }`},f={left:0,top:0},m={posX:"",x:0,posY:"",y:0};v.forEach(e=>{["top","bottom"].includes(e)&&(!c&&l.height+a/1.893m.y)&&Object.assign(m,{posY:e,y:n[e]}),["left","right"].includes(e)&&(!c&&l.width+a/1.893m.x)&&Object.assign(m,{posX:e,x:n[e]})}),c=c||(s?m.posY:m.posX),t.autoResize&&(["top","bottom"].includes(c)&&(l.height>n[c]?(u=n[c],g.tmp.resizedY=!0):g.tmp.resizedY=!1),["left","right"].includes(c))&&(l.width>n[c]?(d=n[c],g.tmp.resizedX=!0):g.tmp.resizedX=!1);var x=c;switch(p.class=r.arrow||"w2ui-arrow-"+x,x){case"top":o=r.left+(r.width-(d??l.width))/2,h=r.top-(u??l.height)-a/1.5+1;break;case"bottom":o=r.left+(r.width-(d??l.width))/2,h=r.top+r.height+a/1.25+1;break;case"left":o=r.left-(d??l.width)-a/1.2-1,h=r.top+(r.height-(u??l.height))/2;break;case"right":o=r.left+r.width+a/1.2+1,h=r.top+(r.height-(u??l.height))/2}if(s)"left"==t.align&&(f.left=r.left-o,o=r.left),"right"==t.align&&(f.left=r.left+r.width-(d??l.width)-o,o=r.left+r.width-(d??l.width)),["top","bottom"].includes(c)&&t.align.startsWith("both")&&(b=t.align.split(":")[1]??50,r.width>=b)&&(o=r.left,d=r.width),"top"==t.align&&(f.top=r.top-h,h=r.top),"bottom"==t.align&&(f.top=r.top+r.height-(u??l.height)-h,h=r.top+r.height-(u??l.height)),["left","right"].includes(c)&&t.align.startsWith("both")&&(b=t.align.split(":")[1]??50,r.height>=b)&&(h=r.top,u=r.height);{let e;(["left","right"].includes(t.align)&&r.width<(d??l.width)||["top","bottom"].includes(t.align)&&r.height<(u??l.height))&&(e=!0);var _="right"==c?a:t.screenMargin,q="bottom"==c?a:t.screenMargin,C=i.width-(d??l.width)-("left"==c?a:t.screenMargin),y=i.height-(u??l.height)-("top"==c?a:t.screenMargin)+3;(["top","bottom"].includes(c)||t.autoResize)&&(o<_&&(e=!0,f.left-=o,o=_),o>C)&&(e=!0,f.left-=o-C,o+=C-o);(["left","right"].includes(c)||t.autoResize)&&(hy)&&(e=!0,f.top-=h-y,h+=y-h);e&&(_=s?"left":"top",C=s?"width":"height",p.offset=-f[_],q=l[C]/2-a,Math.abs(p.offset)>q+a&&(p.class=""),Math.abs(p.offset)>q&&(p.offset=p.offset<0?-q:q),p.style=w2utils.stripSpaces(`#${g.id} .w2ui-overlay-body:after, + #${g.id} .w2ui-overlay-body:before { + --tip-size: ${a}px; + margin-${_}: ${p.offset}px; + }`))}w="top"==c?-t.margin:"bottom"==c?t.margin:0,e="left"==c?-t.margin:"right"==c?t.margin:0;return h=Math.floor(100*(h+parseFloat(t.offsetY)+parseFloat(w)))/100,{left:o=Math.floor(100*(o+parseFloat(t.offsetX)+parseFloat(e)))/100,top:h,arrow:p,adjust:f,width:d,height:u,pos:c}}}}class ColorTooltip extends Tooltip{constructor(){super(),this.palette=[["000000","333333","555555","777777","888888","999999","AAAAAA","CCCCCC","DDDDDD","EEEEEE","F7F7F7","FFFFFF"],["FF011B","FF9838","FFC300","FFFD59","86FF14","14FF7A","2EFFFC","2693FF","006CE7","9B24F4","FF21F5","FF0099"],["FFEAEA","FCEFE1","FCF4DC","FFFECF","EBFFD9","D9FFE9","E0FFFF","E8F4FF","ECF4FC","EAE6F4","FFF5FE","FCF0F7"],["F4CCCC","FCE5CD","FFF1C2","FFFDA1","D5FCB1","B5F7D0","BFFFFF","D6ECFF","CFE2F3","D9D1E9","FFE3FD","FFD9F0"],["EA9899","F9CB9C","FFE48C","F7F56F","B9F77E","84F0B1","83F7F7","B5DAFF","9FC5E8","B4A7D6","FAB9F6","FFADDE"],["E06666","F6B26B","DEB737","E0DE51","8FDB48","52D189","4EDEDB","76ACE3","6FA8DC","8E7CC3","E07EDA","F26DBD"],["CC0814","E69138","AB8816","B5B20E","6BAB30","27A85F","1BA8A6","3C81C7","3D85C6","674EA7","A14F9D","BF4990"],["99050C","B45F17","80650E","737103","395E14","10783D","13615E","094785","0A5394","351C75","780172","782C5A"]],this.defaults=w2utils.extend({},this.defaults,{advanced:!1,transparent:!0,position:"top|bottom",class:"w2ui-white",color:"",liveUpdate:!0,arrowSize:12,autoResize:!1,anchorClass:"w2ui-focus",autoShowOn:"focus",hideOn:["doc-click","focus-change"],onSelect:null,onLiveUpdate:null})}attach(e,t){let i;1==arguments.length&&e.anchor?e=(i=e).anchor:2===arguments.length&&null!=t&&"object"==typeof t&&((i=t).anchor=e);t=i.hideOn;i=w2utils.extend({},this.defaults,i||{}),t&&(i.hideOn=t),i.style+="; padding: 0;",i.transparent&&"333333"==this.palette[0][1]&&(this.palette[0].splice(1,1),this.palette[0].push("")),i.transparent||"333333"==this.palette[0][1]||(this.palette[0].splice(1,0,"333333"),this.palette[0].pop()),i.color&&(i.color=String(i.color).toUpperCase()),"string"==typeof i.color&&"#"===i.color.substr(0,1)&&(i.color=i.color.substr(1)),this.index=[-1,-1];let s=super.attach(i),l=s.overlay;return l.options.html=this.getColorHTML(l.name,i),l.on("show.attach",e=>{var e=e.detail.overlay,t=e.anchor,i=e.options;["INPUT","TEXTAREA"].includes(t.tagName)&&!i.color&&t.value&&(e.tmp.initColor=t.value),delete e.newColor}),l.on("show:after.attach",e=>{var t;s.overlay?.box&&(t=query(s.overlay.box).find(".w2ui-eaction"),w2utils.bindEvents(t,this),this.initControls(s.overlay))}),l.on("update:after.attach",e=>{var t;s.overlay?.box&&(t=query(s.overlay.box).find(".w2ui-eaction"),w2utils.bindEvents(t,this),this.initControls(s.overlay))}),l.on("hide.attach",e=>{var e=e.detail.overlay,t=e.anchor,i=e.newColor??e.options.color??"",t=(["INPUT","TEXTAREA"].includes(t.tagName)&&t.value!=i&&(t.value=i),this.trigger("select",{color:i,target:e.name,overlay:e}));!0!==t.isCancelled&&t.finish()}),s.liveUpdate=t=>(l.on("liveUpdate.attach",e=>{t(e)}),s),s.select=t=>(l.on("select.attach",e=>{t(e)}),s),s}select(e,t){let i;this.index=[-1,-1],"string"!=typeof t&&(i=t.target,this.index=query(i).attr("index").split(":"),t=query(i).closest(".w2ui-overlay").attr("name"));var s=this.get(t),t=this.trigger("liveUpdate",{color:e,target:t,overlay:s,param:arguments[1]});!0!==t.isCancelled&&(["INPUT","TEXTAREA"].includes(s.anchor.tagName)&&s.options.liveUpdate&&query(s.anchor).val(e),s.newColor=e,query(s.box).find(".w2ui-selected").removeClass("w2ui-selected"),i&&query(i).addClass("w2ui-selected"),t.finish())}nextColor(e){var t=this.palette;switch(e){case"up":this.index[0]--;break;case"down":this.index[0]++;break;case"right":this.index[1]++;break;case"left":this.index[1]--}return this.index[0]<0&&(this.index[0]=0),this.index[0]>t.length-2&&(this.index[0]=t.length-2),this.index[1]<0&&(this.index[1]=0),this.index[1]>t[0].length-1&&(this.index[1]=t[0].length-1),t[this.index[0]][this.index[1]]}tabClick(e,t){"string"!=typeof t&&(t=query(t.target).closest(".w2ui-overlay").attr("name"));var t=this.get(t),i=query(t.box).find(`.w2ui-color-tab:nth-child(${e})`);query(t.box).find(".w2ui-color-tab").removeClass("w2ui-selected"),query(i).addClass("w2ui-selected"),query(t.box).find(".w2ui-tab-content").hide().closest(".w2ui-colors").find(".tab-"+e).show()}getColorHTML(s,l){let r=` +
    +
    `;for(let i=0;i';for(let t=0;t  +
    `}r+="
    ",i<2&&(r+='
    ')}return r=(r=(r+="")+` + `)+` +
    +
    +
    +
    + ${"string"==typeof l.html?l.html:""} +
    +
    `}initControls(n){let a,o=this;var e=n.options;let h=w2utils.parseColor(e.color||n.tmp.initColor),d=(null==h&&(h={r:140,g:150,b:160,a:1}),w2utils.rgb2hsv(h));!0===e.advanced&&this.tabClick(2,n.name),u(d,!0,!0),query(n.box).find("input").off(".w2color").on("change.w2color",e=>{e=query(e.target);let t=parseFloat(e.val());var i=parseFloat(e.attr("max")),i=(isNaN(t)&&(t=0,e.val(0)),1i&&(e.val(i),t=i),t<0&&(e.val(0),t=0),e.attr("name")),e={};-1!==["r","g","b","a"].indexOf(i)?(h[i]=t,d=w2utils.rgb2hsv(h)):-1!==["h","s","v"].indexOf(i)&&(e[i]=t),u(e,!0)}),query(n.box).find(".color-original").off(".w2color").on("click.w2color",e=>{e=w2utils.parseColor(query(e.target).css("background-color"));null!=e&&(h=e,u(d=w2utils.rgb2hsv(h),!0))});e=`${w2utils.isIOS?"touchstart":"mousedown"}.w2color`;let s=`${w2utils.isIOS?"touchend":"mouseup"}.w2color`,l=`${w2utils.isIOS?"touchmove":"mousemove"}.w2color`;function u(e,t,i){null!=e.h&&(d.h=e.h),null!=e.s&&(d.s=e.s),null!=e.v&&(d.v=e.v),null!=e.a&&(h.a=e.a,d.a=e.a);let s="rgba("+(h=w2utils.hsv2rgb(d)).r+","+h.g+","+h.b+","+h.a+")",l=[Number(h.r).toString(16).toUpperCase(),Number(h.g).toString(16).toUpperCase(),Number(h.b).toString(16).toUpperCase(),Math.round(255*Number(h.a)).toString(16).toUpperCase()];var r,a;l.forEach((e,t)=>{1===e.length&&(l[t]="0"+e)}),s=l[0]+l[1]+l[2]+l[3],1===h.a&&(s=l[0]+l[1]+l[2]),query(n.box).find(".color-preview").css("background-color","#"+s),query(n.box).find("input").each(e=>{e.name&&(null!=h[e.name]&&(e.value=h[e.name]),null!=d[e.name]&&(e.value=d[e.name]),"a"===e.name)&&(e.value=h.a)}),i?(e=n.tmp?.initColor||s,query(n.box).find(".color-original").css("background-color","#"+e),query(n.box).find(".w2ui-colors .w2ui-selected").removeClass("w2ui-selected"),query(n.box).find(`.w2ui-colors [name="${e}"]`).addClass("w2ui-selected"),8==s.length&&o.tabClick(2,n.name)):o.select(s,n.name),t&&(i=query(n.box).find(".palette .value1"),e=query(n.box).find(".rainbow .value2"),t=query(n.box).find(".alpha .value2"),r=parseInt(i[0].clientWidth)/2,a=parseInt(e[0].clientWidth)/2,i.css({left:150*d.s/100-r+"px",top:125*(100-d.v)/100-r+"px"}),e.css("left",d.h/2.4-a+"px"),t.css("left",150*h.a-a+"px"),c())}function c(){var e=w2utils.hsv2rgb(d.h,100,100),e=`${e.r},${e.g},`+e.b;query(n.box).find(".palette").css("background-image",`linear-gradient(90deg, rgba(${e},0) 0%, rgba(${e},1) 100%)`)}function r(e){query("body").off(".w2color")}function p(e){var t=a.el,i=e.pageX-a.x,e=e.pageY-a.y;let s=a.left+i,l=a.top+e;var i=parseInt(t.prop("clientWidth"))/2,e=(s<-i&&(s=-i),l<-i&&(l=-i),s>a.width-i&&(s=a.width-i),l>a.height-i&&(l=a.height-i),t.hasClass("move-x")&&t.css({left:s+"px"}),t.hasClass("move-y")&&t.css({top:l+"px"}),query(t.get(0).parentNode).attr("name")),r=parseInt(t.css("left"))+i,t=parseInt(t.css("top"))+i;"palette"===e&&u({s:Math.round(r/a.width*100),v:Math.round(100-t/a.height*100)}),"rainbow"===e&&(u({h:Math.round(2.4*r)}),c()),"alpha"===e&&u({a:parseFloat(Number(r/150).toFixed(2))})}query(n.box).find(".palette, .rainbow, .alpha").off(".w2color").on(e+".w2color",function(e){var t=query(this).find(".value1, .value2"),i=parseInt(t.prop("clientWidth"))/2;t.hasClass("move-x")&&t.css({left:e.offsetX-i+"px"});t.hasClass("move-y")&&t.css({top:e.offsetY-i+"px"});a={el:t,x:e.pageX,y:e.pageY,width:t.prop("parentNode").clientWidth,height:t.prop("parentNode").clientHeight,left:parseInt(t.css("left")),top:parseInt(t.css("top"))},p(e),query("body").off(".w2color").on(l,p).on(s,r)})}}class MenuTooltip extends Tooltip{constructor(){super(),this.defaults=w2utils.extend({},this.defaults,{type:"normal",items:[],index:null,render:null,spinner:!1,msgNoItems:w2utils.lang("No items found"),topHTML:"",menuStyle:"",filter:!1,markSearch:!1,match:"contains",search:!1,altRows:!1,arrowSize:10,align:"left",position:"bottom|top",class:"w2ui-white",anchorClass:"w2ui-focus",autoShowOn:"focus",hideOn:["doc-click","focus-change","select"],onSelect:null,onSubMenu:null,onRemove:null})}attach(e,t){let i;1==arguments.length&&e.anchor?e=(i=e).anchor:2===arguments.length&&null!=t&&"object"==typeof t&&((i=t).anchor=e);t=i.hideOn;i=w2utils.extend({},this.defaults,i||{}),t&&(i.hideOn=t),i.style+="; padding: 0;",null==i.items&&(i.items=[]),i.html=this.getMenuHTML(i);let s=super.attach(i),l=s.overlay;return l.on("show:after.attach, update:after.attach",e=>{if(s.overlay?.box){let e="";l.selected=null,l.options.items=w2utils.normMenu(l.options.items),["INPUT","TEXTAREA"].includes(l.anchor.tagName)&&(e=l.anchor.value,l.selected=l.anchor.dataset.selectedIndex);var t=query(s.overlay.box).find(".w2ui-eaction");w2utils.bindEvents(t,this),this.applyFilter(l.name,null,e).then(e=>{l.tmp.searchCount=e.count,l.tmp.search=e.search,this.refreshSearch(l.name),this.initControls(s.overlay),this.refreshIndex(l.name)})}}),l.on("hide:after.attach",e=>{w2tooltip.hide(l.name+"-tooltip")}),s.select=t=>(l.on("select.attach",e=>{t(e)}),s),s.remove=t=>(l.on("remove.attach",e=>{t(e)}),s),s.subMenu=t=>(l.on("subMenu.attach",e=>{t(e)}),s),s}update(e,t){var i,s=Tooltip.active[e];s?((i=s.options).items!=t&&(i.items=t),t=this.getMenuHTML(i),i.html!=t&&(i.html=t,s.needsUpdate=!0,this.show(e))):console.log(`Tooltip "${e}" is not displayed. Cannot update it.`)}initControls(i){query(i.box).find(".w2ui-menu:not(.w2ui-sub-menu)").off(".w2menu").on("mouseDown.w2menu",{delegate:".w2ui-menu-item"},e=>{var t=e.delegate.dataset;this.menuDown(i,e,t.index,t.parents)}).on((w2utils.isIOS?"touchStart":"click")+".w2menu",{delegate:".w2ui-menu-item"},e=>{var t=e.delegate.dataset;this.menuClick(i,e,parseInt(t.index),t.parents)}).find(".w2ui-menu-item").off(".w2menu").on("mouseEnter.w2menu",e=>{var t=e.target.dataset,t=i.options.items[t.index]?.tooltip;t&&w2tooltip.show({name:i.name+"-tooltip",anchor:e.target,html:t,position:"right|left",hideOn:["doc-click"]})}).on("mouseLeave.w2menu",e=>{w2tooltip.hide(i.name+"-tooltip")}),["INPUT","TEXTAREA"].includes(i.anchor.tagName)&&query(i.anchor).off(".w2menu").on("input.w2menu",e=>{}).on("keyup.w2menu",e=>{e._searchType="filter",this.keyUp(i,e)}),i.options.search&&query(i.box).find("#menu-search").off(".w2menu").on("keyup.w2menu",e=>{e._searchType="search",this.keyUp(i,e)})}getCurrent(e,t){var e=Tooltip.active[e.replace(/[\s\.#]/g,"_")],i=e.options;let s=(t||(e.selected??"")).split("-");var t=s.length-1,e=s[t],l=s.slice(0,s.length-1).join("-"),e=w2utils.isInt(e)?parseInt(e):0;let r=i.items;return s.forEach((e,t)=>{t +
    +
    + ${w2utils.lang("Loading...")} +
    + `;u=u||[],null==e&&(e=h.items),Array.isArray(e)||(e=[]);let c=0,t=null,i="",p=(!d&&h.search&&(i+=` + `,e.forEach(e=>e.hidden=!1)),!d&&h.topHTML&&(i+=`
    ${h.topHTML}
    `),` + ${i} +
    + `);return e.forEach((r,a)=>{t=r.icon;var n=(0`),s=``),"break"!==r.type&&null!=i&&""!==i&&"--"!=String(i).substr(0,2)){var o=["w2ui-menu-item"];1==h.altRows&&o.push(c%2==0?"w2ui-even":"w2ui-odd");let e=1,t=(""===s&&e++,null==r.count&&null==r.hotkey&&!0!==r.remove&&null==r.items&&e++,null==r.tooltip&&null!=r.hint&&(r.tooltip=r.hint),"");if(!0===r.remove)t='x';else if(null!=r.items){let e=[];"function"==typeof r.items?e=r.items(r):Array.isArray(r.items)&&(e=r.items),t="",l=` +
    + ${this.getMenuHTML(h,e,!0,u.concat(a))} +
    `}else null!=r.count&&(t+=""+r.count+""),null!=r.hotkey&&(t+=''+r.hotkey+"");!0===r.disabled&&o.push("w2ui-disabled"),!0===r._noSearchInside&&o.push("w2ui-no-search-inside"),""!==l&&(o.push("has-sub-menu"),r.expanded?o.push("expanded"):o.push("collapsed")),p+=` +
    +
    + ${s} + + +
    + `+l,c++}else{o=(i??"").replace(/^-+/g,"");p+=` +
    +
    + ${o?`
    ${o}
    `:""} +
    `}}e[a]=r}),0===c&&h.msgNoItems&&(p+=` +
    + ${w2utils.lang(h.msgNoItems)} +
    `),p+="
    "}refreshIndex(e){var t,i,e=Tooltip.active[e.replace(/[\s\.#]/g,"_")];e&&(e.displayed||this.show(e.name),t=query(e.box).find(".w2ui-overlay-body").get(0),i=query(e.box).find(".w2ui-menu-search, .w2ui-menu-top").get(0),query(e.box).find(".w2ui-menu-item.w2ui-selected").removeClass("w2ui-selected"),e=query(e.box).find(`.w2ui-menu-item[index="${e.selected}"]`).addClass("w2ui-selected").get(0))&&(e.offsetTop+e.clientHeight>t.clientHeight+t.scrollTop&&e.scrollIntoView({behavior:"smooth",block:"start",inline:"start"}),e.offsetTop{var t;this.getCurrent(i,e.getAttribute("index")).item?.hidden?query(e).hide():((t=s.tmp?.search)&&s.options.markSearch&&w2utils.marker(e,t,{onlyFirst:"begins"==s.options.match}),query(e).show())}),query(s.box).find(".w2ui-sub-menu").each(e=>{var t=query(e).find(".w2ui-menu-item").get().some(e=>"none"!=e.style.display);this.getCurrent(i,e.dataset.parent).item.expanded&&(t?query(e).parent().show():query(e).parent().hide())}),0!=s.tmp.searchCount&&0!=s.options?.items?.length||(0==query(s.box).find(".w2ui-no-items").length&&query(s.box).find(".w2ui-menu:not(.w2ui-sub-menu)").append(` +
    + ${w2utils.lang(s.options.msgNoItems)} +
    `),query(s.box).find(".w2ui-no-items").show()))}applyFilter(s,t,l,i){let r=0;var a=Tooltip.active[s.replace(/[\s\.#]/g,"_")];let n=a.options,o,h;var d=new Promise((e,t)=>{o=e,h=t});null==l&&(l=["INPUT","TEXTAREA"].includes(a.anchor.tagName)?a.anchor.value:"");let u=[];n.selected&&(Array.isArray(n.selected)?u=n.selected.map(e=>e?.id??e):n.selected?.id&&(u=[n.selected.id])),a.tmp.activeChain=null;var c=a.tmp.remote??{hasMore:!0,emtpySet:!1,search:null,total:-1};if(null==t&&n.url&&c.hasMore&&c.search!==l){let e=!0,t=w2utils.lang("Loading...");l.length{this.update(s,e),this.applyFilter(s,null,l).then(e=>{o(e)})}).catch(e=>{console.log("Server Request error",e)})}else{let e;null==t&&!0===(e=this.trigger("search",{search:l,overlay:a,prom:d,resolve:o,reject:h})).isCancelled||(null==t&&(t=a.options.items),!1===n.filter?o({count:-1,search:l}):(t.forEach(t=>{let e="",i="";-1!==["is","begins","begins with"].indexOf(n.match)&&(e="^"),-1!==["is","ends","ends with"].indexOf(n.match)&&(i="$");try{new RegExp(e+l+i,"i").test(t.text)||"..."===t.text?t.hidden=!1:t.hidden=!0}catch(e){}n.hideSelected&&u.includes(t.id)&&(t.hidden=!0),Array.isArray(t.items)&&0{e=e.count;0n.search.length||r.length>=n.search.length&&r.substr(0,n.search.length)!==n.search||r.length{var e=a.url;let i={search:r,max:a.cacheMax};Object.assign(i,a.postData);var t,s=this.trigger("request",{search:r,overlay:l,url:e,postData:i,httpMethod:a.method??"GET",httpHeaders:{}});!0!==s.isCancelled&&(e=new URL(s.detail.url,location),t=w2utils.prepareParams(e,{method:s.detail.httpMethod,headers:s.detail.httpHeaders,body:s.detail.postData}),n.controller=new AbortController,t.signal=n.controller.signal,fetch(e,t).then(e=>e.json()).then(e=>{n.controller=null;var t=l.trigger("load",{search:i.search,overlay:l,data:e});!0!==t.isCancelled&&("string"==typeof(e=t.detail.data)&&(e=JSON.parse(e)),null==(e=Array.isArray(e)?{records:e}:e).records&&null!=e.items&&(e.records=e.items,delete e.items),e.error||null!=e.records||(e.records=[]),Array.isArray(e.records)?(e.records.length>=a.cacheMax?(e.records.splice(a.cacheMax,e.records.length),n.hasMore=!0):n.hasMore=!1,null==a.recId&&null!=a.recid&&(a.recId=a.recid),(a.recId||a.recText)&&e.records.forEach(e=>{"string"==typeof a.recId&&(e.id=e[a.recId]),"function"==typeof a.recId&&(e.id=a.recId(e)),"string"==typeof a.recText&&(e.text=e[a.recText]),"function"==typeof a.recText&&(e.text=a.recText(e))}),n.loading=!1,n.search=r,n.total=e.records.length,n.lastError="",n.emptySet=""===r&&0===e.records.length,t.finish(),o(w2utils.normMenu(e.records))):console.error("ERROR: server did not return proper data structure","\n"," - it should return",{records:[{id:1,text:"item"}]},"\n"," - or just an array ",[{id:1,text:"item"}],"\n"," - or if errorr ",{error:!0,message:"error message"}))}).catch(e=>{var t=this.trigger("error",{overlay:l,search:r,error:e});!0!==t.isCancelled&&("AbortError"!==e?.name&&console.error("ERROR: Server communication failed.","\n"," - it should return",{records:[{id:1,text:"item"}]},"\n"," - or just an array ",[{id:1,text:"item"}],"\n"," - or if errorr ",{error:!0,message:"error message"}),n.loading=!1,n.search="",n.total=-1,n.emptySet=!0,n.lastError=t.detail.error||"Server communication failed",a.items=[],t.finish(),h())}),s.finish())},e?a.debounce??350:0)),new Promise((e,t)=>{o=e,h=t})}getActiveChain(i,e,s=[],l=[],t){var r=Tooltip.active[i.replace(/[\s\.#]/g,"_")];return null!=r.tmp.activeChain?r.tmp.activeChain:((e=null==e?r.options.items:e).forEach((e,t)=>{e.hidden||e.disabled||e?.text?.startsWith("--")||(l.push(s.concat([t]).join("-")),Array.isArray(e.items)&&0{l=l[e].items}),l[i]);if(!n.disabled){let l=(i,s)=>{i.forEach((e,t)=>{e.id!=n.id&&(e.group===n.group&&e.checked&&(a.find(`.w2ui-menu-item[index="${(s?s+"-":"")+t}"] .w2ui-icon`).removeClass("w2ui-icon-check").addClass("w2ui-icon-empty"),i[t].checked=!1),Array.isArray(e.items))&&l(e.items,t)})};"check"!==e.type&&"radio"!==e.type||!1===n.group||query(t.target).hasClass("remove")||query(t.target).closest(".w2ui-menu-item").hasClass("has-sub-menu")||(n.checked="radio"==e.type||!n.checked,n.checked?("radio"===e.type&&query(t.target).closest(".w2ui-menu").find(".w2ui-icon").removeClass("w2ui-icon-check").addClass("w2ui-icon-empty"),"check"===e.type&&null!=n.group&&l(e.items),r.removeClass("w2ui-icon-empty").addClass("w2ui-icon-check")):"check"===e.type&&r.removeClass("w2ui-icon-check").addClass("w2ui-icon-empty")),query(t.target).hasClass("remove")||(a.find(".w2ui-menu-item").removeClass("w2ui-selected"),query(t.delegate).addClass("w2ui-selected"))}}menuClick(t,i,s,l){var r=t.options;let a=r.items;var n=query(i.delegate).closest(".w2ui-menu-item");let o=!r.hideOn.includes("select");(i.shiftKey||i.metaKey||i.ctrlKey)&&(o=!0),"string"==typeof l&&""!==l?l.split("-").forEach(e=>{a=a[e].items}):l=null;var h=(a="function"==typeof a?a({overlay:t,index:s,parentIndex:l,event:i}):a)[s];if(!h.disabled||query(i.target).hasClass("remove")){let e;if(query(i.target).hasClass("remove")){if(!0===(e=this.trigger("remove",{originalEvent:i,target:t.name,overlay:t,item:h,index:s,parentIndex:l,el:n[0]})).isCancelled)return;o=!r.hideOn.includes("item-remove"),n.remove()}else if(n.hasClass("has-sub-menu")){if(!0===(e=this.trigger("subMenu",{originalEvent:i,target:t.name,overlay:t,item:h,index:s,parentIndex:l,el:n[0]})).isCancelled)return;o=!0,n.hasClass("expanded")?(h.expanded=!1,n.removeClass("expanded").addClass("collapsed"),query(n.get(0).nextElementSibling).hide()):(h.expanded=!0,n.addClass("expanded").removeClass("collapsed"),query(n.get(0).nextElementSibling).show()),t.selected=parseInt(n.attr("index"))}else{r=this.findChecked(r.items);if(t.selected=parseInt(n.attr("index")),!0===(e=this.trigger("select",{originalEvent:i,target:t.name,overlay:t,item:h,index:s,parentIndex:l,selected:r,keepOpen:o,el:n[0]})).isCancelled)return;null!=h.keepOpen&&(o=h.keepOpen),["INPUT","TEXTAREA"].includes(t.anchor.tagName)&&(t.anchor.dataset.selected=h.id,t.anchor.dataset.selectedIndex=t.selected)}o||this.hide(t.name),e.finish()}}findChecked(e){let t=[];return e.forEach(e=>{e.checked&&t.push(e),Array.isArray(e.items)&&(t=t.concat(this.findChecked(e.items)))}),t}keyUp(s,l){var r=s.options,e=l.target.value;let a=!0,n=!1;switch(l.keyCode){case 46:case 8:""!==e||s.displayed||(a=!1);break;case 13:if(!s.displayed||!s.selected)return;var{index:t,parents:i}=this.getCurrent(s.name);l.delegate=query(s.box).find(".w2ui-selected").get(0),this.menuClick(s,l,parseInt(t),i),a=!1;break;case 27:a=!1,s.displayed?this.hide(s.name):(t=s.anchor,["INPUT","TEXTAREA"].includes(t.tagName)&&(t.value="",delete t.dataset.selected,delete t.dataset.selectedIndex));break;case 37:{if(!s.displayed)return;let{item:e,index:t,parents:i}=this.getCurrent(s.name);i&&(e=r.items[i],t=parseInt(i),i="",n=!0),Array.isArray(e?.items)&&0{s.tmp.searchCount=e.count,s.tmp.search=e.search,0!==e.count&&this.getActiveChain(s.name).includes(s.selected)||(s.selected=null),this.refreshSearch(s.name)}),n&&this.refreshIndex(s.name)}}class DateTooltip extends Tooltip{constructor(){super();var e=new Date;this.daysCount=[31,28,31,30,31,30,31,31,30,31,30,31],this.today=e.getFullYear()+"/"+(Number(e.getMonth())+1)+"/"+e.getDate(),this.defaults=w2utils.extend({},this.defaults,{position:"top|bottom",class:"w2ui-calendar",type:"date",format:"",value:"",start:null,end:null,blockDates:[],blockWeekdays:[],colored:{},arrowSize:12,autoResize:!1,anchorClass:"w2ui-focus",autoShowOn:"focus",hideOn:["doc-click","focus-change"],onSelect:null})}attach(e,t){let i;1==arguments.length&&e.anchor?e=(i=e).anchor:2===arguments.length&&null!=t&&"object"==typeof t&&((i=t).anchor=e);var t=i.hideOn,e=(i=w2utils.extend({},this.defaults,i||{}),t&&(i.hideOn=t),i.format||(e=w2utils.settings.dateFormat,t=w2utils.settings.timeFormat,"date"==i.type?i.format=e:"time"==i.type?i.format=t:i.format=e+"|"+t),"time"==i.type?this.getHourHTML(i):this.getMonthHTML(i));i.style+="; padding: 0;",i.html=e.html;let s=super.attach(i),l=s.overlay;return Object.assign(l.tmp,e),l.on("show.attach",e=>{var e=e.detail.overlay,t=e.anchor,i=e.options;["INPUT","TEXTAREA"].includes(t.tagName)&&!i.value&&t.value&&(e.tmp.initValue=t.value),delete e.newValue,delete e.newDate}),l.on("show:after.attach",e=>{s.overlay?.box&&this.initControls(s.overlay)}),l.on("update:after.attach",e=>{s.overlay?.box&&this.initControls(s.overlay)}),l.on("hide.attach",e=>{var e=e.detail.overlay,t=e.anchor;null!=e.newValue&&(e.newDate&&(e.newValue=e.newDate+" "+e.newValue),["INPUT","TEXTAREA"].includes(t.tagName)&&t.value!=e.newValue&&(t.value=e.newValue),!0!==(t=this.trigger("select",{date:e.newValue,target:e.name,overlay:e})).isCancelled)&&t.finish()}),s.select=t=>(l.on("select.attach",e=>{t(e)}),s),s}initControls(l){let r=l.options,t=e=>{let{month:t,year:i}=l.tmp;12<(t+=e)&&(t=1,i++),t<1&&(t=12,i--);e=this.getMonthHTML(r,t,i);Object.assign(l.tmp,e),query(l.box).find(".w2ui-overlay-body").html(e.html),this.initControls(l)},i=(e,t)=>{query(e.target).parent().find(".w2ui-jump-month, .w2ui-jump-year").removeClass("w2ui-selected"),query(e.target).addClass("w2ui-selected");e=new Date;let{jumpMonth:i,jumpYear:s}=l.tmp;(i=t&&(null==s&&(s=e.getFullYear()),null==i)?e.getMonth()+1:i)&&s&&(t=this.getMonthHTML(r,i,s),Object.assign(l.tmp,t),query(l.box).find(".w2ui-overlay-body").html(t.html),l.tmp.jump=!1,this.initControls(l))};query(l.box).find(".w2ui-cal-title").off(".calendar").on("click.calendar",e=>{var t,i;Object.assign(l.tmp,{jumpYear:null,jumpMonth:null}),l.tmp.jump?({month:t,year:i}=l.tmp,t=this.getMonthHTML(r,t,i),query(l.box).find(".w2ui-overlay-body").html(t.html),l.tmp.jump=!1):(query(l.box).find(".w2ui-overlay-body .w2ui-cal-days").replace(this.getYearHTML()),(i=query(l.box).find(`[name="${l.tmp.year}"]`).get(0))&&i.scrollIntoView(!0),l.tmp.jump=!0),this.initControls(l),e.stopPropagation()}).find(".w2ui-cal-previous").off(".calendar").on("click.calendar",e=>{t(-1),e.stopPropagation()}).parent().find(".w2ui-cal-next").off(".calendar").on("click.calendar",e=>{t(1),e.stopPropagation()}),query(l.box).find(".w2ui-cal-now").off(".calendar").on("click.calendar",e=>{"datetime"==r.type?l.newDate?l.newValue=w2utils.formatTime(new Date,r.format.split("|")[1]):l.newValue=w2utils.formatDateTime(new Date,r.format):"date"==r.type?l.newValue=w2utils.formatDate(new Date,r.format):"time"==r.type&&(l.newValue=w2utils.formatTime(new Date,r.format)),this.hide(l.name)}),query(l.box).off(".calendar").on("click.calendar",{delegate:".w2ui-day.w2ui-date"},e=>{"datetime"==r.type?(l.newDate=query(e.target).attr("date"),query(l.box).find(".w2ui-overlay-body").html(this.getHourHTML(l.options).html),this.initControls(l)):(l.newValue=query(e.target).attr("date"),this.hide(l.name))}).on("click.calendar",{delegate:".w2ui-jump-month"},e=>{l.tmp.jumpMonth=parseInt(query(e.target).attr("name")),i(e)}).on("dblclick.calendar",{delegate:".w2ui-jump-month"},e=>{l.tmp.jumpMonth=parseInt(query(e.target).attr("name")),i(e,!0)}).on("click.calendar",{delegate:".w2ui-jump-year"},e=>{l.tmp.jumpYear=parseInt(query(e.target).attr("name")),i(e)}).on("dblclick.calendar",{delegate:".w2ui-jump-year"},e=>{l.tmp.jumpYear=parseInt(query(e.target).attr("name")),i(e,!0)}).on("click.calendar",{delegate:".w2ui-time.hour"},e=>{var e=query(e.target).attr("hour");let t=this.str2min(r.value)%60;l.tmp.initValue&&!r.value&&(t=this.str2min(l.tmp.initValue)%60),r.noMinutes?(l.newValue=this.min2str(60*e,r.format),this.hide(l.name)):(l.newValue=e+":"+t,e=this.getMinHTML(e,r).html,query(l.box).find(".w2ui-overlay-body").html(e),this.initControls(l))}).on("click.calendar",{delegate:".w2ui-time.min"},e=>{e=60*Math.floor(this.str2min(l.newValue)/60)+parseInt(query(e.target).attr("min"));l.newValue=this.min2str(e,r.format),this.hide(l.name)})}getMonthHTML(l,r,e){var t=w2utils.settings.fulldays.slice(),i=w2utils.settings.shortdays.slice();"M"!==w2utils.settings.weekStarts&&(t.unshift(t.pop()),i.unshift(i.pop()));let s=new Date;var t="datetime"===l.type?w2utils.isDateTime(l.value,l.format,!0):w2utils.isDate(l.value,l.format,!0),a=w2utils.formatDate(t);null!=r&&null!=e||(e=(t||s).getFullYear(),r=t?t.getMonth()+1:s.getMonth()+1),12${i[e]}`}let c=` +
    +
    +
    +
    +
    +
    +
    + ${w2utils.settings.fullmonths[r-1]}, ${e} + +
    +
    + ${o} + `,p=new Date(e+`/${r}/1`);t=(p=new Date(p.getTime()+432e5)).getDay();"M"==w2utils.settings.weekStarts&&n--,0 + ${g} +
    `,p=new Date(p.getTime()+864e5)}return c+="",l.btnNow&&(t=w2utils.lang("Today"+("datetime"==l.type?" & Now":"")),c+=`
    ${t}
    `),{html:c,month:r,year:e}}getYearHTML(){let t="",i="";for(let e=0;e${w2utils.settings.shortmonths[e]}`;for(let e=w2utils.settings.dateStartYear;e<=w2utils.settings.dateEndYear;e++)i+=`
    ${e}
    `;return`
    +
    ${t}
    +
    ${i}
    +
    `}getHourHTML(l){(l=l??{}).format||(l.format=w2utils.settings.timeFormat);var r=-1${e}
    `}return{html:`
    +
    ${w2utils.lang("Select Hour")}
    +
    +
    ${n[0]}
    +
    ${n[1]}
    +
    ${n[2]}
    +
    + ${l.btnNow?`
    ${w2utils.lang("Now")}
    `:""} +
    `}}getMinHTML(i,s){null==i&&(i=0),(s=s??{}).format||(s.format=w2utils.settings.timeFormat);var l=-1${n}
    `}return{html:`
    +
    ${w2utils.lang("Select Minute")}
    +
    +
    ${a[0]}
    +
    ${a[1]}
    +
    ${a[2]}
    +
    + ${s.btnNow?`
    ${w2utils.lang("Now")}
    `:""} +
    `}}inRange(i,s,e){let l=!1;if("date"===s.type){var r=w2utils.isDate(i,s.format,!0);if(r){if(s.start||s.end){var a="string"==typeof s.start?s.start:query(s.start).val(),n="string"==typeof s.end?s.end:query(s.end).val();let e=w2utils.isDate(a,s.format,!0),t=w2utils.isDate(n,s.format,!0);a=new Date(r);e=e||a,t=t||a,a>=e&&a<=t&&(l=!0)}else l=!0;Array.isArray(s.blockDates)&&s.blockDates.includes(i)&&(l=!1),Array.isArray(s.blockWeekdays)&&s.blockWeekdays.includes(r.getDay())&&(l=!1)}}else if("time"===s.type)if(s.start||s.end){n=this.str2min(i);let e=this.str2min(s.start),t=this.str2min(s.end);e=e||n,t=t||n,n>=e&&n<=t&&(l=!0)}else l=!0;else"datetime"===s.type&&(a=w2utils.isDateTime(i,s.format,!0))&&(r=s.format.split("|").map(e=>e.trim()),e?(n=w2utils.formatDate(a,r[0]),i=w2utils.extend({},s,{type:"date",format:r[0]}),this.inRange(n,i)&&(l=!0)):(e=w2utils.formatTime(a,r[1]),n={type:"time",format:r[1],start:s.startTime,end:s.endTime},this.inRange(e,n)&&(l=!0)));return l}str2min(e){var t;return"string"!=typeof e||2!==(t=e.split(":")).length?null:(t[0]=parseInt(t[0]),t[1]=parseInt(t[1]),-1!==e.indexOf("pm")&&12!==t[0]&&(t[0]+=12),e.includes("am")&&12==t[0]&&(t[0]=0),60*t[0]+t[1])}min2str(e,t){let i="";1440<=e&&(e%=1440),e<0&&(e=1440+e);var s=Math.floor(e/60),e=(e%60<10?"0":"")+e%60;return t=t||w2utils.settings.timeFormat,i=-1!==t.indexOf("h24")?s+":"+e:(s<=12?s:s-12)+":"+e+" "+(12<=s?"pm":"am")}}let w2tooltip=new Tooltip,w2menu=new MenuTooltip,w2color=new ColorTooltip,w2date=new DateTooltip;class w2toolbar extends w2base{constructor(e){super(e.name),this.box=null,this.name=null,this.routeData={},this.items=[],this.right="",this.tooltip="top|left",this.onClick=null,this.onMouseDown=null,this.onMouseUp=null,this.onMouseEnter=null,this.onMouseLeave=null,this.onRender=null,this.onRefresh=null,this.onResize=null,this.onDestroy=null,this.item_template={id:null,type:"button",text:null,html:"",tooltip:null,count:null,hidden:!1,disabled:!1,checked:!1,icon:null,route:null,arrow:null,style:null,group:null,items:null,selected:null,color:null,overlay:{anchorClass:""},onClick:null,onRefresh:null},this.last={badge:{}};var t=e.items;delete e.items,Object.assign(this,e),Array.isArray(t)&&this.add(t,!0),e.items=t,"string"==typeof this.box&&(this.box=query(this.box).get(0)),this.box&&this.render(this.box)}add(e,t){this.insert(null,e,t)}insert(r,e,a){(e=Array.isArray(e)?e:[e]).forEach((e,t,i)=>{"string"==typeof e&&(e=i[t]={id:e,text:e});var l,s=["button","check","radio","drop","menu","menu-radio","menu-check","color","text-color","html","break","spacer","new-line"];if(s.includes(String(e.type)))if(null!=e.id||["break","spacer","new-line"].includes(e.type)){if(null==e.type)console.log('ERROR: The parameter "type" is required but not supplied.',e);else if(w2utils.checkUniqueId(e.id,this.items,"toolbar",this.name)){let s=w2utils.extend({},this.item_template,e);"menu-check"==s.type?(Array.isArray(s.selected)||(s.selected=[]),Array.isArray(s.items)&&s.items.forEach(e=>{(e="string"==typeof e?i[t]={id:e,text:e}:e).checked&&!s.selected.includes(e.id)&&s.selected.push(e.id),!e.checked&&s.selected.includes(e.id)&&(e.checked=!0),null==e.checked&&(e.checked=!1)})):"menu-radio"==s.type&&Array.isArray(s.items)&&s.items.forEach((e,t,i)=>{(e="string"==typeof e?i[t]={id:e,text:e}:e).checked&&null==s.selected?s.selected=e.id:e.checked=!1,e.checked||s.selected!=e.id||(e.checked=!0),null==e.checked&&(e.checked=!1)}),null==r?this.items.push(s):(l=this.get(r,!0),this.items=this.items.slice(0,l).concat([s],this.items.slice(l))),s.line=s.line??1,!0!==a&&this.refresh(s.id)}}else console.log('ERROR: The parameter "id" is required but not supplied.',e);else console.log('ERROR: The parameter "type" should be one of the following:',s,`, but ${e.type} is supplied.`,e)}),!0!==a&&this.resize()}remove(){let i=0;return Array.from(arguments).forEach(e=>{var t=this.get(e);t&&-1==String(e).indexOf(":")&&(i++,query(this.box).find("#tb_"+this.name+"_item_"+w2utils.escapeId(t.id)).remove(),null!=(e=this.get(t.id,!0)))&&this.items.splice(e,1)}),this.resize(),i}set(e,t){var i=this.get(e);return null!=i&&(Object.assign(i,t),this.refresh(String(e).split(":")[0]),!0)}get(e,i){if(0===arguments.length){var t=[];for(let e=0;e span`);0{var t=this.get(e);t&&(t.hidden=!1,i.push(String(e).split(":")[0]))}),setTimeout(()=>{i.forEach(e=>{this.refresh(e),this.resize()})},15),i}hide(){let i=[];return Array.from(arguments).forEach(e=>{var t=this.get(e);t&&(t.hidden=!0,i.push(String(e).split(":")[0]))}),setTimeout(()=>{i.forEach(e=>{this.refresh(e),this.tooltipHide(e),this.resize()})},15),i}enable(){let i=[];return Array.from(arguments).forEach(e=>{var t=this.get(e);t&&(t.disabled=!1,i.push(String(e).split(":")[0]))}),setTimeout(()=>{i.forEach(e=>{this.refresh(e)})},15),i}disable(){let i=[];return Array.from(arguments).forEach(e=>{var t=this.get(e);t&&(t.disabled=!0,i.push(String(e).split(":")[0]))}),setTimeout(()=>{i.forEach(e=>{this.refresh(e),this.tooltipHide(e)})},15),i}check(){let i=[];return Array.from(arguments).forEach(e=>{var t=this.get(e);t&&-1==String(e).indexOf(":")&&(t.checked=!0,i.push(String(e).split(":")[0]))}),setTimeout(()=>{i.forEach(e=>{this.refresh(e)})},15),i}uncheck(){let i=[];return Array.from(arguments).forEach(e=>{var t=this.get(e);t&&-1==String(e).indexOf(":")&&(["menu","menu-radio","menu-check","drop","color","text-color"].includes(t.type)&&t.checked&&w2tooltip.hide(this.name+"-drop"),t.checked=!1,i.push(String(e).split(":")[0]))}),setTimeout(()=>{i.forEach(e=>{this.refresh(e)})},15),i}click(e,t){var i=String(e).split(":");let l=this.get(i[0]),r=l&&l.items?w2utils.normMenu.call(this,l.items,l):[];if(1{var t=(e,t)=>{let i=this;return function(){i.set(e,{checked:!1})}},i=query(this.box).find("#tb_"+this.name+"_item_"+w2utils.escapeId(l.id));if(w2utils.isPlainObject(l.overlay)||(l.overlay={}),"drop"==l.type&&w2tooltip.show(w2utils.extend({html:l.html,class:"w2ui-white",hideOn:["doc-click"]},l.overlay,{anchor:i[0],name:this.name+"-drop",data:{item:l,btn:s}})).hide(t(l.id,s)),["menu","menu-radio","menu-check"].includes(l.type)){let e="normal";"menu-radio"==l.type&&(e="radio",r.forEach(e=>{l.selected==e.id?e.checked=!0:e.checked=!1})),"menu-check"==l.type&&(e="check",r.forEach(e=>{Array.isArray(l.selected)&&l.selected.includes(e.id)?e.checked=!0:e.checked=!1})),w2menu.show(w2utils.extend({items:r},l.overlay,{type:e,name:this.name+"-drop",anchor:i[0],data:{item:l,btn:s}})).hide(t(l.id,s)).remove(e=>{this.menuClick({name:this.name,remove:!0,item:l,subItem:e.detail.item,originalEvent:e})}).select(e=>{this.menuClick({name:this.name,item:l,subItem:e.detail.item,originalEvent:e})})}["color","text-color"].includes(l.type)&&w2color.show(w2utils.extend({color:l.color},l.overlay,{anchor:i[0],name:this.name+"-drop",data:{item:l,btn:s}})).hide(t(l.id,s)).select(e=>{null!=e.detail.color&&this.colorClick({name:this.name,item:l,color:e.detail.color})})},0)}if(["check","menu","menu-radio","menu-check","drop","color","text-color"].includes(l.type)&&(l.checked=!l.checked,l.checked?query(this.box).find(s).addClass("checked"):query(this.box).find(s).removeClass("checked")),l.route){let t=String("/"+l.route).replace(/\/{2,}/g,"/");var n=w2utils.parseRoute(t);if(0{window.location.hash=t},1)}this.tooltipShow(e),i.finish()}}}scroll(n,o,h){return new Promise((e,t)=>{var i=query(this.box).find(`.w2ui-tb-line:nth-child(${o}) .w2ui-scroll-wrapper`),s=i.get(0).scrollLeft,l=i.find(".w2ui-tb-right").get(0),r=i.parent().get(0).getBoundingClientRect().width,a=s+parseInt(l.offsetLeft)+parseInt(l.clientWidth);switch(n){case"left":(scroll=s-r+50)<=0&&(scroll=0),i.get(0).scrollTo({top:0,left:scroll,behavior:h?"atuo":"smooth"});break;case"right":(scroll=s+r-50)>=a-r&&(scroll=a-r),i.get(0).scrollTo({top:0,left:scroll,behavior:h?"atuo":"smooth"})}setTimeout(()=>{this.resize(),e()},h?0:500)})}render(e){var s=Date.now(),l=("string"==typeof e&&(e=query(e).get(0)),this.trigger("render",{target:this.name,box:e??this.box}));if(!0!==l.isCancelled&&(null!=e&&(0 ",r),null!=r.hint&&console.log("NOTICE: toolbar item.hint property is deprecated, please use item.tooltip. Item -> ",r),0!==e&&"new-line"!=r.type||(i++,t+=` +
    +
    +
    ${this.right[i-1]??""}
    +
    +
    +
    +
    + `),r.line=i)}return query(this.box).attr("name",this.name).addClass("w2ui-reset w2ui-toolbar").html(t),0{this.resize()}),this.last.observeResize.observe(this.box),this.refresh(),this.resize(),l.finish(),Date.now()-s}}refresh(t){var i=Date.now(),l=this.trigger("refresh",{target:null!=t?t:this.name,item:this.get(t)});if(!0!==l.isCancelled){let e;if(null==t)for(let e=0;e{i[e].anchor==s.get(0)&&(i[e].anchor=t)})}if(["menu","menu-radio","menu-check"].includes(r.type)&&r.checked){let t=Array.isArray(r.selected)?r.selected:[r.selected];r.items.forEach(e=>{t.includes(e.id)?e.checked=!0:e.checked=!1}),w2menu.update(this.name+"-drop",r.items)}return"function"==typeof r.onRefresh&&e.finish(),l.finish(),Date.now()-i}}}}resize(){var e=Date.now(),t=this.trigger("resize",{target:this.name});if(!0!==t.isCancelled)return query(this.box).find(".w2ui-tb-line").each(e=>{var e=query(e),t=(e.find(".w2ui-scroll-left, .w2ui-scroll-right").hide(),e.find(".w2ui-scroll-wrapper").get(0)),i=e.find(".w2ui-tb-right"),s=e.get(0).getBoundingClientRect().width,i=0e.id==t)}),""),s="function"==typeof i.text?i.text.call(this,i):i.text;i.icon&&(t=i.icon,"function"==typeof i.icon&&(t=i.icon.call(this,i)),t=`
    ${t="<"!==String(t).slice(0,1)?``:t}
    `);var l=["w2ui-tb-button"];switch(i.checked&&l.push("checked"),i.disabled&&l.push("disabled"),i.hidden&&l.push("hidden"),t||l.push("no-icon"),i.type){case"color":case"text-color":"string"==typeof i.color&&("#"==i.color.slice(0,1)&&(i.color=i.color.slice(1)),[3,6,8].includes(i.color.length))&&(i.color="#"+i.color),"color"==i.type&&(s=` + `+(i.text?`
    ${w2utils.lang(i.text)}
    `:"")),"text-color"==i.type&&(s=''+(i.text?w2utils.lang(i.text):"Aa")+"");case"menu":case"menu-check":case"menu-radio":case"button":case"check":case"radio":case"drop":var r=!0===i.arrow||!1!==i.arrow&&["menu","menu-radio","menu-check","drop","color","text-color"].includes(i.type);e=` +
    + ${t} + ${""!=s?`
    + ${w2utils.lang(s)} + ${null!=i.count?w2utils.stripSpaces(` + ${i.count} + `):""} + ${r?'':""} +
    `:""} +
    + `;break;case"break":e=`
    +   +
    `;break;case"spacer":e=`
    +
    `;break;case"html":e=`
    + ${"function"==typeof i.html?i.html.call(this,i):i.html} +
    `}return e}tooltipShow(t){if(null!=this.tooltip){var i=query(this.box).find("#tb_"+this.name+"_item_"+w2utils.escapeId(t)).get(0),t=this.get(t),s=this.tooltip;let e=t.tooltip;"function"==typeof e&&(e=e.call(this,t)),["menu","menu-radio","menu-check","drop","color","text-color"].includes(t.type)&&1==t.checked||w2tooltip.show({anchor:i,name:this.name+"-tooltip",html:e,position:s})}}tooltipHide(e){null!=this.tooltip&&w2tooltip.hide(this.name+"-tooltip")}menuClick(t){if(t.item&&!t.item.disabled){var i=this.trigger(!0!==t.remove?"click":"remove",{target:t.item.id+":"+t.subItem.id,item:t.item,subItem:t.subItem,originalEvent:t.originalEvent});if(!0!==i.isCancelled){let l=t.subItem,r=this.get(t.item.id),e=r.items;if("function"==typeof e&&(e=r.items()),"menu"==r.type&&(r.selected=l.id),"menu-radio"==r.type&&(r.selected=l.id,Array.isArray(e)&&e.forEach(e=>{!0===e.checked&&delete e.checked,Array.isArray(e.items)&&e.items.forEach(e=>{!0===e.checked&&delete e.checked})}),l.checked=!0),"menu-check"==r.type)if(Array.isArray(r.selected)||(r.selected=[]),null==l.group){var a=r.selected.indexOf(l.id);-1==a?(r.selected.push(l.id),l.checked=!0):(r.selected.splice(a,1),l.checked=!1)}else if(!1!==l.group){let i=[];a=r.selected.indexOf(l.id);let s=e=>{e.forEach(e=>{var t;e.group===l.group&&-1!=(t=r.selected.indexOf(e.id))&&(e.id!=l.id&&i.push(e.id),r.selected.splice(t,1)),Array.isArray(e.items)&&s(e.items)})};s(e),-1==a&&(r.selected.push(l.id),l.checked=!0)}if("string"==typeof l.route){let t=""!==l.route?String("/"+l.route).replace(/\/{2,}/g,"/"):"";var s=w2utils.parseRoute(t);if(0{window.location.hash=t},1)}this.refresh(t.item.id),i.finish()}}}colorClick(e){var t;e.item&&!e.item.disabled&&!0!==(t=this.trigger("click",{target:e.item.id,item:e.item,color:e.color,final:e.final,originalEvent:e.originalEvent})).isCancelled&&(e.item.color=e.color,this.refresh(e.item.id),t.finish())}mouseAction(e,t,i,s){var l=this.get(s),e=this.trigger("mouse"+i,{target:s,item:l,object:l,originalEvent:e});if(!0!==e.isCancelled&&!l.disabled&&!l.hidden){switch(i){case"Enter":query(t).addClass("over"),this.tooltipShow(s);break;case"Leave":query(t).removeClass("over down"),this.tooltipHide(s);break;case"Down":query(t).addClass("down");break;case"Up":query(t).removeClass("down")}e.finish()}}}class w2sidebar extends w2base{constructor(e){super(e.name),this.name=null,this.box=null,this.sidebar=null,this.parent=null,this.nodes=[],this.menu=[],this.routeData={},this.selected=null,this.icon=null,this.style="",this.topHTML="",this.bottomHTML="",this.flatButton=!1,this.keyboard=!0,this.flat=!1,this.hasFocus=!1,this.levelPadding=12,this.skipRefresh=!1,this.tabIndex=null,this.handle={size:0,style:"",html:"",tooltip:""},this.onClick=null,this.onDblClick=null,this.onMouseEnter=null,this.onMouseLeave=null,this.onContextMenu=null,this.onMenuClick=null,this.onExpand=null,this.onCollapse=null,this.onKeydown=null,this.onRender=null,this.onRefresh=null,this.onResize=null,this.onDestroy=null,this.onFocus=null,this.onBlur=null,this.onFlat=null,this.node_template={id:null,text:"",order:null,count:null,icon:null,nodes:[],style:"",route:null,selected:!1,expanded:!1,hidden:!1,disabled:!1,group:!1,groupShowHide:!0,collapsible:!1,plus:!1,onClick:null,onDblClick:null,onContextMenu:null,onExpand:null,onCollapse:null,parent:null,sidebar:null},this.last={badge:{}};var t=e.nodes;delete e.nodes,Object.assign(this,e),Array.isArray(t)&&this.add(t),e.nodes=t,"string"==typeof this.box&&(this.box=query(this.box).get(0)),this.box&&this.render(this.box)}add(e,t){return 1==arguments.length&&(t=arguments[0],e=this),"string"==typeof e&&(e=this.get(e)),this.insert(e=null!=e&&""!=e?e:this,null,t)}insert(t,i,s){let l,r,a,n,o;if(2==arguments.length&&"string"==typeof t)if(s=arguments[1],null!=(i=arguments[0])){if(null==(r=this.get(i)))return null!=(s=Array.isArray(s)?s:[s])[0].caption&&null==s[0].text&&(console.log("NOTICE: sidebar node.caption property is deprecated, please use node.text. Node -> ",s[0]),s[0].text=s[0].caption),l=s[0].text,console.log('ERROR: Cannot insert node "'+l+'" because cannot find node "'+i+'" to insert before.'),null;t=this.get(i).parent}else t=this;null!=(t="string"==typeof t?this.get(t):t)&&""!=t||(t=this),Array.isArray(s)||(s=[s]);for(let e=0;e{null!=(i=this.get(e))&&(null!=this.selected&&this.selected===i.id&&(this.selected=null),null!=(e=this.get(i.parent,e,!0)))&&(i.parent.nodes[e].selected&&i.sidebar.unselect(i.id),i.parent.nodes.splice(e,1),i.parent.collapsible=0{var e=i.nodes&&0{e.nodes&&0{t.call(this,e),e.nodes&&0{-1===e.text.toLowerCase().indexOf(i)?e.hidden=!0:(t++,function e(t){t.parent&&(t.parent.hidden=!1,e(t.parent))}(e),e.hidden=!1)}),this.refresh(),t}show(){let t=[];return Array.from(arguments).forEach(e=>{e=this.get(e);null!=e&&!1!==e.hidden&&(e.hidden=!1,t.push(e.id))}),0{e=this.get(e);null!=e&&!0!==e.hidden&&(e.hidden=!0,t.push(e.id))}),0{e=this.get(e);null!=e&&!1!==e.disabled&&(e.disabled=!1,t.push(e.id))}),0{e=this.get(e);null!=e&&!0!==e.disabled&&(e.disabled=!0,e.selected&&this.unselect(e.id),t.push(e.id))}),0{t.refresh(e)},0),!0):void 0)}expand(e){var t=this.get(e),i=this.trigger("expand",{target:e,object:t});if(!0!==i.isCancelled)return query(this.box).find("#node_"+w2utils.escapeId(e)+"_sub").show(),query(this.box).find("#node_"+w2utils.escapeId(e)+" .w2ui-collapsed").removeClass("w2ui-collapsed").addClass("w2ui-expanded"),t.expanded=!0,i.finish(),this.refresh(e),!0}collapseAll(t){if(null==(t="string"==typeof(t=null==t?this:t)?this.get(t):t).nodes)return!1;for(let e=0;e{var t=query(e).attr("id").replace("node_",""),t=a.get(t);null!=t&&(t.selected=!1),query(e).removeClass("w2ui-selected").find(".w2ui-icon").removeClass("w2ui-icon-selected")});let t=query(a.box).find("#node_"+w2utils.escapeId(l)),s=query(a.box).find("#node_"+w2utils.escapeId(a.selected));t.addClass("w2ui-selected").find(".w2ui-icon").addClass("w2ui-icon-selected"),setTimeout(()=>{var e=a.trigger("click",{target:l,originalEvent:r,node:n,object:n});if(!0===e.isCancelled)t.removeClass("w2ui-selected").find(".w2ui-icon").removeClass("w2ui-icon-selected"),s.addClass("w2ui-selected").find(".w2ui-icon").addClass("w2ui-icon-selected");else{if(null!=s&&(s.selected=!1),a.get(l).selected=!0,a.selected=l,"string"==typeof n.route){let t=""!==n.route?String("/"+n.route).replace(/\/{2,}/g,"/"):"";var i=w2utils.parseRoute(t);if(0{window.location.hash=t},1)}e.finish()}},1)}}focus(e){let t=this;e=this.trigger("focus",{target:this.name,originalEvent:e});if(!0===e.isCancelled)return!1;this.hasFocus=!0,query(this.box).find(".w2ui-sidebar-body").addClass("w2ui-focus"),setTimeout(()=>{var e=query(t.box).find("#sidebar_"+t.name+"_focus").get(0);document.activeElement!=e&&e.focus()},10),e.finish()}blur(e){e=this.trigger("blur",{target:this.name,originalEvent:e});if(!0===e.isCancelled)return!1;this.hasFocus=!1,query(this.box).find(".w2ui-sidebar-body").removeClass("w2ui-focus"),e.finish()}keydown(e){let a=this,t=a.get(a.selected);var i;function s(e,t){null==e||e.hidden||e.disabled||e.group||(a.click(e.id,t),a.inView(e.id))||a.scrollIntoView(e.id)}function l(e,t){for(e=t(e);null!=e&&(e.hidden||e.disabled)&&!e.group;)e=t(e);return e}function r(e){if(null==e)return null;var t=e.parent,e=a.get(e.id,!0);let i=0t.clientHeight+t.scrollTop)}scrollIntoView(i,s){return new Promise((e,t)=>{null==i&&(i=this.selected),null!=this.get(i)&&(query(this.box).find("#node_"+w2utils.escapeId(i)).get(0).scrollIntoView({block:"center",inline:"center",behavior:s?"atuo":"smooth"}),setTimeout(()=>{this.resize(),e()},s?0:500))})}dblClick(e,t){var i=this.get(e),t=this.trigger("dblClick",{target:e,originalEvent:t,object:i});!0!==t.isCancelled&&(this.toggle(e),t.finish())}contextMenu(t,i){var e=this.get(t),s=(t!=this.selected&&this.click(t),this.trigger("contextMenu",{target:t,originalEvent:i,object:e,allowOnDisabled:!1}));!0===s.isCancelled||e.disabled&&!s.allowOnDisabled||(0{this.menuClick(t,parseInt(e.detail.index),i)}),i.preventDefault&&i.preventDefault(),s.finish())}menuClick(e,t,i){e=this.trigger("menuClick",{target:e,originalEvent:i,menuIndex:t,menuItem:this.menu[t]});!0!==e.isCancelled&&e.finish()}goFlat(){var e=this.trigger("flat",{goFlat:!this.flat});!0!==e.isCancelled&&(this.flat=!this.flat,this.refresh(),e.finish())}render(e){var i=Date.now();let s=this;"string"==typeof e&&(e=query(e).get(0));var l=this.trigger("render",{target:this.name,box:e??this.box});if(!0!==l.isCancelled&&(null!=e&&(0 +
    + +
    +
    + `);e=query(this.box).get(0).getBoundingClientRect();query(this.box).find(":scope > div").css({width:e.width+"px",height:e.height+"px"}),query(this.box).get(0).style.cssText+=this.style;let t;return query(this.box).find("#sidebar_"+this.name+"_focus").on("focus",function(e){clearTimeout(t),s.hasFocus||s.focus(e)}).on("blur",function(e){t=setTimeout(()=>{s.hasFocus&&s.blur(e)},100)}).on("keydown",function(e){9!=e.keyCode&&w2ui[s.name].keydown.call(w2ui[s.name],e)}),query(this.box).off("mousedown").on("mousedown",function(t){setTimeout(()=>{var e;-1==["INPUT","TEXTAREA","SELECT"].indexOf(t.target.tagName.toUpperCase())&&(e=query(s.box).find("#sidebar_"+s.name+"_focus"),document.activeElement!=e.get(0))&&e.get(0).focus()},1)}),this.last.observeResize=new ResizeObserver(()=>{this.resize()}),this.last.observeResize.observe(this.box),l.finish(),this.refresh(),Date.now()-i}}update(e,t){var i,s,e=this.get(e);let l;return e&&(i=query(this.box).find("#node_"+w2utils.escapeId(e.id)),e.group?(t.text&&(e.text=t.text,i.find(".w2ui-group-text").replace("function"==typeof e.text?e.text.call(this,e):''+e.text+""),delete t.text),t.class&&(e.class=t.class,l=i.data("level"),i.get(0).className="w2ui-node-group w2ui-level-"+l+(e.class?" "+e.class:""),delete t.class),t.style&&(e.style=t.style,i.get(0).nextElementSibling.style=e.style+";"+(!e.hidden&&e.expanded?"":"display: none;"),delete t.style)):(t.icon&&0<(s=i.find(".w2ui-node-image > span")).length&&(e.icon=t.icon,s[0].className="function"==typeof e.icon?e.icon.call(this,e):e.icon,delete t.icon),t.count&&(e.count=t.count,i.find(".w2ui-node-count").html(e.count),0`),null!=l||""===this.topHTML&&""===e||(query(this.box).find(".w2ui-sidebar-top").html(this.topHTML+e),query(this.box).find(".w2ui-sidebar-body").css("top",query(this.box).find(".w2ui-sidebar-top").get(0)?.clientHeight+"px"),query(this.box).find(".w2ui-flat").off("click").on("click",e=>{this.goFlat()})),null!=l&&""!==this.bottomHTML&&(query(this.box).find(".w2ui-sidebar-bottom").html(this.bottomHTML),query(this.box).find(".w2ui-sidebar-body").css("bottom",query(this.box).find(".w2ui-sidebar-bottom").get(0)?.clientHeight+"px")),query(this.box).find(":scope > div").removeClass("w2ui-sidebar-flat").addClass(this.flat?"w2ui-sidebar-flat":"").css({width:query(this.box).get(0)?.clientWidth+"px",height:query(this.box).get(0)?.clientHeight+"px"}),0'),query(this.box).find(o).remove(),query(this.box).find(i).remove(),query(this.box).find("#sidebar_"+this.name+"_tmp").before(s),query(this.box).find("#sidebar_"+this.name+"_tmp").remove());var l=query(this.box).find(":scope > div").get(0),d={top:l?.scrollTop,left:l?.scrollLeft};query(this.box).find(i).html("");for(let e=0;e ",t),t.text=t.caption),Array.isArray(t.nodes)&&0${e}
    `),i=` +
    + ${t.groupShowHide&&t.collapsible?`${!t.hidden&&t.expanded?w2utils.lang("Hide"):w2utils.lang("Show")}`:""} ${e} +
    +
    +
    `,h.flat&&(i=` +
     
    +
    `)}else{t.selected&&!t.disabled&&(h.selected=t.id),l="",s&&(l=` +
    + +
    `);let e="";var a=null!=t.count?`
    + ${t.count} +
    `:"",n=(!0===t.collapsible&&(e=`
    `),w2utils.lang("function"==typeof t.text?t.text.call(h,t):t.text)),o=["w2ui-node","w2ui-level-"+r,"w2ui-eaction"];t.selected&&o.push("w2ui-selected"),t.disabled&&o.push("w2ui-disabled"),t.class&&o.push(t.class),i=` +
    + ${h.handle.html?`
    + ${"function"==typeof h.handle.html?h.handle.html.call(h,t):h.handle.html} +
    `:""} +
    + ${e} ${l} ${a} +
    ${n}
    +
    +
    +
    `,h.flat&&(i=` +
    +
    ${l}
    +
    +
    `)}return i}}}}mouseAction(e,t,i,s,l){var r=this.get(i),a=w2utils.lang("function"==typeof r.text?r.text.call(this,r):r.text)+(r.count||0===r.count?' - '+r.count+"":""),e=this.trigger("mouse"+e,{target:i,node:r,tooltip:a,originalEvent:s});"tooltip"==l&&this.tooltip(t,a,i),"handle"==l&&this.handleTooltip(t,i),e.finish()}tooltip(e,t,i){e=query(e).find(".w2ui-node-data");""!==t?w2tooltip.show({anchor:e.get(0),name:this.name+"_tooltip",html:t,position:"right|left"}):w2tooltip.hide(this.name+"_tooltip")}handleTooltip(e,t){let i=this.handle.tooltip;""!==(i="function"==typeof i?i(t):i)&&null!=t?w2tooltip.show({anchor:e,name:this.name+"_tooltip",html:i,position:"top|bottom"}):w2tooltip.hide(this.name+"_tooltip")}showPlus(e,t){query(e).find("span:nth-child(1)").css("color",t)}resize(){var e,t=Date.now(),i=this.trigger("resize",{target:this.name});if(!0!==i.isCancelled)return e=query(this.box).get(0).getBoundingClientRect(),query(this.box).css("overflow","hidden"),query(this.box).find(":scope > div").css({width:e.width+"px",height:e.height+"px"}),i.finish(),Date.now()-t}destroy(){var e=this.trigger("destroy",{target:this.name});!0!==e.isCancelled&&(0{var t,i;null==e.id?console.log(`ERROR: The parameter "id" is required but not supplied. (obj: ${this.name})`):w2utils.checkUniqueId(e.id,this.tabs,"tabs",this.name)&&(e=Object.assign({},this.tab_template,e),null==s?(this.tabs.push(e),l.push(this.animateInsert(null,e))):(t=this.get(s,!0),i=this.tabs[t].id,this.tabs.splice(t,0,e),l.push(this.animateInsert(i,e))))}),Promise.all(l)}remove(){let t=0;return Array.from(arguments).forEach(e=>{e=this.get(e);e&&(t++,this.tabs.splice(this.get(e.id,!0),1),query(this.box).find(`#tabs_${this.name}_tab_`+w2utils.escapeId(e.id)).remove())}),this.resize(),t}select(e){return this.active!=e&&null!=this.get(e)&&(this.active=e,this.refresh(),!0)}set(e,t){var i=this.get(e,!0);return null!=i&&(w2utils.extend(this.tabs[i],t),this.refresh(e),!0)}get(t,i){if(0===arguments.length){var s=[];for(let e=0;e{e=this.get(e);e&&!1!==e.hidden&&(e.hidden=!1,t.push(e.id))}),setTimeout(()=>{t.forEach(e=>{this.refresh(e),this.resize()})},15),t}hide(){let t=[];return Array.from(arguments).forEach(e=>{e=this.get(e);e&&!0!==e.hidden&&(e.hidden=!0,t.push(e.id))}),setTimeout(()=>{t.forEach(e=>{this.refresh(e),this.resize()})},15),t}enable(){let t=[];return Array.from(arguments).forEach(e=>{e=this.get(e);e&&!1!==e.disabled&&(e.disabled=!1,t.push(e.id))}),setTimeout(()=>{t.forEach(e=>{this.refresh(e)})},15),t}disable(){let t=[];return Array.from(arguments).forEach(e=>{e=this.get(e);e&&!0!==e.disabled&&(e.disabled=!0,t.push(e.id))}),setTimeout(()=>{t.forEach(e=>{this.refresh(e)})},15),t}dragMove(i){if(this.last.reordering){let s=this;var l=this.last.moving,r=this.tabs[l.index],a=h(l.index,1),n=h(l.index,-1),r=query(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(r.id));if(0t)return a=this.tabs.indexOf(a),this.tabs.splice(l.index,0,this.tabs.splice(a,1)[0]),l.$tab.before(o.get(0)),l.$tab.css("opacity",0),void Object.assign(this.last.moving,{index:a,divX:-e,x:i.pageX+e,left:l.left+l.divX+e})}if(l.divX<0&&n){o=query(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(n.id));let e=parseInt(r.get(0).clientWidth),t=parseInt(o.get(0).clientWidth);e=et&&(a=this.tabs.indexOf(n),this.tabs.splice(l.index,0,this.tabs.splice(a,1)[0]),o.before(l.$tab),l.$tab.css("opacity",0),Object.assign(l,{index:a,divX:e,x:i.pageX-e,left:l.left+l.divX-e}))}function h(e,t){e+=t;let i=s.tabs[e];return i=i&&i.hidden?h(e,t):i}}}mouseAction(e,t,i){var s=this.get(t),l=this.trigger("mouse"+e,{target:t,tab:s,object:s,originalEvent:i});if(!0!==l.isCancelled&&!s.disabled&&!s.hidden){switch(e){case"Enter":this.tooltipShow(t);break;case"Leave":this.tooltipHide(t);break;case"Down":this.initReorder(t,i)}l.finish()}}tooltipShow(t){var i=this.get(t),t=query(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(t)).get(0);if(null!=this.tooltip&&!i.disabled&&!this.last.reordering){var s=this.tooltip;let e=i.tooltip;"function"==typeof e&&(e=e.call(this,i)),w2tooltip.show({anchor:t,name:this.name+"_tooltip",html:e,position:s})}}tooltipHide(e){null!=this.tooltip&&w2tooltip.hide(this.name+"_tooltip")}getTabHTML(e){e=this.get(e,!0),e=this.tabs[e];if(null==e)return!1;null==e.text&&null!=e.caption&&(e.text=e.caption),null==e.tooltip&&null!=e.hint&&(e.tooltip=e.hint),null!=e.caption&&console.log("NOTICE: tabs tab.caption property is deprecated, please use tab.text. Tab -> ",e),null!=e.hint&&console.log("NOTICE: tabs tab.hint property is deprecated, please use tab.tooltip. Tab -> ",e);let t=e.text,i=(null==(t="function"==typeof t?t.call(this,e):t)&&(t=""),""),s="";return e.hidden&&(s+="display: none;"),e.disabled&&(s+="opacity: 0.2;"),e.closable&&!e.disabled&&(i=`
    +
    `),` +
    + ${w2utils.lang(t)+i} +
    `}refresh(e){var t=Date.now(),i=("up"==this.flow?query(this.box).addClass("w2ui-tabs-up"):query(this.box).removeClass("w2ui-tabs-up"),this.trigger("refresh",{target:null!=e?e:this.name,object:this.get(e)}));if(!0!==i.isCancelled){if(null==e)for(let e=0;e +
    +
    ${this.right}
    +
    +
    +
    `,query(this.box).attr("name",this.name).addClass("w2ui-reset w2ui-tabs").html(e),0{this.resize()}),this.last.observeResize.observe(this.box),i.finish(),this.refresh(),this.resize(),Date.now()-t)}initReorder(e,a){if(this.reorder){let t=this,i=query(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(e)),s=this.get(e,!0),l=query(i.get(0).cloneNode(!0)),r;l.attr("id","#tabs_"+this.name+"_tab_ghost"),this.last.moving={index:s,indexFrom:s,$tab:i,$ghost:l,divX:0,left:i.get(0).getBoundingClientRect().left,parentX:query(this.box).get(0).getBoundingClientRect().left,x:a.pageX,opacity:i.css("opacity")},query(document).off(".w2uiTabReorder").on("mousemove.w2uiTabReorder",function(e){if(!t.last.reordering){if(!0===(r=t.trigger("reorder",{target:t.tabs[s].id,indexFrom:s,tab:t.tabs[s]})).isCancelled)return;w2tooltip.hide(this.name+"_tooltip"),t.last.reordering=!0,l.addClass("moving"),l.css({"pointer-events":"none",position:"absolute",left:i.get(0).getBoundingClientRect().left}),i.css("opacity",0),query(t.box).find(".w2ui-scroll-wrapper").append(l.get(0)),query(t.box).find(".w2ui-tab-close").hide()}t.last.moving.divX=e.pageX-t.last.moving.x,l.css("left",t.last.moving.left-t.last.moving.parentX+t.last.moving.divX+"px"),t.dragMove(e)}).on("mouseup.w2uiTabReorder",function(){query(document).off(".w2uiTabReorder"),l.css({transition:"0.1s",left:t.last.moving.$tab.get(0).getBoundingClientRect().left-t.last.moving.parentX}),query(t.box).find(".w2ui-tab-close").show(),setTimeout(()=>{l.remove(),i.css({opacity:t.last.moving.opacity}),t.last.reordering&&r.finish({indexTo:t.last.moving.index}),t.last.reordering=!1},100)})}}scroll(n,o){return new Promise((e,t)=>{var i=query(this.box).find(".w2ui-scroll-wrapper"),s=i.get(0).scrollLeft,l=i.find(".w2ui-tabs-right").get(0),r=i.parent().get(0).getBoundingClientRect().width,a=s+parseInt(l.offsetLeft)+parseInt(l.clientWidth);switch(n){case"left":{let e=s-r+50;e<=0&&(e=0),i.get(0).scrollTo({top:0,left:e,behavior:o?"atuo":"smooth"});break}case"right":{let e=s+r-50;e>=a-r&&(e=a-r),i.get(0).scrollTo({top:0,left:e,behavior:o?"atuo":"smooth"});break}}setTimeout(()=>{this.resize(),e()},o?0:350)})}scrollIntoView(i,s){return new Promise((e,t)=>{null==i&&(i=this.active),null!=this.get(i)&&(query(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(i)).get(0).scrollIntoView({block:"start",inline:"center",behavior:s?"atuo":"smooth"}),setTimeout(()=>{this.resize(),e()},s?0:500))})}resize(){var e=Date.now();if(null!=this.box){var t,i,s,l,r=this.trigger("resize",{target:this.name});if(!0!==r.isCancelled)return(t=query(this.box)).find(".w2ui-scroll-left, .w2ui-scroll-right").hide(),i=t.find(".w2ui-scroll-wrapper").get(0),l=t.find(".w2ui-tabs-right"),(s=t.get(0).getBoundingClientRect().width)<(l=0{window.location.hash=t},1)}e.finish()}}clickClose(e,t){var i=this.get(e);if(null==i||i.disabled)return!1;let s=this.trigger("close",{target:e,object:i,tab:i,originalEvent:t});!0!==s.isCancelled&&(this.animateClose(e).then(()=>{this.remove(e),s.finish(),this.refresh()}),t)&&t.stopPropagation()}animateClose(r){return new Promise((e,t)=>{var i=query(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(r)),s=parseInt(i.get(0).clientWidth||0);let l=i.replace(`
    `);setTimeout(()=>{l.css({width:"0px"})},1),setTimeout(()=>{l.remove(),this.resize(),e()},500)})}animateInsert(t,r){return new Promise((i,e)=>{let s=query(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(t)),l=query.html(this.getTabHTML(r.id));if(0==s.length)(s=query(this.box).find("#tabs_tabs_right")).before(l),this.resize();else{l.css({opacity:0}),query(this.box).find("#tabs_tabs_right").before(l.get(0));let e=query(this.box).find("#"+l.attr("id")).get(0).clientWidth??0,t=query.html('
    ');s.before(t),l.hide(),t.before(l[0]),setTimeout(()=>{t.css({width:e+"px"})},1),setTimeout(()=>{t.remove(),l.css({opacity:1}).show(),this.refresh(r.id),this.resize(),i()},500)}})}}let w2panels=["top","left","main","preview","right","bottom"];class w2layout extends w2base{constructor(e){super(e.name),this.box=null,this.name=null,this.panels=[],this.last={},this.padding=1,this.resizer=4,this.style="",this.onShow=null,this.onHide=null,this.onResizing=null,this.onResizerClick=null,this.onRender=null,this.onRefresh=null,this.onChange=null,this.onResize=null,this.onDestroy=null,this.panel_template={type:null,title:"",size:100,minSize:20,maxSize:!1,hidden:!1,resizable:!1,overflow:"auto",style:"",html:"",tabs:null,toolbar:null,width:null,height:null,show:{toolbar:!1,tabs:!1},removed:null,onRefresh:null,onShow:null,onHide:null},Object.assign(this,e),Array.isArray(this.panels)||(this.panels=[]),this.panels.forEach((e,t)=>{var i,s,l;this.panels[t]=w2utils.extend({},this.panel_template,e),(w2utils.isPlainObject(e.tabs)||Array.isArray(e.tabs))&&function(e,t,i){var s=e.get(t);null!=s&&null==i&&(i=s.tabs);if(null==s||null==i)return;Array.isArray(i)&&(i={tabs:i});var l=e.name+"_"+t+"_tabs";w2ui[l]&&w2ui[l].destroy();s.tabs=new w2tabs(w2utils.extend({},i,{owner:e,name:e.name+"_"+t+"_tabs"})),s.show.tabs=!0}(this,e.type),(w2utils.isPlainObject(e.toolbar)||Array.isArray(e.toolbar))&&(t=this,e=e.type,i=void 0,null!=(s=t.get(e))&&null==i&&(i=s.toolbar),null!=s)&&null!=i&&(Array.isArray(i)&&(i={items:i}),l=t.name+"_"+e+"_toolbar",w2ui[l]&&w2ui[l].destroy(),s.toolbar=new w2toolbar(w2utils.extend({},i,{owner:t,name:t.name+"_"+e+"_toolbar"})),s.show.toolbar=!0)}),w2panels.forEach(e=>{null==this.get(e)&&this.panels.push(w2utils.extend({},this.panel_template,{type:e,hidden:"main"!==e,size:50}))}),"string"==typeof this.box&&(this.box=query(this.box).get(0)),this.box&&this.render(this.box)}html(l,r,a){let n=this.get(l);var e={panel:l,html:n.html,error:!1,cancelled:!1,removed(e){"function"==typeof e&&(n.removed=e)}};if("function"==typeof n.removed&&(n.removed({panel:l,html:n.html,html_new:r,transition:a||"none"}),n.removed=null),"css"==l)query(this.box).find("#layout_"+this.name+"_panel_css").html(""),e.status=!0;else if(null==n)console.log("ERROR: incorrect panel name. Panel name can be main, left, right, top, bottom, preview or css"),e.error=!0;else if(null!=r){var t=this.trigger("change",{target:l,panel:n,html_new:r,transition:a});if(!0===t.isCancelled)e.cancelled=!0;else{let i="#layout_"+this.name+"_panel_"+n.type;var o=query(this.box).find(i+"> .w2ui-panel-content");let s=0;if(0 .w2ui-panel-content"),t=(e.after('
    '),query(this.box).find(i+"> .w2ui-panel-content.new-panel"));e.css("top",s),t.css("top",s),"object"==typeof r?(r.box=t[0],r.render()):t.hide().html(r),w2utils.transition(e[0],t[0],a,()=>{e.remove(),t.removeClass("new-panel"),t.css("overflow",n.overflow),query(query(this.box).find(i+"> .w2ui-panel-content").get(1)).remove(),query(this.box).removeClass("animating"),this.refresh(l)})}else this.refresh(l);t.finish()}}return e}message(e,t){var i=this.get(e);let s=query(this.box).find("#layout_"+this.name+"_panel_"+i.type),l=s.css("overflow");s.css("overflow","hidden");i=w2utils.message({owner:this,box:s.get(0),after:".w2ui-panel-title",param:e},t);return i&&i.self.on("close:after",()=>{s.css("overflow",l)}),i}confirm(e,t){var i=this.get(e);let s=query(this.box).find("#layout_"+this.name+"_panel_"+i.type),l=s.css("overflow");s.css("overflow","hidden");i=w2utils.confirm({owner:this,box:s.get(0),after:".w2ui-panel-title",param:e},t);return i&&i.self.on("close:after",()=>{s.css("overflow",l)}),i}load(i,s,l){return new Promise((t,e)=>{"css"!=i&&null==this.get(i)||null==s?e():fetch(s).then(e=>e.text()).then(e=>{this.resize(),t(this.html(i,e,l))})})}sizeTo(e,t,i){return null!=this.get(e)&&(query(this.box).find(":scope > div > .w2ui-panel").css("transition",!0!==i?".2s":"0s"),setTimeout(()=>{this.set(e,{size:t})},1),setTimeout(()=>{query(this.box).find(":scope > div > .w2ui-panel").css("transition","0s"),this.resize()},300),!0)}show(e,t){let i=this.trigger("show",{target:e,thisect:this.get(e),immediate:t});var s;if(!0!==i.isCancelled)return null!=(s=this.get(e))&&(!(s.hidden=!1)===t?(query(this.box).find("#layout_"+this.name+"_panel_"+e).css({opacity:"1"}),i.finish(),this.resize()):(query(this.box).addClass("animating"),query(this.box).find("#layout_"+this.name+"_panel_"+e).css({opacity:"0"}),query(this.box).find(":scope > div > .w2ui-panel").css("transition",".2s"),setTimeout(()=>{this.resize()},1),setTimeout(()=>{query(this.box).find("#layout_"+this.name+"_panel_"+e).css({opacity:"1"})},250),setTimeout(()=>{query(this.box).find(":scope > div > .w2ui-panel").css("transition","0s"),query(this.box).removeClass("animating"),i.finish(),this.resize()},300)),!0)}hide(e,t){let i=this.trigger("hide",{target:e,object:this.get(e),immediate:t});var s;if(!0!==i.isCancelled)return null!=(s=this.get(e))&&((s.hidden=!0)===t?(query(this.box).find("#layout_"+this.name+"_panel_"+e).css({opacity:"0"}),i.finish(),this.resize()):(query(this.box).addClass("animating"),query(this.box).find(":scope > div > .w2ui-panel").css("transition",".2s"),query(this.box).find("#layout_"+this.name+"_panel_"+e).css({opacity:"0"}),setTimeout(()=>{this.resize()},1),setTimeout(()=>{query(this.box).find(":scope > div > .w2ui-panel").css("transition","0s"),query(this.box).removeClass("animating"),i.finish(),this.resize()},300)),!0)}toggle(e,t){var i=this.get(e);return null!=i&&(i.hidden?this.show(e,t):this.hide(e,t))}set(e,t){var i=this.get(e,!0);return null!=i&&(w2utils.extend(this.panels[i],t),null==t.html&&null==t.resizable||this.refresh(e),this.resize(),!0)}get(t,i){for(let e=0;e .w2ui-panel-content");return 1!=e.length?null:e[0]}hideToolbar(e){var t=this.get(e);t&&(t.show.toolbar=!1,query(this.box).find("#layout_"+this.name+"_panel_"+e+"> .w2ui-panel-toolbar").hide(),this.resize())}showToolbar(e){var t=this.get(e);t&&(t.show.toolbar=!0,query(this.box).find("#layout_"+this.name+"_panel_"+e+"> .w2ui-panel-toolbar").show(),this.resize())}toggleToolbar(e){var t=this.get(e);t&&(t.show.toolbar?this.hideToolbar(e):this.showToolbar(e))}assignToolbar(e,t){"string"==typeof t&&null!=w2ui[t]&&(t=w2ui[t]);var i=this.get(e),s=(i.toolbar=t,query(this.box).find(e+"> .w2ui-panel-toolbar"));null!=i.toolbar?(0===s.find("[name="+i.toolbar.name+"]").length?i.toolbar.render(s.get(0)):null!=i.toolbar&&i.toolbar.refresh(),(t.owner=this).showToolbar(e),this.refresh(e)):(s.html(""),this.hideToolbar(e))}hideTabs(e){var t=this.get(e);t&&(t.show.tabs=!1,query(this.box).find("#layout_"+this.name+"_panel_"+e+"> .w2ui-panel-tabs").hide(),this.resize())}showTabs(e){var t=this.get(e);t&&(t.show.tabs=!0,query(this.box).find("#layout_"+this.name+"_panel_"+e+"> .w2ui-panel-tabs").show(),this.resize())}toggleTabs(e){var t=this.get(e);t&&(t.show.tabs?this.hideTabs(e):this.showTabs(e))}render(e){var t=Date.now();let o=this;"string"==typeof e&&(e=query(e).get(0));var i=this.trigger("render",{target:this.name,box:e??this.box});if(!0!==i.isCancelled){if(null!=e&&(0"),0
    ';query(this.box).find(":scope > div").append(s)}return query(this.box).find(":scope > div").append('
    '),this.refresh(),this.last.observeResize=new ResizeObserver(()=>{this.resize()}),this.last.observeResize.observe(this.box),i.finish(),setTimeout(()=>{o.last.events={resizeStart:l,mouseMove:a,mouseUp:r},this.resize()},0),Date.now()-t}function l(e,t){o.box&&(t=t||window.event,query(document).off("mousemove",o.last.events.mouseMove).on("mousemove",o.last.events.mouseMove),query(document).off("mouseup",o.last.events.mouseUp).on("mouseup",o.last.events.mouseUp),o.last.resize={type:e,x:t.screenX,y:t.screenY,diff_x:0,diff_y:0,value:0},w2panels.forEach(e=>{var t=query(o.el(e)).find(".w2ui-lock");0{var t=query(o.el(e)).find(".w2ui-lock");"yes"==t.data("locked")?t.removeData("locked"):o.unlock(e)}),0!==o.last.diff_x||0!==o.last.resize.diff_y){var s=o.get("top"),l=o.get("bottom"),r=o.get(o.last.resize.type),i=w2utils.getSize(query(o.box),"width"),a=w2utils.getSize(query(o.box),"height"),n=String(r.size);let e,t;switch(o.last.resize.type){case"top":e=parseInt(r.sizeCalculated)+o.last.resize.diff_y,t=0;break;case"bottom":e=parseInt(r.sizeCalculated)-o.last.resize.diff_y,t=0;break;case"preview":e=parseInt(r.sizeCalculated)-o.last.resize.diff_y,t=(s&&!s.hidden?s.sizeCalculated:0)+(l&&!l.hidden?l.sizeCalculated:0);break;case"left":e=parseInt(r.sizeCalculated)+o.last.resize.diff_x,t=0;break;case"right":e=parseInt(r.sizeCalculated)-o.last.resize.diff_x,t=0}"%"==n.substr(n.length-1)?r.size=Math.floor(100*e/("left"==r.type||"right"==r.type?i:a-t)*100)/100+"%":"-"==String(r.size).substr(0,1)?r.size=parseInt(r.size)-r.sizeCalculated+e:r.size=e,o.resize()}query(o.box).find("#layout_"+o.name+"_resizer_"+o.last.resize.type).removeClass("active"),delete o.last.resize}}function a(i){if(o.box&&(i=i||window.event,null!=o.last.resize)){var s=o.get(o.last.resize.type),l=o.last.resize,r=o.trigger("resizing",{target:o.name,object:s,originalEvent:i,panel:l?l.type:"all",diff_x:l?l.diff_x:0,diff_y:l?l.diff_y:0});if(!0!==r.isCancelled){var a=query(o.box).find("#layout_"+o.name+"_resizer_"+l.type);let e=i.screenX-l.x,t=i.screenY-l.y;var n=o.get("main");switch(a.hasClass("active")||a.addClass("active"),l.type){case"left":s.minSize-e>s.width&&(e=s.minSize-s.width),s.maxSize&&s.width+e>s.maxSize&&(e=s.maxSize-s.width),n.minSize+e>n.width&&(e=n.width-n.minSize);break;case"right":s.minSize+e>s.width&&(e=s.width-s.minSize),s.maxSize&&s.width-e>s.maxSize&&(e=s.width-s.maxSize),n.minSize-e>n.width&&(e=n.minSize-n.width);break;case"top":s.minSize-t>s.height&&(t=s.minSize-s.height),s.maxSize&&s.height+t>s.maxSize&&(t=s.maxSize-s.height),n.minSize+t>n.height&&(t=n.height-n.minSize);break;case"preview":case"bottom":s.minSize+t>s.height&&(t=s.height-s.minSize),s.maxSize&&s.height-t>s.maxSize&&(t=s.height-s.maxSize),n.minSize-t>n.height&&(t=n.minSize-n.height)}switch(l.diff_x=e,l.diff_y=t,l.type){case"top":case"preview":case"bottom":(l.diff_x=0) .w2ui-panel-content")[0],setTimeout(()=>{0 .w2ui-panel-content").length&&(query(l.box).find(t+"> .w2ui-panel-content").removeClass().removeAttr("name").addClass("w2ui-panel-content").css("overflow",e.overflow)[0].style.cssText+=";"+e.style),e.html&&"function"==typeof e.html.render&&e.html.render()},1)):0 .w2ui-panel-content").length&&(query(l.box).find(t+"> .w2ui-panel-content").removeClass().removeAttr("name").addClass("w2ui-panel-content").html(e.html).css("overflow",e.overflow)[0].style.cssText+=";"+e.style);let i=query(l.box).find(t+"> .w2ui-panel-tabs");e.show.tabs?0===i.find("[name="+e.tabs.name+"]").length&&null!=e.tabs?e.tabs.render(i.get(0)):e.tabs.refresh():i.html("").removeClass("w2ui-tabs").hide(),i=query(l.box).find(t+"> .w2ui-panel-toolbar"),e.show.toolbar?0===i.find("[name="+e.toolbar.name+"]").length&&null!=e.toolbar?e.toolbar.render(i.get(0)):e.toolbar.refresh():i.html("").removeClass("w2ui-toolbar").hide(),i=query(l.box).find(t+"> .w2ui-panel-title"),e.title?i.html(e.title).show():i.html("").hide()}else{if(0===query(l.box).find("#layout_"+l.name+"_panel_main").length)return void l.render();l.resize();for(let e=0;ethis.padding?this.resizer:this.padding,query(this.box).find("#layout_"+this.name+"_resizer_top").css({display:"block",left:e+"px",top:t+"px",width:s+"px",height:l+"px",cursor:"ns-resize"}).off("mousedown").on("mousedown",function(e){e.preventDefault();var t=i.trigger("resizerClick",{target:"top",originalEvent:e});if(!0!==t.isCancelled)return w2ui[i.name].last.events.resizeStart("top",e),t.finish(),!1}))):(query(this.box).find("#layout_"+this.name+"_panel_top").hide(),query(this.box).find("#layout_"+this.name+"_resizer_top").hide()),null!=c&&!0!==c.hidden?(e=0,t=0+(b?f.sizeCalculated+this.padding:0),s=c.sizeCalculated,l=h-(b?f.sizeCalculated+this.padding:0)-(v?m.sizeCalculated+this.padding:0),query(this.box).find("#layout_"+this.name+"_panel_left").css({display:"block",left:e+"px",top:t+"px",width:s+"px",height:l+"px"}),c.width=s,c.height=l,c.resizable&&(e=c.sizeCalculated-(0===this.padding?this.resizer:0),s=this.resizer>this.padding?this.resizer:this.padding,query(this.box).find("#layout_"+this.name+"_resizer_left").css({display:"block",left:e+"px",top:t+"px",width:s+"px",height:l+"px",cursor:"ew-resize"}).off("mousedown").on("mousedown",function(e){e.preventDefault();var t=i.trigger("resizerClick",{target:"left",originalEvent:e});if(!0!==t.isCancelled)return w2ui[i.name].last.events.resizeStart("left",e),t.finish(),!1}))):(query(this.box).find("#layout_"+this.name+"_panel_left").hide(),query(this.box).find("#layout_"+this.name+"_resizer_left").hide()),null!=p&&!0!==p.hidden?(e=o-p.sizeCalculated,t=0+(b?f.sizeCalculated+this.padding:0),s=p.sizeCalculated,l=h-(b?f.sizeCalculated+this.padding:0)-(v?m.sizeCalculated+this.padding:0),query(this.box).find("#layout_"+this.name+"_panel_right").css({display:"block",left:e+"px",top:t+"px",width:s+"px",height:l+"px"}),p.width=s,p.height=l,p.resizable&&(e-=this.padding,s=this.resizer>this.padding?this.resizer:this.padding,query(this.box).find("#layout_"+this.name+"_resizer_right").css({display:"block",left:e+"px",top:t+"px",width:s+"px",height:l+"px",cursor:"ew-resize"}).off("mousedown").on("mousedown",function(e){e.preventDefault();var t=i.trigger("resizerClick",{target:"right",originalEvent:e});if(!0!==t.isCancelled)return w2ui[i.name].last.events.resizeStart("right",e),t.finish(),!1}))):(query(this.box).find("#layout_"+this.name+"_panel_right").hide(),query(this.box).find("#layout_"+this.name+"_resizer_right").hide()),null!=m&&!0!==m.hidden?(e=0,t=h-m.sizeCalculated,s=o,l=m.sizeCalculated,query(this.box).find("#layout_"+this.name+"_panel_bottom").css({display:"block",left:e+"px",top:t+"px",width:s+"px",height:l+"px"}),m.width=s,m.height=l,m.resizable&&(t-=0===this.padding?0:this.padding,l=this.resizer>this.padding?this.resizer:this.padding,query(this.box).find("#layout_"+this.name+"_resizer_bottom").css({display:"block",left:e+"px",top:t+"px",width:s+"px",height:l+"px",cursor:"ns-resize"}).off("mousedown").on("mousedown",function(e){e.preventDefault();var t=i.trigger("resizerClick",{target:"bottom",originalEvent:e});if(!0!==t.isCancelled)return w2ui[i.name].last.events.resizeStart("bottom",e),t.finish(),!1}))):(query(this.box).find("#layout_"+this.name+"_panel_bottom").hide(),query(this.box).find("#layout_"+this.name+"_resizer_bottom").hide()),e=0+(y?c.sizeCalculated+this.padding:0),t=0+(b?f.sizeCalculated+this.padding:0),s=o-(y?c.sizeCalculated+this.padding:0)-(w?p.sizeCalculated+this.padding:0),l=h-(b?f.sizeCalculated+this.padding:0)-(v?m.sizeCalculated+this.padding:0)-(g?u.sizeCalculated+this.padding:0),query(this.box).find("#layout_"+this.name+"_panel_main").css({display:"block",left:e+"px",top:t+"px",width:s+"px",height:l+"px"}),d.width=s,d.height=l,null!=u&&!0!==u.hidden?(e=0+(y?c.sizeCalculated+this.padding:0),t=h-(v?m.sizeCalculated+this.padding:0)-u.sizeCalculated,s=o-(y?c.sizeCalculated+this.padding:0)-(w?p.sizeCalculated+this.padding:0),l=u.sizeCalculated,query(this.box).find("#layout_"+this.name+"_panel_preview").css({display:"block",left:e+"px",top:t+"px",width:s+"px",height:l+"px"}),u.width=s,u.height=l,u.resizable&&(t-=0===this.padding?0:this.padding,l=this.resizer>this.padding?this.resizer:this.padding,query(this.box).find("#layout_"+this.name+"_resizer_preview").css({display:"block",left:e+"px",top:t+"px",width:s+"px",height:l+"px",cursor:"ns-resize"}).off("mousedown").on("mousedown",function(e){e.preventDefault();var t=i.trigger("resizerClick",{target:"preview",originalEvent:e});if(!0!==t.isCancelled)return w2ui[i.name].last.events.resizeStart("preview",e),t.finish(),!1}))):(query(this.box).find("#layout_"+this.name+"_panel_preview").hide(),query(this.box).find("#layout_"+this.name+"_resizer_preview").hide());for(let t=0;t .w2ui-panel-";let e=0;q&&(q.title&&(_=query(this.box).find(C+"title").css({top:e+"px",display:"block"}),e+=w2utils.getSize(_,"height")),q.show.tabs&&(_=query(this.box).find(C+"tabs").css({top:e+"px",display:"block"}),e+=w2utils.getSize(_,"height")),q.show.toolbar)&&(q=query(this.box).find(C+"toolbar").css({top:e+"px",display:"block"}),e+=w2utils.getSize(q,"height")),query(this.box).find(C+"content").css({display:"block"}).css({top:e+"px"})}return n.finish(),Date.now()-r}}destroy(){var e=this.trigger("destroy",{target:this.name});if(!0!==e.isCancelled)return null!=w2ui[this.name]&&(0'},add:{type:"button",id:"w2ui-add",text:"Add New",tooltip:"Add new record",icon:"w2ui-icon-plus"},edit:{type:"button",id:"w2ui-edit",text:"Edit",tooltip:"Edit selected record",icon:"w2ui-icon-pencil",batch:1,disabled:!0},delete:{type:"button",id:"w2ui-delete",text:"Delete",tooltip:"Delete selected records",icon:"w2ui-icon-cross",batch:!0,disabled:!0},save:{type:"button",id:"w2ui-save",text:"Save",tooltip:"Save changed records",icon:"w2ui-icon-check"}},this.operators={text:["is","begins","contains","ends"],number:["=","between",">","<",">=","<="],date:["is",{oper:"less",text:"before"},{oper:"more",text:"since"},"between"],list:["is"],hex:["is","between"],color:["is","begins","contains","ends"],enum:["in","not in"]},this.defaultOperator={text:"begins",number:"=",date:"is",list:"is",enum:"in",hex:"begins",color:"begins"},this.operatorsMap={text:"text",int:"number",float:"number",money:"number",currency:"number",percent:"number",hex:"hex",alphanumeric:"text",color:"color",date:"date",time:"date",datetime:"date",list:"list",combo:"text",enum:"enum",file:"enum",select:"list",radio:"list",checkbox:"list",toggle:"list"},this.onAdd=null,this.onEdit=null,this.onRequest=null,this.onLoad=null,this.onDelete=null,this.onSave=null,this.onSelect=null,this.onClick=null,this.onDblClick=null,this.onContextMenu=null,this.onContextMenuClick=null,this.onColumnClick=null,this.onColumnDblClick=null,this.onColumnContextMenu=null,this.onColumnResize=null,this.onColumnAutoResize=null,this.onSort=null,this.onSearch=null,this.onSearchOpen=null,this.onChange=null,this.onRestore=null,this.onExpand=null,this.onCollapse=null,this.onError=null,this.onKeydown=null,this.onToolbar=null,this.onColumnOnOff=null,this.onCopy=null,this.onPaste=null,this.onSelectionExtend=null,this.onEditField=null,this.onRender=null,this.onRefresh=null,this.onReload=null,this.onResize=null,this.onDestroy=null,this.onStateSave=null,this.onStateRestore=null,this.onFocus=null,this.onBlur=null,this.onReorderRow=null,this.onSearchSave=null,this.onSearchRemove=null,this.onSearchSelect=null,this.onColumnSelect=null,this.onColumnDragStart=null,this.onColumnDragEnd=null,this.onResizerDblClick=null,this.onMouseEnter=null,this.onMouseLeave=null,w2utils.extend(this,e),Array.isArray(this.records)){let i=[];this.records.forEach((e,t)=>{null!=e[this.recid]&&(e.recid=e[this.recid]),null==e.recid&&console.log("ERROR: Cannot add records without recid. (obj: "+this.name+")"),!0===e.w2ui?.summary&&(this.summary.push(e),i.push(t))}),i.sort();for(let e=i.length-1;0<=e;e--)this.records.splice(i[e],1)}Array.isArray(this.columns)&&this.columns.forEach((i,e)=>{i=w2utils.extend({},this.colTemplate,i);e=(this.columns[e]=i).searchable;if(null!=e&&!1!==e&&null==this.getSearch(i.field))if(w2utils.isPlainObject(e))this.addSearch(w2utils.extend({field:i.field,label:i.text,type:"text"},e));else{let e=i.searchable,t="";!0===i.searchable&&(e="text",t='size="20"'),this.addSearch({field:i.field,label:i.text,type:e,attr:t})}}),Array.isArray(this.defaultSearches)&&this.defaultSearches.forEach((e,t)=>{e.id="default-"+t,e.icon??="w2ui-icon-search"});e=this.cache("searches");Array.isArray(e)&&e.forEach(e=>{this.savedSearches.push({id:e.id??"none",text:e.text??"none",icon:"w2ui-icon-search",remove:!0,logic:e.logic??"AND",data:e.data??[]})}),"string"==typeof this.box&&(this.box=query(this.box).get(0)),this.box&&this.render(this.box)}add(t,i){Array.isArray(t)||(t=[t]);let s=0;for(let e=0;ethis.records.length&&(n=this.records.length);for(let i=a;i{this.columns.forEach(i=>{if(i.field==e){let t=w2utils.clone(s);Object.keys(t).forEach(e=>{"function"==typeof t[e]&&(t[e]=t[e](i)),i[e]!=t[e]&&l++}),w2utils.extend(i,t)}})}),0{if(!(e.w2ui&&null!=e.w2ui.parent_recid||t.w2ui&&null!=t.w2ui.parent_recid))return o(e,t);var i=a(e),s=a(t);for(let e=0;es.length?1:i.length{this.status(w2utils.lang("Sorting took ${count} seconds",{count:e/1e3}))},10),e;function a(e){var t;return e.w2ui&&null!=e.w2ui.parent_recid?e.w2ui._path||((t=n.get(e.w2ui.parent_recid))?a(t).concat(e):(console.log("ERROR: no parent record: "+e.w2ui.parent_recid),[e])):[e]}function o(s,l){if(s===l)return 0;for(let i=0;it.constructor.name?s:-s;e&&"object"==typeof e&&(e=e.valueOf()),t&&"object"==typeof t&&(t=t.valueOf());var r={}.toString;switch(e&&"object"==typeof e&&e.toString!=r&&(e=String(e)),t&&"object"==typeof t&&t.toString!=r&&(t=String(t)),"string"==typeof e&&(e=e.toLowerCase().trim()),"string"==typeof t&&(t=t.toLowerCase().trim()),l){case"natural":l=w2utils.naturalCompare;break;case"i18n":l=w2utils.i18nCompare}return"function"==typeof l?l(e,t)*s:t=parseFloat(n)&&parseFloat(c.parseField(l,s.field))<=parseFloat(o)&&r++:"date"==s.type?(h=c.parseField(l,s.field+"_")instanceof Date?c.parseField(l,s.field+"_"):c.parseField(l,s.field),a=w2utils.isDate(h,w2utils.settings.dateFormat,!0),n=w2utils.isDate(n,w2utils.settings.dateFormat,!0),null!=(o=w2utils.isDate(o,w2utils.settings.dateFormat,!0))&&(o=new Date(o.getTime()+864e5)),a>=n&&a=n&&a=n)&&a=":d=!0;case">":case"more":-1!=["int","float","money","currency","percent"].indexOf(s.type)?(a=parseFloat(c.parseField(l,s.field)),n=parseFloat(i.value),(a>n||d&&a===n)&&r++):"date"==s.type?(h=c.parseField(l,s.field+"_")instanceof Date?c.parseField(l,s.field+"_"):c.parseField(l,s.field),a=w2utils.isDate(h,w2utils.settings.dateFormat,!0),n=w2utils.isDate(n,w2utils.settings.dateFormat,!0),(a>n||d&&a===n)&&r++):"time"==s.type?(h=c.parseField(l,s.field+"_")instanceof Date?c.parseField(l,s.field+"_"):c.parseField(l,s.field),a=w2utils.formatTime(h,"hh24:mi"),n=w2utils.formatTime(n,"hh24:mi"),(a>n||d&&a===n)&&r++):"datetime"==s.type&&(h=c.parseField(l,s.field+"_")instanceof Date?c.parseField(l,s.field+"_"):c.parseField(l,s.field),a=w2utils.formatDateTime(h,"yyyy-mm-dd|hh24:mm:ss"),n=w2utils.formatDateTime(w2utils.isDateTime(n,w2utils.settings.datetimeFormat,!0),"yyyy-mm-dd|hh24:mm:ss"),a.length==n.length)&&(a>n||d&&a===n)&&r++;break;case"in":h=i.value,-1===(h=i.svalue?i.svalue:h).indexOf(w2utils.isFloat(t)?parseFloat(t):t)&&-1===h.indexOf(a)||r++;break;case"not in":h=i.value,-1===(h=i.svalue?i.svalue:h).indexOf(w2utils.isFloat(t)?parseFloat(t):t)&&-1===h.indexOf(a)&&r++;break;case"begins":case"begins with":0===a.indexOf(n)&&r++;break;case"contains":0<=a.indexOf(n)&&r++;break;case"null":null==c.parseField(l,s.field)&&r++;break;case"not null":null!=c.parseField(l,s.field)&&r++;break;case"ends":case"ends with":let e=a.lastIndexOf(n);-1!==e&&e==a.length-n.length&&r++}}}if("OR"==c.last.logic&&0!==r||"AND"==c.last.logic&&r==c.searchData.length)return!0;if(l.w2ui?.children&&!0!==l.w2ui?.expanded)for(let t=0;tthis.records.length&&(i=this.records.length-s),0{this.status(w2utils.lang("Search took ${count} seconds",{count:e/1e3}))},10),e}}getRangeData(e,i){var s=this.get(e[0].recid,!0),l=this.get(e[1].recid,!0),r=e[0].column,a=e[1].column,n=[];if(r==a)for(let e=s;e<=l;e++){var t=this.records[e],o=t[this.columns[r].field]||null;n.push(!0!==i?o:{data:o,column:r,index:e,record:t})}else if(s==l){var h=this.records[s];for(let e=r;e<=a;e++){var d=h[this.columns[e].field]||null;n.push(!0!==i?d:{data:d,column:e,index:s,record:h})}}else for(let t=s;t<=l;t++){var u=this.records[t];n.push([]);for(let e=r;e<=a;e++){var c=u[this.columns[e].field];!0!==i?n[n.length-1].push(c):n[n.length-1].push({data:c,column:e,index:t,record:u})}}return n}addRange(s){let e=0,l,r;if("row"!=this.selectType){Array.isArray(s)||(s=[s]);for(let i=0;ithis.last.colStart&&(e=query(this.box).find("#grid_"+this.name+"_rec_"+w2utils.escapeId(u.recid)+' td[col="start"]')),u.columnthis.last.colEnd&&(t=query(this.box).find("#grid_"+this.name+"_rec_"+w2utils.escapeId(c.recid)+' td[col="end"]'),l='"end"');var p=parseInt(query(this.box).find("#grid_"+this.name+"_rec_top").next().attr("index")),f=parseInt(query(this.box).find("#grid_"+this.name+"_rec_bottom").prev().attr("index")),m=parseInt(query(this.box).find("#grid_"+this.name+"_frec_top").next().attr("index")),g=parseInt(query(this.box).find("#grid_"+this.name+"_frec_bottom").prev().attr("index"));0===e.length&&u.indexp&&(e=query(this.box).find("#grid_"+this.name+"_rec_top").next().find('td[col="'+u.column+'"]')),0===t.length&&c.index>f&&u.indexm&&(i=query(this.box).find("#grid_"+this.name+"_frec_top").next().find('td[col="'+u.column+'"]')),0===s.length&&c.index>g&&u.index'+("selection"==d.name?'
    ':"")+""),a=query(this.box).find("#grid_"+this.name+"_f"+d.name)):(a.attr("style",d.style),a.find(".w2ui-selection-resizer").show()),0===s.length&&(0===(s=query(this.box).find("#grid_"+this.name+"_frec_"+w2utils.escapeId(c.recid)+" td:last-child")).length&&(s=query(this.box).find("#grid_"+this.name+"_frec_bottom td:first-child")),a.css("border-right","0px"),a.find(".w2ui-selection-resizer").hide()),null!=u.recid)&&null!=c.recid&&0'+("selection"==d.name?'
    ':"")+""),a=query(this.box).find("#grid_"+this.name+"_"+d.name)):a.attr("style",d.style),0===e.length&&0===(e=query(this.box).find("#grid_"+this.name+"_rec_"+w2utils.escapeId(u.recid)+" td:first-child")).length&&(e=query(this.box).find("#grid_"+this.name+"_rec_top td:first-child")),0!==s.length&&a.css("border-left","0px"),null!=u.recid)&&null!=c.recid&&0{e=this.trigger("resizerDblClick",{target:this.name,originalEvent:e});!0!==e.isCancelled&&e.finish()});let n={target:this.name,originalRange:null,newRange:null};return Date.now()-e;function i(s){var l=r.last.move;if(l&&"expand"==l.type){l.divX=s.screenX-l.x,l.divY=s.screenY-l.y;let e,t,i=s.target;"TD"!=i.tagName.toUpperCase()&&(i=query(i).closest("td")[0]),null!=(t=null!=query(i).attr("col")?parseInt(query(i).attr("col")):t)&&(i=query(i).closest("tr")[0],e=r.records[query(i).attr("index")].recid,l.newRange[1].recid!=e||l.newRange[1].column!=t)&&(s=w2utils.clone(l.newRange),l.newRange=[{recid:l.recid,column:l.column},{recid:e,column:t}],n.detail&&(n.detail.newRange=w2utils.clone(l.newRange),n.detail.originalRange=w2utils.clone(l.originalRange)),!0===(n=r.trigger("selectionExtend",n)).isCancelled?(l.newRange=s,n.detail.newRange=s):(r.removeRange("grid-selection-expand"),r.addRange({name:"grid-selection-expand",range:l.newRange,style:"background-color: rgba(100,100,100,0.1); border: 2px dotted rgba(100,100,100,0.5);"})))}}function s(e){r.removeRange("grid-selection-expand"),delete r.last.move,query("body").off(".w2ui-"+r.name),n.finish&&n.finish()}}}select(){if(0===arguments.length)return 0;let s=0;var l=this.last.selection;this.multiSelect||this.selectNone(!0);let t=Array.from(arguments);Array.isArray(t[0])&&(t=t[0]);var e={target:this.name},e=(1==t.length?(e.multiple=!1,w2utils.isPlainObject(t[0])?e.clicked={recid:t[0].recid,column:t[0].column}:e.recid=t[0]):(e.multiple=!0,e.clicked={recids:t}),this.trigger("select",e));if(!0===e.isCancelled)return 0;if("row"==this.selectType)for(let e=0;e=this.last.range_start&&r+1<=this.last.range_end)&&(e=query(this.box).find("#grid_"+this.name+"_frec_"+w2utils.escapeId(i)),t=query(this.box).find("#grid_"+this.name+"_rec_"+w2utils.escapeId(i))),"row"==this.selectType&&-1==l.indexes.indexOf(r)&&(l.indexes.push(r),e&&t&&(e.addClass("w2ui-selected").find(".w2ui-col-number").addClass("w2ui-row-selected"),t.addClass("w2ui-selected").find(".w2ui-col-number").addClass("w2ui-row-selected"),e.find(".w2ui-grid-select-check").prop("checked",!0)),s++)}}else{var a={};for(let e=0;e=this.last.range_start&&u+1<=this.last.range_end&&(t=query(this.box).find("#grid_"+this.name+"_rec_"+w2utils.escapeId(h)),i=query(this.box).find("#grid_"+this.name+"_frec_"+w2utils.escapeId(h)));var c=l.columns[u]||[];-1==l.indexes.indexOf(u)&&l.indexes.push(u);for(let e=0;ee-t);for(let e=0;ee-t);var f=0 td[col="${h}"]`).removeClass("w2ui-selected w2ui-inactive"),query(this.box).find(`#grid_${this.name}_frec_${w2utils.escapeId(r)} > td[col="${h}"]`).removeClass("w2ui-selected w2ui-inactive");let t=!1,i=!1;var d=this.getSelection();for(let e=0;e{i(t,""),Array.isArray(t.items)&&t.items.forEach(e=>{i(e,t.id+":")})}),this.show.toolbarSave&&(0{this.initSearches(),this.last.search_opened=!0;let t=query(`#w2overlay-${this.name}-search-overlay`);t.data("gridName",this.name).off(".grid-search").on("click.grid-search",()=>{t.find("input, select").each(e=>{e=query(e).data("tooltipName");e&&e.forEach(e=>{w2tooltip.hide(e)})})}),w2utils.bindEvents(t.find("select, input, button"),this);var i=query(`#w2overlay-${this.name}-search-overlay *[rel=search]`);0{t.removeClass("checked"),this.last.search_opened=!1})}}}searchClose(){w2tooltip.hide(this.name+"-search-overlay")}searchFieldTooltip(e,t,i){var e=this.searches[e],s=this.searchData[t];let l=s.operator,r=("less"==(l="more"==l&&"date"==s.type?"since":l)&&"date"==s.type&&(l="before"),""),a=s.value;Array.isArray(s.value)?(s.value.forEach(e=>{r+=`${e.text||e}`}),"date"==s.type&&(r="",s.value.forEach(e=>{r+=`${w2utils.formatDate(e)}`}))):"date"==s.type&&(a=w2utils.formatDateTime(a)),w2tooltip.hide(this.name+"-search-props"),w2tooltip.show({name:this.name+"-search-props",anchor:i,class:"w2ui-white",hideOn:"doc-click",html:` +
    + ${e.label} + ${w2utils.lang(l)} + ${Array.isArray(s.value)?""+r:`${a}`} +
    + +
    +
    `}).then(e=>{query(e.detail.overlay.box).find("#remove").on("click",()=>{this.searchData.splice(""+t,1),this.reload(),this.localSearch(),w2tooltip.hide(this.name+"-search-props")})})}searchSuggest(e,t,i){clearTimeout(this.last.kbd_timer),clearTimeout(this.last.overlay_timer),this.searchShowFields(!0),this.searchClose(),!0===t?w2tooltip.hide(this.name+"-search-suggest"):0${t}`:t}}).select(e=>{var t=this.trigger("searchSelect",{target:this.name,index:e.detail.index,item:e.detail.item});!0===t.isCancelled?e.preventDefault():(e.detail.overlay.hide(),this.last.logic=e.detail.item.logic||"AND",this.last.search="",this.last.label="[Multiple Fields]",this.searchData=w2utils.clone(e.detail.item.data),this.searchSelected=w2utils.clone(e.detail.item,{exclude:["icon","remove"]}),this.reload(),t.finish())}).remove(e=>{let i=e.detail.item,s=this.trigger("searchRemove",{target:this.name,index:e.detail.index,item:i});!0===s.isCancelled?e.preventDefault():(e.detail.overlay.hide(),this.confirm(w2utils.lang('Do you want to delete search "${item}"?',{item:i.text})).yes(e=>{var t=this.savedSearches.findIndex(e=>e.id==i.id);-1!==t&&this.savedSearches.splice(t,1),this.cacheSave("searches",this.savedSearches.map(e=>w2utils.clone(e,{exclude:["remove","icon"]}))),e.detail.self.close(),s.finish()}).no(e=>{e.detail.self.close()}))})):this.last.overlay_timer=setTimeout(()=>{this.searchSuggest(!0)},100))}searchSave(){let e="",t=(this.searchSelected&&(e=this.searchSelected.text),this.savedSearches.findIndex(e=>e.id==this.searchSelected?.id)),s=this.trigger("searchSave",{target:this.name,saveLocalStorage:!0});!0!==s.isCancelled&&this.message({width:350,height:150,body:``,buttons:` + + + `}).open(async i=>{query(i.detail.box).find("input, button").eq(0).val(e),await i.complete,query(i.detail.box).find("#grid-search-cancel").on("click",()=>{this.message()}),query(i.detail.box).find("#grid-search-save").on("click",()=>{var e=query(i.detail.box).find(".w2ui-message .search-name").val();this.searchSelected&&-1!=t?Object.assign(this.savedSearches[t],{id:e,text:e,logic:this.last.logic,data:w2utils.clone(this.searchData)}):this.savedSearches.push({id:e,text:e,icon:"w2ui-icon-search",remove:!0,logic:this.last.logic,data:this.searchData}),this.cacheSave("searches",this.savedSearches.map(e=>w2utils.clone(e,{exclude:["remove","icon"]}))),this.message(),(this.searchSelected?(this.searchSelected.text=e,query(this.box).find(`#grid_${this.name}_search_name .name-text`)):(this.searchSelected={text:e,logic:this.last.logic,data:w2utils.clone(this.searchData)},query(i.detail.box).find(`#grid_${this.name}_search_all`).val(" ").prop("readOnly",!0),query(i.detail.box).find(`#grid_${this.name}_search_name`).show().find(".name-text"))).html(e),s.finish({name:e})}),query(i.detail.box).find("input, button").off(".message").on("keydown.message",e=>{var t=String(query(i.detail.box).find(".w2ui-message-body input").val()).trim();13==e.keyCode&&""!=t&&query(i.detail.box).find("#grid-search-save").trigger("click"),27==e.keyCode&&this.message()}).eq(0).on("input.message",e=>{var t=query(i.detail.box).closest(".w2ui-message").find("#grid-search-save");""===String(query(i.detail.box).val()).trim()?t.prop("disabled",!0):t.prop("disabled",!1)}).get(0).focus()})}cache(e){if(w2utils.hasLocalStorage&&this.useLocalStorage)try{var t=JSON.parse(localStorage.w2ui||"{}");return t[this.stateId||this.name]??={},t[this.stateId||this.name][e]}catch(e){}return null}cacheSave(e,t){if(w2utils.hasLocalStorage&&this.useLocalStorage)try{var i=JSON.parse(localStorage.w2ui||"{}");return i[this.stateId||this.name]??={},i[this.stateId||this.name][e]=t,localStorage.w2ui=JSON.stringify(i),!0}catch(e){delete localStorage.w2ui}return!1}searchReset(e){var t=[];let i=!1;for(let e=0;e=this.searches.length?(this.last.field="",this.last.label=""):(this.last.field=this.searches[e].field,this.last.label=this.searches[e].label)}this.last.multi=!1,this.last.fetch.offset=0,this.last.scrollTop=0,this.last.scrollLeft=0,this.last.selection.indexes=[],this.last.selection.columns={},this.searchClose();l=l.val("").get(0);l?._w2field&&l._w2field.reset(),e||this.reload(),s.finish()}}searchShowFields(e){if(!0===e)w2tooltip.hide(this.name+"-search-fields");else{var l=[];for(let s=-1;s",e),e.label=e.caption),l.push({id:e.field,text:w2utils.lang(e.label),search:e,tooltip:i,disabled:t,checked:e.field==this.last.field})}w2menu.show({type:"radio",name:this.name+"-search-fields",anchor:query(this.box).find("#grid_"+this.name+"_search_name").parent().find(".w2ui-search-down").get(0),items:l,align:"none",hideOn:["doc-click","select"]}).select(e=>{this.searchInitInput(e.detail.item.search.field)})}}searchInitInput(e,t){let i;var s=query(this.box).find("#grid_"+this.name+"_search_all");if("all"==e)i={field:"all",label:w2utils.lang("All Fields")};else if(null==(i=this.getSearch(e)))return;""!=this.last.search?(this.last.label=i.label,this.search(i.field,this.last.search)):(this.last.field=i.field,this.last.label=i.label),s.attr("placeholder",w2utils.lang("Search")+" "+w2utils.lang(i.label||i.caption||i.field,!0))}clear(e){this.total=0,this.records=[],this.summary=[],this.last.fetch.offset=0,this.last.idCache={},this.last.selection={indexes:[],columns:{}},this.reset(!0),e||this.refresh()}reset(e){this.last.scrollTop=0,this.last.scrollLeft=0,this.last.range_start=null,this.last.range_end=null,query(this.box).find(`#grid_${this.name}_records`).prop("scrollTop",0),e||this.refresh()}skip(e,t){this.url?.get??this.url?(this.offset=parseInt(e),this.offset>this.total&&(this.offset=this.total-this.limit),(this.offset<0||!w2utils.isInt(this.offset))&&(this.offset=0),this.clear(!0),this.reload(t)):console.log("ERROR: grid.skip() can only be called when you have remote data source.")}load(e,t){return null==e?(console.log('ERROR: You need to provide url argument when calling .load() method of "'+this.name+'" object.'),new Promise((e,t)=>{t()})):(this.clear(!0),this.request("load",{},e,t))}reload(e){let t=this;var i=this.url?.get??this.url;return t.selectionSave(),i?this.load(i,()=>{t.selectionRestore(),"function"==typeof e&&e()}):(this.reset(!0),this.localSearch(),this.selectionRestore(),"function"==typeof e&&e({status:"success"}),new Promise(e=>{e()}))}request(i,e,t,s){let l=this,r,a;var n=new Promise((e,t)=>{r=e,a=t});if(null==e&&(e={}),!(t=t||this.url))return new Promise((e,t)=>{t()});w2utils.isInt(this.offset)||(this.offset=0),w2utils.isInt(this.last.fetch.offset)||(this.last.fetch.offset=0);let o;var h={limit:this.limit,offset:parseInt(this.offset)+parseInt(this.last.fetch.offset),searchLogic:this.last.logic,search:this.searchData.map(e=>{e=w2utils.clone(e);return this.searchMap&&this.searchMap[e.field]&&(e.field=this.searchMap[e.field]),e}),sort:this.sortData.map(e=>{e=w2utils.clone(e);return this.sortMap&&this.sortMap[e.field]&&(e.field=this.sortMap[e.field]),e})};if(0===this.searchData.length&&(delete h.search,delete h.searchLogic),0===this.sortData.length&&delete h.sort,w2utils.extend(h,this.postData),w2utils.extend(h,e),"delete"!=i&&"save"!=i||(delete h.limit,delete h.offset,"delete"==(h.action=i)&&(h[this.recid||"recid"]=this.getSelection())),"load"==i){if(!0===(o=this.trigger("request",{target:this.name,url:t,postData:h,httpMethod:"GET",httpHeaders:this.httpHeaders})).isCancelled)return new Promise((e,t)=>{t()})}else o={detail:{url:t,postData:h,httpMethod:"save"==i?"PUT":"DELETE",httpHeaders:this.httpHeaders}};if(0===this.last.fetch.offset&&this.lock(w2utils.lang(this.msgRefresh),!0),this.last.fetch.controller)try{this.last.fetch.controller.abort()}catch(e){}switch(t=o.detail.url,i){case"save":t?.save&&(t=t.save);break;case"delete":t?.remove&&(t=t.remove);break;default:t=t?.get??t}if(0{null!=e&&(200!=e?.status?u(e??{}):(l.unlock(),e.json().catch(u).then(e=>{this.requestComplete(e,i,s,r,a)})))}),"load"==i&&o.finish(),n;function u(e){var t;"AbortError"!==e?.name&&(l.unlock(),!0!==(t=l.trigger("error",{response:e,lastFetch:l.last.fetch})).isCancelled)&&(e.status&&200!=e.status?l.error(e.status+": "+e.statusText):(console.log("ERROR: Server communication failed.","\n EXPECTED:",{total:5,records:[{recid:1,field:"value"}]},"\n OR:",{error:!0,message:"error message"}),l.requestComplete({error:!0,message:w2utils.lang(this.msgHTTPError),response:e},i,s,r,a)),t.finish())}}requestComplete(e,t,i,s,l){let r=e.error??!1,a=(null==e.error&&"error"===e.status&&(r=!0),this.last.fetch.response=(Date.now()-this.last.fetch.start)/1e3,setTimeout(()=>{this.show.statusResponse&&this.status(w2utils.lang("Server Response ${count} seconds",{count:this.last.fetch.response}))},10),this.last.pull_more=!1,this.last.pull_refresh=!0,"load");"save"==this.last.fetch.action&&(a="save"),"delete"==this.last.fetch.action&&(a="delete");var n=this.trigger(a,{target:this.name,error:r,data:e,lastFetch:this.last.fetch});if(!0===n.isCancelled)l();else{if(r)this.error(w2utils.lang(e.message??this.msgServerError)),l(e);else if("function"==typeof this.parser?"object"!=typeof(e=this.parser(e))&&console.log("ERROR: Your parser did not return proper object"):null==e?e={error:!0,message:w2utils.lang(this.msgNotJSON)}:Array.isArray(e)&&(e={error:r,records:e,total:e.length}),"load"==t){if(null==e.total&&(e.total=-1),null==e.records&&(e.records=[]),e.records.length==this.limit?(l=this.records.length+e.records.length,this.last.fetch.hasMore=l!=this.total):(this.last.fetch.hasMore=!1,this.total=this.offset+this.last.fetch.offset+e.records.length),this.last.fetch.hasMore||query(this.box).find("#grid_"+this.name+"_rec_more, #grid_"+this.name+"_frec_more").hide(),0===this.last.fetch.offset)this.records=[],this.summary=[];else if(-1!=e.total&&parseInt(e.total)!=parseInt(this.total)){let e=this;return this.message(w2utils.lang(this.msgNeedReload)).ok(()=>{delete e.last.fetch.offset,e.reload()}),new Promise(e=>{e()})}w2utils.isInt(e.total)&&(this.total=parseInt(e.total)),e.records&&e.records.forEach(e=>{this.recid&&(e.recid=this.parseField(e,this.recid)),null==e.recid&&(e.recid="recid-"+this.records.length),(!0===e.w2ui?.summary?this.summary:this.records).push(e)}),e.summary&&(this.summary=[],e.summary.forEach(e=>{this.recid&&(e.recid=this.parseField(e,this.recid)),null==e.recid&&(e.recid="recid-"+this.summary.length),this.summary.push(e)}))}else if("delete"==t)return this.reset(),this.reload();(this.url?.get??this.url)||(this.localSort(),this.localSearch()),this.total=parseInt(this.total),0===this.last.fetch.offset?this.refresh():(this.scroll(),this.resize()),"function"==typeof i&&i(e),s(e),n.finish(),this.last.fetch.loaded=!0}}error(e){var t=this.trigger("error",{target:this.name,message:e});!0!==t.isCancelled&&(this.message(e),t.finish())}getChanges(t){var i=[];void 0===t&&(t=this.records);for(let e=0;e{e.error||this.mergeChanges(),s.finish(),"function"==typeof t&&t(e)}):(this.mergeChanges(),s.finish()))}editField(d,u,c,p){let f=this;if(!0===this.last.inEditMode)p&&13==p.keyCode?({index:m,column:g,value:y}=this.last._edit,this.editChange({type:"custom",value:y},m,g,p),this.editDone(m,g,p)):0<(y=query(this.box).find("div.w2ui-edit-box .w2ui-input")).length&&("DIV"==y.get(0).tagName?(y.text(y.text()+c),w2utils.setCursorPosition(y.get(0),y.text().length)):(y.val(y.val()+c),w2utils.setCursorPosition(y.get(0),y.val().length)));else{let o=this.get(d,!0),h=this.getCellEditable(o,u);if(h&&!["checkbox","check"].includes(h.type)){let a=this.records[o],n=this.columns[u];var m=!0===n.frozen?"_f":"_";if(-1!=["enum","file"].indexOf(h.type))console.log('ERROR: input types "enum" and "file" are not supported in inline editing.');else{var g=this.trigger("editField",{target:this.name,recid:d,column:u,value:c,index:o,originalEvent:p});if(!0!==g.isCancelled){c=g.detail.value,this.last.inEditMode=!0,this.last.editColumn=u,this.last._edit={value:c,index:o,column:u,recid:d},this.selectNone(!0),this.select({recid:d,column:u});var y=query(this.box).find("#grid_"+this.name+m+"rec_"+w2utils.escapeId(d));let e=y.find('[col="'+u+'"] > div'),t=(this.last._edit.tr=y,this.last._edit.div=e,query(this.box).find("div.w2ui-edit-box").remove(),"row"!=this.selectType&&(query(this.box).find("#grid_"+this.name+m+"selection").attr("id","grid_"+this.name+"_editable").removeClass("w2ui-selection").addClass("w2ui-edit-box").prepend('
    ').find(".w2ui-selection-resizer").remove(),e=query(this.box).find("#grid_"+this.name+"_editable > div:first-child")),h.attr=h.attr??"",h.text=h.text??"",h.style=h.style??"",h.items=h.items??[],null!=a.w2ui?.changes?.[n.field]?w2utils.stripTags(a.w2ui.changes[n.field]):w2utils.stripTags(f.parseField(a,n.field))),i="object"!=typeof(t=null==t?"":t)?t:"",s=(null!=g.detail.prevValue&&(i=g.detail.prevValue),null!=c&&(t=c),null!=n.style?n.style+";":"");"string"==typeof n.render&&["number","int","float","money","percent","size"].includes(n.render.split(":")[0])&&(s+="text-align: right;"),0 div').get(0)),m=`font-family: ${p["font-family"]}; font-size: ${p["font-size"]};`;function w(e){try{var t=getComputedStyle(e),i="DIV"==e.tagName.toUpperCase()?e.innerText:e.value,s=query(f.box).find("#grid_"+f.name+"_editable").get(0),l=`font-family: ${t["font-family"]}; font-size: ${t["font-size"]}; white-space: no-wrap;`,r=w2utils.getStrWidth(i,l);r+20>s.clientWidth&&query(s).css("width",r+20+"px")}catch(e){}}"div"===h.type?(e.addClass("w2ui-editable").html(w2utils.stripSpaces(`
    +
    `+h.text)),(l=e.find("div.w2ui-input").get(0)).innerText="object"!=typeof t?t:"",null!=c?w2utils.setCursorPosition(l,l.innerText.length):w2utils.setCursorPosition(l,0,l.innerText.length)):(e.addClass("w2ui-editable").html(w2utils.stripSpaces(``+h.text)),l=e.find("input").get(0),"number"==h.type&&(t=w2utils.formatNumber(t)),"date"==h.type&&(t=w2utils.formatDate(w2utils.isDate(t,h.format,!0)||new Date,h.format)),l.value="object"!=typeof t?t:"",y=e=>{var t=this.last._edit?.escKey;let i=!1;var s=query(l).data("tooltipName");s&&null!=w2tooltip.get(s[0])?.selected&&(i=!0),!this.last.inEditMode||t||!r.includes(h.type)||e.detail.overlay.anchor?.id!=this.last._edit.input?.id&&"list"!=h.type||(this.editChange(),this.editDone(void 0,void 0,{keyCode:i?13:0}))},new w2field(w2utils.extend({},h,{el:l,selected:t,onSelect:y,onHide:y})),null==c&&l&&l.select()),Object.assign(this.last._edit,{input:l,edit:h}),query(l).off(".w2ui-editable").on("blur.w2ui-editable",e=>{var t,i;this.last.inEditMode&&(t=this.last._edit.edit.type,i=query(l).data("tooltipName"),r.includes(t)&&i||(this.editChange(l,o,u,e),this.editDone()))}).on("mousedown.w2ui-editable",e=>{e.stopPropagation()}).on("click.w2ui-editable",e=>{w.call(l,e)}).on("paste.w2ui-editable",e=>{e.preventDefault();e=e.clipboardData.getData("text/plain");document.execCommand("insertHTML",!1,e)}).on("keyup.w2ui-editable",e=>{w.call(l,e)}).on("keydown.w2ui-editable",i=>{switch(i.keyCode){case 8:"list"!=h.type||l._w2field||i.preventDefault();break;case 9:case 13:i.preventDefault();break;case 27:var e=query(l).data("tooltipName");e&&0{switch(i.keyCode){case 9:var e=i.shiftKey?f.prevCell(o,u,!0):f.nextCell(o,u,!0);null!=e&&(t=f.records[e.index].recid,this.editChange(l,o,u,i),this.editDone(o,u,i),"row"!=f.selectType?(f.selectNone(!0),f.select({recid:t,column:e.colIndex})):f.editField(t,e.colIndex,null,i),i.preventDefault)&&i.preventDefault();break;case 13:{let e=!1;var t=query(l).data("tooltipName");t&&null!=w2tooltip.get(t[0]).selected&&(e=!0),t&&e||(this.editChange(l,o,u,i),this.editDone(o,u,i));break}case 27:{this.last._edit.escKey=!1;let e=f.parseField(a,n.field);null!=a.w2ui?.changes?.[n.field]&&(e=a.w2ui.changes[n.field]),null!=l._prevValue&&(e=l._prevValue),"DIV"==l.tagName?l.innerText=null!=e?e:"":l.value=null!=e?e:"",this.editDone(o,u,i),setTimeout(()=>{f.select({recid:d,column:u})},1);break}}w(l)},1)}),l&&(l._prevValue=i),"list"!=h.type&&setTimeout(()=>{this.last.inEditMode&&l&&(l.focus(),clearTimeout(this.last.kbd_timer),(l.resize=w)(l))},50),g.finish({input:l})}}}}}editChange(e,t,i,s){e=e??this.last._edit.input,t=t??this.last._edit.index,i=i??this.last._edit.column,s=s??{};var l=(t<0?this.summary:this.records)[t=t<0?-t-1:t],r=this.columns[i];let a="DIV"==e?.tagName?e.innerText:e.value;var n=e._w2field,o=(n&&("list"==n.type&&(a=n.selected),0!==Object.keys(a).length&&null!=a||(a=""),w2utils.isPlainObject(a)||(a=n.clean(a))),"checkbox"==e.type&&(!1===l.w2ui?.editable&&(e.checked=!e.checked),a=e.checked),this.parseField(l,r.field)),h=l.w2ui?.changes&&l.w2ui.changes.hasOwnProperty(r.field)?l.w2ui.changes[r.field]:o;let d={target:this.name,input:e,recid:l.recid,index:t,column:i,originalEvent:s,value:{new:a,previous:h,original:o}},u=(null!=s.target?._prevValue&&(d.value.previous=s.target._prevValue),0);for(;u<20;){if(u++,"object"!=typeof(a=d.value.new)&&String(o)!=String(a)||"object"==typeof a&&a&&a.id!=o&&("object"!=typeof o||null==o||a.id!=o.id)){if(!0!==(d=this.trigger("change",d)).isCancelled){if(a!==d.detail.value.new)continue;(""!==d.detail.value.new&&null!=d.detail.value.new||""!==h&&null!=h)&&(l.w2ui=l.w2ui??{},l.w2ui.changes=l.w2ui.changes??{},l.w2ui.changes[r.field]=d.detail.value.new),d.finish()}}else if(!0!==(d=this.trigger("restore",d)).isCancelled){if(a!==d.detail.value.new)continue;l.w2ui?.changes&&(delete l.w2ui.changes[r.field],0===Object.keys(l.w2ui.changes).length)&&delete l.w2ui.changes,d.finish()}break}}editDone(t,i,s){if(t=t??this.last._edit.index,i=i??this.last._edit.column,s=s??{},this.advanceOnEdit&&13==s.keyCode){let e=s.shiftKey?this.prevRow(t,i,1):this.nextRow(t,i,1);null==e&&(e=t),setTimeout(()=>{"row"!=this.selectType?(this.selectNone(!0),this.select({recid:this.records[e].recid,column:i})):this.editField(this.records[e].recid,i,null,s)},1)}var e=t<0,l=query(this.last._edit.tr).find('[col="'+i+'"]'),r=this.records[t],a=this.columns[i];this.last.inEditMode=!1,this.last._edit=null,e||(null!=r.w2ui?.changes?.[a.field]?l.addClass("w2ui-changed"):l.removeClass("w2ui-changed"),l.replace(this.getCellHTML(t,i,e))),query(this.box).find("div.w2ui-edit-box").remove(),this.updateToolbar(),setTimeout(()=>{var e=query(this.box).find(`#grid_${this.name}_focus`).get(0);document.activeElement===e||this.last.inEditMode||e.focus()},10)}delete(e){var t=this.trigger("delete",{target:this.name,force:e});if(e&&this.message(),!0!==t.isCancelled){e=t.detail.force;var i=this.getSelection();if(0!==i.length)if(""==this.msgDelete||e){if("object"!=typeof this.url?this.url:this.url.remove)this.request("delete");else if("object"!=typeof i[0])this.selectNone(),this.remove.apply(this,i);else{for(let e=0;e{e.detail.self.close(),this.delete(!0)}).no(e=>{e.detail.self.close()})}}click(l,r){var a=Date.now();let n=null;if(!(1==this.last.cancelClick||r&&r.altKey))if("object"==typeof l&&null!==l&&(n=l.column,l=l.recid),null==r&&(r={}),a-parseInt(this.last.click_time)<350&&this.last.click_recid==l&&"click"==r.type)this.dblClick(l,r);else{this.last.bubbleEl&&(this.last.bubbleEl=null),this.last.click_time=a;a=this.last.click_recid;if(this.last.click_recid=l,null==n&&r.target){let e=r.target;"TD"!=e.tagName&&(e=query(e).closest("td")[0]),null!=query(e).attr("col")&&(n=parseInt(query(e).attr("col")))}var o=this.trigger("click",{target:this.name,recid:l,column:n,originalEvent:r});if(!0!==o.isCancelled){var h=this.getSelection(),d=(query(this.box).find("#grid_"+this.name+"_check_all").prop("checked",!1),this.get(l,!0)),u=[];this.last.sel_ind=d,this.last.sel_col=n,this.last.sel_recid=l,this.last.sel_type="click";let e,i,t,s;if(r.shiftKey&&0h[0].column?(t=h[0].column,n):(t=n,h[0].column);for(let e=t;e<=s;e++)u.push(e)}else e=this.get(a,!0),i=this.get(l,!0);var c=[],p=(e>i&&(a=e,e=i,i=a),this.url?.get?this.url.get:this.url);for(let t=e;t<=i;t++)if(!(0=this.records.length?this.selectNone():this.selectAll())}else if(t.altKey&&(l=this.getColumn(s))&&l.sortable&&this.sort(s,null,!(!t||!t.ctrlKey&&!t.metaKey)),"line-number"==e.detail.field)this.getSelection().length>=this.records.length?this.selectNone():this.selectAll();else{t.shiftKey||t.metaKey||t.ctrlKey||this.selectNone(!0);var l=this.getSelection(),s=this.getColumn(e.detail.field,!0),i=[],r=[];if(0!=l.length&&t.shiftKey){let t=s,i=l[0].column;t>i&&(t=l[0].column,i=s);for(let e=t;e<=i;e++)r.push(e)}else r.push(s);if(!0!==(e=this.trigger("columnSelect",{target:this.name,columns:r})).isCancelled){for(let e=0;e{query("#w2overlay-context-menu .w2ui-grid-skip").off(".w2ui-grid").on("click.w2ui-grid",e=>{e.stopPropagation()}).on("keypress",e=>{13==e.keyCode&&(this.skip(e.target.value),this.toolbar.click("w2ui-column-on-off"))})}).select(e=>{var t=e.detail.item.id;["w2ui-stateSave","w2ui-stateReset"].includes(t)?this[t.substring(5)]():"w2ui-skip"!=t&&this.columnOnOff(e,e.detail.item.id),clearTimeout(this.last.kbd_timer)}),clearTimeout(this.last.kbd_timer)),t.preventDefault(),e.finish())}focus(e){e=this.trigger("focus",{target:this.name,originalEvent:e});if(!0===e.isCancelled)return!1;this.hasFocus=!0,query(this.box).removeClass("w2ui-inactive").find(".w2ui-inactive").removeClass("w2ui-inactive"),setTimeout(()=>{var e=query(this.box).find(`#grid_${this.name}_focus`).get(0);e&&document.activeElement!=e&&e.focus()},10),e.finish()}blur(e){e=this.trigger("blur",{target:this.name,originalEvent:e});if(!0===e.isCancelled)return!1;this.hasFocus=!1,query(this.box).addClass("w2ui-inactive").find(".w2ui-selected").addClass("w2ui-inactive"),query(this.box).find(".w2ui-selection").addClass("w2ui-inactive"),e.finish()}keydown(c){let p=this,f="object"!=typeof this.url?this.url:this.url.get;if(!0===p.keyboard){var m=p.trigger("keydown",{target:p.name,originalEvent:c});if(!0!==m.isCancelled)if(0t&&p.last.sel_ind!=l?p.unselect(p.records[l].recid):p.select(p.records[t].recid);else if(p.last.sel_ind>t&&p.last.sel_ind!=l){t=l;var i=[];for(let e=0;e{var e=query(p.box).find("#grid_"+p.name+"_focus"),t=e.val();e.val(""),p.editField(a,n[0],t,c)},1)),d&&c.preventDefault&&c.preventDefault(),m.finish()}}}scrollIntoView(e,s,t,i){let l=this.records.length;if(0!==(l=0==this.searchData.length||this.url?l:this.last.searchIds.length)){if(null==e){var r=this.getSelection();if(0===r.length)return;w2utils.isPlainObject(r[0])?(e=r[0].index,s=r[0].column):e=this.get(r[0],!0)}var r=query(this.box).find(`#grid_${this.name}_records`),a=r[0].clientWidth,n=r[0].clientHeight,o=r[0].scrollTop,h=r[0].scrollLeft,d=this.last.searchIds.length;if(0{clearTimeout(this.last.kbd_timer),this.contextMenuClick(i,s,e)}),clearTimeout(this.last.kbd_timer)),e.preventDefault(),t.finish())}}contextMenuClick(e,t,i){e=this.trigger("contextMenuClick",{target:this.name,recid:e,column:t,originalEvent:i.detail.originalEvent,menuEvent:i,menuIndex:i.detail.index,menuItem:i.detail.item});!0!==e.isCancelled&&e.finish()}toggle(e){var t=this.get(e);if(null!=t)return t.w2ui=t.w2ui??{},!0===t.w2ui.expanded?this.collapse(e):this.expand(e)}expand(e,t){var i=this.get(e,!0);let s=this.records[i];s.w2ui=s.w2ui??{};var l=w2utils.escapeId(e),r=s.w2ui.children;let a;if(Array.isArray(r)){if(!0===s.w2ui.expanded||0===r.length)return!1;if(!0===(a=this.trigger("expand",{target:this.name,recid:e})).isCancelled)return!1;s.w2ui.expanded=!0,r.forEach(e=>{e.w2ui=e.w2ui??{},e.w2ui.parent_recid=s.recid,null==e.w2ui.children&&(e.w2ui.children=[])}),this.records.splice.apply(this.records,[i+1,0].concat(r)),-1!==this.total&&(this.total+=r.length),("object"!=typeof this.url?this.url:this.url.get)||(this.localSort(!0,!0),0 + +
    + + + `),query(this.box).find("#grid_"+this.name+"_frec_"+l).after(` + ${this.show.lineNumbers?'':""} + +
    + + `),!0===(a=this.trigger("expand",{target:this.name,recid:e,box_id:"grid_"+this.name+"_rec_"+e+"_expanded",fbox_id:"grid_"+this.name+"_frec_"+e+"_expanded"})).isCancelled)return query(this.box).find("#grid_"+this.name+"_rec_"+l+"_expanded_row").remove(),query(this.box).find("#grid_"+this.name+"_frec_"+l+"_expanded_row").remove(),!1;i=query(this.box).find("#grid_"+this.name+"_rec_"+e+"_expanded"),r=query(this.box).find("#grid_"+this.name+"_frec_"+e+"_expanded"),t=i.find(":scope div:first-child")[0]?.clientHeight??50;i[0].clientHeight{query(this.box).find("#grid_"+this.name+"_rec_"+e+"_expanded_row").remove(),query(this.box).find("#grid_"+this.name+"_frec_"+e+"_expanded_row").remove(),l.w2ui.expanded=!1,a.finish(),this.resizeRecords()},300)}return!0}sort(i,e,s){var t=this.trigger("sort",{target:this.name,field:i,direction:e,multiField:s});if(!0!==t.isCancelled){if(null!=i){let t=this.sortData.length;for(let e=0;ei&&(i=s[e].column),-1==r.indexOf(s[e].index)&&r.push(s[e].index);r.sort((e,t)=>e-t);for(let e=0;e!!e);e.classList.forEach(e=>{t.includes(e)||i.push(e)}),e.classList.remove(...i),e.classList.add(...o)}}if(u.columns[t].style&&u.columns[t].style!=e.style.cssText&&(e.style.cssText=u.columns[t].style??""),null!=s.w2ui.class){if("string"==typeof s.w2ui.class){let t=["w2ui-odd","w2ui-even","w2ui-record"],i=[];a=s.w2ui.class.split(" ").filter(e=>!!e);l&&r&&(l.classList.forEach(e=>{t.includes(e)||i.push(e)}),l.classList.remove(...i),l.classList.add(...a),r.classList.remove(...i),r.classList.add(...a))}if(w2utils.isPlainObject(s.w2ui.class)&&"string"==typeof s.w2ui.class[n.field]){let t=["w2ui-grid-data"],i=[];h=s.w2ui.class[n.field].split(" ").filter(e=>!!e);e.classList.forEach(e=>{t.includes(e)||i.push(e)}),e.classList.remove(...i),e.classList.add(...h)}}null!=s.w2ui.style&&(l&&r&&"string"==typeof s.w2ui.style&&l.style.cssText!==s.w2ui.style&&(l.style.cssText="height: "+u.recordHeight+"px;"+s.w2ui.style,l.setAttribute("custom_style",s.w2ui.style),r.style.cssText="height: "+u.recordHeight+"px;"+s.w2ui.style,r.setAttribute("custom_style",s.w2ui.style)),w2utils.isPlainObject(s.w2ui.style))&&"string"==typeof s.w2ui.style[n.field]&&e.style.cssText!==s.w2ui.style[n.field]&&(e.style.cssText=s.w2ui.style[n.field])}}}}refreshCell(e,t){var i=this.get(e,!0),t=this.getColumn(t,!0),e=!this.records[i]||this.records[i].recid!=e,s=query(this.box).find(`${e?".w2ui-grid-summary ":""}#grid_${this.name}_data_${i}_`+t);return 0!=s.length&&(s.replace(this.getCellHTML(i,t,e)),!0)}refreshRow(t,i=null){let s=query(this.box).find("#grid_"+this.name+"_frec_"+w2utils.escapeId(t)),l=query(this.box).find("#grid_"+this.name+"_rec_"+w2utils.escapeId(t));if(0{var t=[];for(let e=0;e{var t=query(this.box).find('td[col="'+e.col+'"]:not(.w2ui-head)');w2utils.marker(t,e.search)})},50),this.updateToolbar(this.last.selection),t.finish(),this.resize(),this.addRange("selection"),setTimeout(()=>{this.resize(),this.scroll()},1),this.reorderColumns&&!this.last.columnDrag?this.last.columnDrag=this.initColumnDrag():!this.reorderColumns&&this.last.columnDrag&&this.last.columnDrag.remove(),Date.now()-e}}}refreshSearch(){if(this.multiSearch&&0`);let r=` + +
    `;this.searchData.forEach((i,e)=>{var t=this.getSearch(i.field,!0),s=this.searches[t];let l;if(l=Array.isArray(i.value)?`${i.value.length}`:s&&"list"==s.type&&i.text&&i.text!==i.value?": "+i.text:": "+i.value,s&&"date"==s.type)if("between"==i.operator){let e=i.value[0],t=i.value[1];Number(e)===e&&(e=w2utils.formatDate(e)),Number(t)===t&&(t=w2utils.formatDate(t)),l=`: ${e} - `+t}else{let e=i.value,t=(Number(e)==e&&(e=w2utils.formatDate(e)),i.operator);"more:"==(t="less"==(t="more"==t?"since":t)?"before":t).substr(0,5)&&(t="since"),l=`: ${t} `+e}r+=` + ${s?s.label:""} + ${l} + + `}),r+=` + ${this.show.searchSave?`
    + + `:""} + + `,query(this.box).find(`#grid_${this.name}_searches`).html(r),query(this.box).find(`#grid_${this.name}_search_logic`).html(w2utils.lang("AND"==this.last.logic?"All":"Any"))}else query(this.box).find(".w2ui-grid-toolbar").css("height",this.last.toolbar_height+"px").find(".w2ui-grid-searches").remove();this.searchSelected?(query(this.box).find(`#grid_${this.name}_search_all`).val(" ").prop("readOnly",!0),query(this.box).find(`#grid_${this.name}_search_name`).show().find(".name-text").html(this.searchSelected.text)):(query(this.box).find(`#grid_${this.name}_search_all`).prop("readOnly",!1),query(this.box).find(`#grid_${this.name}_search_name`).hide().find(".name-text").html("")),w2utils.bindEvents(query(this.box).find(`#grid_${this.name}_searches .w2ui-action, #grid_${this.name}_searches button`),this)}refreshBody(){this.scroll();var e=this.getRecordsHTML(),t=this.getColumnsHTML(),e='
    '+e[0]+'
    '+e[1]+'
    '+t[0]+'
    '+t[1]+"
    "+``;let l=query(this.box).find(`#grid_${this.name}_body`,this.box).html(e);t=query(this.box).find(`#grid_${this.name}_records`,this.box),e=query(this.box).find(`#grid_${this.name}_frecords`,this.box);"row"==this.selectType&&(t.on("mouseover mouseout",{delegate:"tr"},e=>{var t=query(e.delegate).attr("recid");query(this.box).find(`#grid_${this.name}_frec_`+w2utils.escapeId(t)).toggleClass("w2ui-record-hover","mouseover"==e.type)}),e.on("mouseover mouseout",{delegate:"tr"},e=>{var t=query(e.delegate).attr("recid");query(this.box).find(`#grid_${this.name}_rec_`+w2utils.escapeId(t)).toggleClass("w2ui-record-hover","mouseover"==e.type)})),w2utils.isIOS?t.append(e).on("click",{delegate:"tr"},e=>{var t=query(e.delegate).attr("recid");this.dblClick(t,e)}):t.add(e).on("click",{delegate:"tr"},e=>{var t=query(e.delegate).attr("recid");"-none-"!=t&&this.click(t,e)}).on("contextmenu",{delegate:"tr"},e=>{var t=query(e.delegate).attr("recid"),i=query(e.target).closest("td"),i=parseInt(i.attr("col")??-1);this.showContextMenu(t,i,e)}).on("mouseover",{delegate:"tr"},e=>{this.last.rec_out=!1;let t=query(e.delegate).attr("index"),i=query(e.delegate).attr("recid");t!==this.last.rec_over&&(this.last.rec_over=t,setTimeout(()=>{delete this.last.rec_out,this.trigger("mouseEnter",{target:this.name,originalEvent:e,index:t,recid:i}).finish()}))}).on("mouseout",{delegate:"tr"},t=>{let i=query(t.delegate).attr("index"),s=query(t.delegate).attr("recid");this.last.rec_out=!0,setTimeout(()=>{let e=()=>{this.trigger("mouseLeave",{target:this.name,originalEvent:t,index:i,recid:s}).finish()};i!==this.last.rec_over&&e(),setTimeout(()=>{this.last.rec_out&&(delete this.last.rec_out,delete this.last.rec_over,e())})})}),l.data("scroll",{lastDelta:0,lastTime:0}).find(".w2ui-grid-frecords").on("mousewheel DOMMouseScroll ",e=>{e.preventDefault();var t=l.data("scroll"),i=l.find(".w2ui-grid-records"),e=null!=typeof e.wheelDelta?-e.wheelDelta:e.detail||e.deltaY,s=i.prop("scrollTop");t.lastDelta+=e,e=Math.round(t.lastDelta),l.data("scroll",t),i.get(0).scroll({top:s+e,behavior:"smooth"})}),t.off(".body-global").on("scroll.body-global",{delegate:".w2ui-grid-records"},e=>{this.scroll(e)}),query(this.box).find(".w2ui-grid-body").off(".body-global").on("click.body-global dblclick.body-global contextmenu.body-global",{delegate:"td.w2ui-head"},e=>{var t=query(e.delegate).attr("col"),i=this.columns[t]??{field:t};switch(e.type){case"click":this.columnClick(i.field,e);break;case"dblclick":this.columnDblClick(i.field,e);break;case"contextmenu":this.columnContextMenu(i.field,e)}}).on("mouseover.body-global",{delegate:".w2ui-col-header"},e=>{let t=query(e.delegate).parent().attr("col");this.columnTooltipShow(t,e),query(e.delegate).off(".tooltip").on("mouseleave.tooltip",()=>{this.columnTooltipHide(t,e)})}).on("click.body-global",{delegate:"input.w2ui-select-all"},e=>{e.delegate.checked?this.selectAll():this.selectNone(),e.stopPropagation(),clearTimeout(this.last.kbd_timer)}).on("click.body-global",{delegate:".w2ui-show-children, .w2ui-col-expand"},e=>{e.stopPropagation(),this.toggle(query(e.target).parents("tr").attr("recid"))}).on("click.body-global mouseover.body-global",{delegate:".w2ui-info"},e=>{var t=query(e.delegate).closest("td"),i=t.parent(),s=this.columns[t.attr("col")],l=i.parents(".w2ui-grid-body").hasClass("w2ui-grid-summary");["mouseenter","mouseover"].includes(s.info?.showOn?.toLowerCase())&&"mouseover"==e.type?this.showBubble(i.attr("index"),t.attr("col"),l).then(()=>{query(e.delegate).off(".tooltip").on("mouseleave.tooltip",()=>{w2tooltip.hide(this.name+"-bubble")})}):"click"==e.type&&(w2tooltip.hide(this.name+"-bubble"),this.showBubble(i.attr("index"),t.attr("col"),l))}).on("mouseover.body-global",{delegate:".w2ui-clipboard-copy"},l=>{if(!l.delegate._tooltipShow){let t=query(l.delegate).parent(),i=t.parent();var e=this.columns[t.attr("col")];let s=i.parents(".w2ui-grid-body").hasClass("w2ui-grid-summary");w2tooltip.show({name:this.name+"-bubble",anchor:l.delegate,html:w2utils.lang("string"==typeof e.clipboardCopy?e.clipboardCopy:"Copy to clipboard"),position:"top|bottom",offsetY:-2}).hide(e=>{l.delegate._tooltipShow=!1,query(l.delegate).off(".tooltip")}),query(l.delegate).off(".tooltip").on("mouseleave.tooltip",e=>{w2tooltip.hide(this.name+"-bubble")}).on("click.tooltip",e=>{e.stopPropagation(),w2tooltip.update(this.name+"-bubble",w2utils.lang("Copied")),this.clipboardCopy(i.attr("index"),t.attr("col"),s)}),l.delegate._tooltipShow=!0}}).on("click.body-global",{delegate:".w2ui-editable-checkbox"},e=>{var t=query(e.delegate).data();this.editChange.call(this,e.delegate,t.changeind,t.colind,e),this.updateToolbar()}),0===this.records.length&&this.msgEmpty?query(this.box).find(`#grid_${this.name}_body`).append(`
    ${w2utils.lang(this.msgEmpty)}
    `):0=this.searches.length?(this.last.field="",this.last.label=""):(this.last.field=this.searches[e].field,this.last.label=this.searches[e].label)}if(query(this.box).attr("name",this.name).addClass("w2ui-reset w2ui-grid w2ui-inactive").html('
    "),"row"!=this.selectType&&query(this.box).addClass("w2ui-ss"),0{this.searchInitInput(this.last.field,1==e.length?e[0].value:null)},1)}query(this.box).find(`#grid_${this.name}_footer`).html(this.getFooterHTML()),this.last.state||(this.last.state=this.stateSave(!0)),this.stateRestore(),e&&(this.clear(),this.refresh());let t=!1;for(let e=0;e{this.searchReset()},1)):this.reload(),query(this.box).find(`#grid_${this.name}_focus`).on("focus",e=>{clearTimeout(this.last.kbd_timer),this.hasFocus||this.focus()}).on("blur",e=>{clearTimeout(this.last.kbd_timer),this.last.kbd_timer=setTimeout(()=>{this.hasFocus&&this.blur()},100)}).on("paste",i=>{var s=i.clipboardData||null;if(s){let e=s.items,t=[];for(var l in e=2==e.length&&2==(e=2==e.length&&"file"==e[1].kind?[e[1]]:e).length&&"text/plain"==e[0].type&&"text/html"==e[1].type?[e[1]]:e){l=e[l];if("file"===l.kind){var r=l.getAsFile();t.push({kind:"file",data:r})}else if("string"===l.kind&&("text/plain"===l.type||"text/html"===l.type)){i.preventDefault();let e=s.getData("text/plain");-1!=e.indexOf("\r")&&-1==e.indexOf("\n")&&(e=e.replace(/\r/g,"\n")),t.push({kind:"text/html"==l.type?"html":"text",data:e})}}1===t.length&&"file"!=t[0].kind&&(t=t[0].data),w2ui[this.name].paste(t,i),i.preventDefault()}}).on("keydown",function(e){w2ui[p.name].keydown.call(w2ui[p.name],e)});let c;return query(this.box).off("mousedown.mouseStart").on("mousedown.mouseStart",function(l){if(1==l.which&&("text"==p.last.userSelect&&(p.last.userSelect="",query(p.box).find(".w2ui-grid-body").css("user-select","none")),!("row"==p.selectType&&(query(l.target).parents().hasClass("w2ui-head")||query(l.target).hasClass("w2ui-head"))||p.last.move&&"expand"==p.last.move.type))){if(l.altKey)query(p.box).find(".w2ui-grid-body").css("user-select","text"),p.selectNone(),p.last.move={type:"text-select"},p.last.userSelect="text";else{let e=l.target;var r={x:l.offsetX-10,y:l.offsetY-10};let t=!1;for(;e&&(!e.classList||!e.classList.contains("w2ui-grid"));)e.tagName&&"TD"==e.tagName.toUpperCase()&&(t=!0),e.tagName&&"TR"!=e.tagName.toUpperCase()&&1==t&&(r.x+=e.offsetLeft,r.y+=e.offsetTop),e=e.parentNode;p.last.move={x:l.screenX,y:l.screenY,divX:0,divY:0,focusX:r.x,focusY:r.y,recid:query(l.target).parents("tr").attr("recid"),column:parseInt(("TD"==l.target.tagName.toUpperCase()?query(l.target):query(l.target).parents("td")).attr("col")),type:"select",ghost:!1,start:!0},null==p.last.move.recid&&(p.last.move.type="select-column");let i=l.target,s=query(p.box).find("#grid_"+p.name+"_focus");if(p.last.move){let e=p.last.move.focusX,t=p.last.move.focusY;var a=query(i).parents("table").parent();(a.hasClass("w2ui-grid-records")||a.hasClass("w2ui-grid-frecords")||a.hasClass("w2ui-grid-columns")||a.hasClass("w2ui-grid-fcolumns")||a.hasClass("w2ui-grid-summary"))&&(e=p.last.move.focusX-query(p.box).find("#grid_"+p.name+"_records").prop("scrollLeft"),t=p.last.move.focusY-query(p.box).find("#grid_"+p.name+"_records").prop("scrollTop")),(query(i).hasClass("w2ui-grid-footer")||0{p.last.inEditMode||(["INPUT","TEXTAREA","SELECT"].includes(i.tagName)?i.focus():s.get(0)!==document.active&&s.get(0)?.focus({preventScroll:!0}))},50),p.multiSelect||p.reorderRows||"drag"!=p.last.move.type||delete p.last.move}if(1==p.reorderRows){let e=l.target;var t,i,s,n;"TD"!=e.tagName.toUpperCase()&&(e=query(e).parents("td")[0]),query(e).hasClass("w2ui-col-number")||query(e).hasClass("w2ui-col-order")?(p.selectNone(),p.last.move.reorder=!0,a=query(p.box).find(".w2ui-even.w2ui-empty-record").css("background-color"),t=query(p.box).find(".w2ui-odd.w2ui-empty-record").css("background-color"),query(p.box).find(".w2ui-even td").filter(":not(.w2ui-col-number)").css("background-color",a),query(p.box).find(".w2ui-odd td").filter(":not(.w2ui-col-number)").css("background-color",t),t=p.last.move,i=query(p.box).find(".w2ui-grid-records"),t.ghost||(s=query(p.box).find(`#grid_${p.name}_rec_`+t.recid),n=s.parents("table").find("tr:first-child").get(0).cloneNode(!0),t.offsetY=l.offsetY,t.from=t.recid,t.pos={top:s.get(0).offsetTop-1,left:s.get(0).offsetLeft},t.ghost=query(s.get(0).cloneNode(!0)),t.ghost.removeAttr("id"),t.ghost.find("td").css({"border-top":"1px solid silver","border-bottom":"1px solid silver"}),s.find("td").remove(),s.append(`
    `),i.append('
    '),i.append('
    '),query(p.box).find("#grid_"+p.name+"_ghost").append(n).append(t.ghost)),query(p.box).find("#grid_"+p.name+"_ghost").css({top:t.pos.top+"px",left:t.pos.left+"px"})):p.last.move.reorder=!1}query(document).on("mousemove.w2ui-"+p.name,o).on("mouseup.w2ui-"+p.name,h),l.stopPropagation()}}),this.updateToolbar(),s.finish(),this.last.observeResize=new ResizeObserver(()=>{this.resize()}),this.last.observeResize.observe(this.box),Date.now()-i;function o(t){if(t.target.tagName){var r=p.last.move;if(r&&-1!=["select","select-column"].indexOf(r.type)&&(r.divX=t.screenX-r.x,r.divY=t.screenY-r.y,!(Math.abs(r.divX)<=1&&Math.abs(r.divY)<=1)))if(p.last.cancelClick=!0,1==p.reorderRows&&p.last.move.reorder){let e=query(t.target).parents("tr").attr("recid");(e="-none-"==e?"bottom":e)!=r.from&&(n=query(p.box).find("#grid_"+p.name+"_rec_"+e),query(p.box).find(".insert-before"),n.addClass("insert-before"),r.lastY=t.screenY,r.to=e,n={top:n.get(0)?.offsetTop,left:n.get(0)?.offsetLeft},query(p.box).find("#grid_"+p.name+"_ghost_line").css({top:n.top+"px",left:r.pos.left+"px","border-top":"2px solid #769EFC"})),void query(p.box).find("#grid_"+p.name+"_ghost").css({top:r.pos.top+r.divY+"px",left:r.pos.left+"px"})}else{r.start&&r.recid&&(p.selectNone(),r.start=!1);var a=[],n=("TR"==t.target.tagName.toUpperCase()?query(t.target):query(t.target).parents("tr")).attr("recid");if(null==n){if("row"!=p.selectType&&(!p.last.move||"select"!=p.last.move.type)){var o=parseInt(query(t.target).parents("td").attr("col"));if(isNaN(o))p.removeRange("column-selection"),query(p.box).find(".w2ui-grid-columns .w2ui-col-header, .w2ui-grid-fcolumns .w2ui-col-header").removeClass("w2ui-col-selected"),query(p.box).find(".w2ui-col-number").removeClass("w2ui-row-selected"),delete r.colRange;else{let e=o+"-"+o;r.columno?o+"-"+r.column:e).split("-");for(let e=parseInt(s[0]);e<=parseInt(s[1]);e++)i.push(e);if(r.colRange!=e&&!0!==(c=p.trigger("columnSelect",{target:p.name,columns:i})).isCancelled){null==r.colRange&&p.selectNone();var l=e.split("-");query(p.box).find(".w2ui-grid-columns .w2ui-col-header, .w2ui-grid-fcolumns .w2ui-col-header").removeClass("w2ui-col-selected");for(let e=parseInt(l[0]);e<=parseInt(l[1]);e++)query(p.box).find("#grid_"+p.name+"_column_"+e+" .w2ui-col-header").addClass("w2ui-col-selected");query(p.box).find(".w2ui-col-number").not(".w2ui-head").addClass("w2ui-row-selected"),r.colRange=e,p.removeRange("column-selection"),p.addRange({name:"column-selection",range:[{recid:p.records[0].recid,column:l[0]},{recid:p.records[p.records.length-1].recid,column:l[1]}],style:"background-color: rgba(90, 145, 234, 0.1)"})}}}}else{let l=p.get(r.recid,!0);if(!(null==l||p.records[l]&&p.records[l].recid!=r.recid)){let e=p.get(n,!0);if(null!=e){let i=parseInt(r.column),s=parseInt(("TD"==t.target.tagName.toUpperCase()?query(t.target):query(t.target).parents("td")).attr("col"));isNaN(i)&&isNaN(s)&&(i=0,s=p.columns.length-1),l>e&&(o=l,l=e,e=o);var h,n="ind1:"+l+",ind2;"+e+",col1:"+i+",col2:"+s;if(r.range!=n){r.range=n;for(let t=l;t<=e;t++)if(!(0s&&(h=i,i=s,s=h);for(let e=i;e<=s;e++)p.columns[e].hidden||a.push({recid:p.records[t].recid,column:parseInt(e)})}else a.push(p.records[t].recid);if("row"!=p.selectType){var d=p.getSelection();let e=[];for(let i=0;i{delete p.last.cancelClick},1),!query(t.target).parents().hasClass(".w2ui-head")&&!query(t.target).hasClass(".w2ui-head")){if(i&&-1!=["select","select-column"].indexOf(i.type)){if(null!=i.colRange&&!0!==c.isCancelled){var s=i.colRange.split("-"),l=[];for(let e=0;ee?p.records.splice(e,0,i):p.records.splice(e-1,0,i)),p.sortData=[],query(p.box).find(`#grid_${p.name}_columns .w2ui-col-header`).removeClass("w2ui-col-sorted"),n(),t.finish()}else n()}delete p.last.move,query(document).off(".w2ui-"+p.name)}}function n(){query(p.box).find(`#grid_${p.name}_ghost`).remove(),query(p.box).find(`#grid_${p.name}_ghost_line`).remove(),p.refresh(),delete p.last.move}}}destroy(){var e=this.trigger("destroy",{target:this.name});!0!==e.isCancelled&&(query(this.box).off(),"object"==typeof this.toolbar&&this.toolbar.destroy&&this.toolbar.destroy(),0`+w2utils.lang("records"),i.push({id:"w2ui-skip",text:e,group:!1,icon:"w2ui-icon-empty"})),this.show.saveRestoreState&&i.push({id:"w2ui-stateSave",text:w2utils.lang("Save Grid State"),icon:"w2ui-icon-empty",group:!1},{id:"w2ui-stateReset",text:w2utils.lang("Restore Default State"),icon:"w2ui-icon-empty",group:!1});let t=[];return i.forEach(e=>{e.text=w2utils.lang(e.text),e.checked&&t.push(e.id)}),this.toolbar.set("w2ui-column-on-off",{selected:t,items:i}),i}initColumnDrag(e){if(this.columnGroups&&this.columnGroups.length)throw"Draggable columns are not currently supported with column groups.";let r=this,a={pressed:!1,targetPos:null,columnHead:null},n=(t,e)=>{var i=["w2ui-col-number","w2ui-col-expand","w2ui-col-select"];!0!==e&&i.push("w2ui-head-last");for(let e=0;e{var e=query(r.box).find(".w2ui-grid-ghost");query(r.box).find(".w2ui-intersection-marker").hide(),query(a.ghost).remove(),e.remove(),query(document).off(".colDrag"),a={}};if(e.pageX==a.initialX&&e.pageY==a.initialY)r.columnClick(r.columns[a.originalPos].field,e),s();else{if(!0===(e=r.trigger("columnDragEnd",{originalEvent:e,target:a.columnHead[0],dragData:a})).isCancelled)return!1;t=r.columns[a.originalPos],i=r.columns,a.originalPos!=a.targetPos&&null!=a.targetPos&&(i.splice(a.targetPos,0,w2utils.clone(t)),i.splice(i.indexOf(t),1)),s(),r.refresh(),e.finish({targetColumn:NaN})}}}return query(r.box).off(".colDrag").on("mousedown.colDrag",function(e){if(!a.pressed&&0!==a.numberPreColumnsPresent&&0===e.button){var i,t;if(query(e.target).parents().hasClass("w2ui-head")&&!n(e.target)){if(a.pressed=!0,a.initialX=e.pageX,a.initialY=e.pageY,a.numberPreColumnsPresent=query(r.box).find(".w2ui-head.w2ui-col-number, .w2ui-head.w2ui-col-expand, .w2ui-head.w2ui-col-select").length,a.columnHead=s=query(e.target).closest(".w2ui-head"),a.originalPos=t=parseInt(s.attr("col"),10),!0===(t=r.trigger("columnDragStart",{originalEvent:e,origColumnNumber:t,target:s[0]})).isCancelled)return!1;i=a.columns=query(r.box).find(".w2ui-head:not(.w2ui-head-last)"),query(document).on("mouseup.colDrag",h),query(document).on("mousemove.colDrag",o);var s=r.columns[a.originalPos],s=w2utils.lang("function"==typeof s.text?s.text(s):s.text);a.ghost=query.html(`${s}`)[0],query(document.body).append(a.ghost),query(a.ghost).css({display:"none",left:e.pageX,top:e.pageY,opacity:1,margin:"3px 0 0 20px",padding:"3px","background-color":"white",position:"fixed","z-index":999999}).addClass(".w2ui-grid-ghost"),a.offsets=[];for(let e=0,t=i.length;e + ${this.buttons.search.html} +
    + + + x +
    + +
    + +
    + `,this.toolbar.items.push({id:"w2ui-search",type:"html",html:t,onRefresh:async e=>{await e.complete;var e=query(this.box).find(`#grid_${this.name}_search_all`),t=(w2utils.bindEvents(query(this.box).find(`#grid_${this.name}_search_all, .w2ui-action`),this),w2utils.debounce(e=>{var t=e.target.value;this.liveSearch&&this.last.liveText!=t&&(this.last.liveText=t,this.search(this.last.field,t)),40==e.keyCode&&this.searchSuggest(!0)},250));e.on("change",e=>{this.liveSearch||(this.search(this.last.field,e.target.value),this.searchSuggest(!0,!0,this))}).on("blur",()=>{this.last.liveText=""}).on("keyup",t)}})),Array.isArray(e)&&(t=e.map(e=>e.id),this.show.toolbarAdd&&!t.includes(this.buttons.add.id)&&this.toolbar.items.push(w2utils.extend({},this.buttons.add)),this.show.toolbarEdit&&!t.includes(this.buttons.edit.id)&&this.toolbar.items.push(w2utils.extend({},this.buttons.edit)),this.show.toolbarDelete&&!t.includes(this.buttons.delete.id)&&this.toolbar.items.push(w2utils.extend({},this.buttons.delete)),this.show.toolbarSave&&!t.includes(this.buttons.save.id)&&((this.show.toolbarAdd||this.show.toolbarDelete||this.show.toolbarEdit)&&this.toolbar.items.push({type:"break",id:"w2ui-break2"}),this.toolbar.items.push(w2utils.extend({},this.buttons.save))),e=e.map(e=>this.buttons[e.name]?w2utils.extend({},this.buttons[e.name],e):e)),this.toolbar.items.push(...e),this.toolbar.on("click",e=>{var i=this.trigger("toolbar",{target:e.target,originalEvent:e});if(!0!==i.isCancelled){let t;switch(e.detail.item.id){case"w2ui-reload":if(!0===(t=this.trigger("reload",{target:this.name})).isCancelled)return!1;this.reload(),t.finish();break;case"w2ui-column-on-off":e.detail.subItem?(s=e.detail.subItem.id,["w2ui-stateSave","w2ui-stateReset"].includes(s)?this[s.substring(5)]():"w2ui-skip"!=s&&this.columnOnOff(e,e.detail.subItem.id)):(this.initColumnOnOff(),setTimeout(()=>{query(`#w2overlay-${this.name}_toolbar-drop .w2ui-grid-skip`).off(".w2ui-grid").on("click.w2ui-grid",e=>{e.stopPropagation()}).on("keypress",e=>{13==e.keyCode&&(this.skip(e.target.value),this.toolbar.click("w2ui-column-on-off"))})},100));break;case"w2ui-add":if(!0===(t=this.trigger("add",{target:this.name,recid:null})).isCancelled)return!1;t.finish();break;case"w2ui-edit":{var s=this.getSelection();let e=null;if(1==s.length&&(e=s[0]),!0===(t=this.trigger("edit",{target:this.name,recid:e})).isCancelled)return!1;t.finish();break}case"w2ui-delete":this.delete();break;case"w2ui-save":this.save()}i.finish()}}),this.toolbar.on("refresh",e=>{if("w2ui-search"==e.target){let e=this.searchData;setTimeout(()=>{this.searchInitInput(this.last.field,1==e.length?e[0].value:null)},1)}})}}initResize(){let r=this;query(this.box).find(".w2ui-resizer").off(".grid-col-resize").on("click.grid-col-resize",function(e){e.stopPropagation?e.stopPropagation():e.cancelBubble=!0,e.preventDefault&&e.preventDefault()}).on("mousedown.grid-col-resize",function(e){e=e||window.event,r.last.colResizing=!0,r.last.tmp={x:e.screenX,y:e.screenY,gx:e.screenX,gy:e.screenY,col:parseInt(query(this).attr("name"))},r.last.tmp.tds=query(r.box).find("#grid_"+r.name+'_body table tr:first-child td[col="'+r.last.tmp.col+'"]'),e.stopPropagation?e.stopPropagation():e.cancelBubble=!0,e.preventDefault&&e.preventDefault();for(let e=0;e{r.resizeRecords(),r.scroll()},100),r.last.tmp.tds.css({width:t}),r.last.tmp.x=e.screenX,r.last.tmp.y=e.screenY))}).on("mouseup.grid-col-resize",function(e){query(document).off(".grid-col-resize"),r.resizeRecords(),r.scroll(),i.finish({originalEvent:e}),setTimeout(()=>{r.last.colResizing=!1},1)})}).on("dblclick.grid-col-resize",function(e){let t=parseInt(query(this).attr("name")),i=r.columns[t],s=0;if(!1===i.autoResize)return!0;e.stopPropagation?e.stopPropagation():e.cancelBubble=!0,e.preventDefault&&e.preventDefault(),query(r.box).find('.w2ui-grid-records td[col="'+t+'"] > div',r.box).each(()=>{var e=this.offsetWidth-this.scrollWidth;e{var t=query(e).get(0).parentNode;query(e).css({height:t.clientHeight+"px","margin-left":t.clientWidth-3+"px"})})}resizeBoxes(){var e=query(this.box).find(`#grid_${this.name}_header`),t=query(this.box).find(`#grid_${this.name}_toolbar`),i=query(this.box).find(`#grid_${this.name}_fsummary`),s=query(this.box).find(`#grid_${this.name}_summary`),l=query(this.box).find(`#grid_${this.name}_footer`),r=query(this.box).find(`#grid_${this.name}_body`);this.show.header&&e.css({top:"0px",left:"0px",right:"0px"}),this.show.toolbar&&t.css({top:0+(this.show.header?w2utils.getSize(e,"height"):0)+"px",left:"0px",right:"0px"}),0 div.w2ui-grid-box"),r=query(this.box).find(`#grid_${this.name}_header`),a=query(this.box).find(`#grid_${this.name}_toolbar`),n=query(this.box).find(`#grid_${this.name}_summary`),o=query(this.box).find(`#grid_${this.name}_fsummary`),h=query(this.box).find(`#grid_${this.name}_footer`),d=query(this.box).find(`#grid_${this.name}_body`),u=query(this.box).find(`#grid_${this.name}_columns`),c=query(this.box).find(`#grid_${this.name}_fcolumns`),p=query(this.box).find(`#grid_${this.name}_records`),f=query(this.box).find(`#grid_${this.name}_frecords`),m=query(this.box).find(`#grid_${this.name}_scroll1`);let g=8*String(this.total).length+10,y=(g<34&&(g=34),null!=this.lineNumberWidth&&(g=this.lineNumberWidth),!1),w=!1,b=0;for(let e=0;e table")[0]?.clientHeight??0)+(y?w2utils.scrollBarSize():0)&&(w=!0),this.fixedBody?(e=l[0]?.clientHeight-(this.show.header?w2utils.getSize(r,"height"):0)-(this.show.toolbar?w2utils.getSize(a,"height"):0)-("none"!=n.css("display")?w2utils.getSize(n,"height"):0)-(this.show.footer?w2utils.getSize(h,"height"):0),d.css("height",e+"px")):(r=(e=w2utils.getSize(u,"height")+w2utils.getSize(query(this.box).find("#grid_"+this.name+"_records table"),"height")+(y?w2utils.scrollBarSize():0))+(this.show.header?w2utils.getSize(r,"height"):0)+(this.show.toolbar?w2utils.getSize(a,"height"):0)+("none"!=n.css("display")?w2utils.getSize(n,"height"):0)+(this.show.footer?w2utils.getSize(h,"height"):0),l.css("height",r+"px"),d.css("height",e+"px"),s.css("height",w2utils.getSize(l,"height")+"px"));let v=this.records.length;a="object"!=typeof this.url?this.url:this.url.get;if(0==this.searchData.length||a||(v=this.last.searchIds.length),this.fixedBody||(w=!1),y||w?(u.find(":scope > table > tbody > tr:nth-child(1) td.w2ui-head-last").css("width",w2utils.scrollBarSize()+"px").show(),p.css({top:(0 table > tbody > tr:nth-child(1) td.w2ui-head-last").hide(),p.css({top:(0=this.recordHeight&&(e-=this.recordHeight,t++),this.fixedBody){for(let e=v;e',l+='',i.show.lineNumbers&&(s+=''),i.show.selectColumn&&(s+=''),i.show.expandColumn&&(s+=''),l+='',i.reorderRows&&(l+='');for(let e=0;ei.last.colEnd)&&!a.frozen||(r='',a.frozen?s+=r:l+=r)}s+=' ',l+=' ',query(i.box).find("#grid_"+i.name+"_frecords > table").append(s),query(i.box).find("#grid_"+i.name+"_records > table").append(l)}let _,q;if(0_&&!0!==C.hidden&&(C.hidden=!0,i=!0),C.gridMinWidth<_)&&!0===C.hidden&&(C.hidden=!1,i=!0)}if(!0===i)return void this.refresh();for(let e=0;eparseInt(E.max)&&(E.sizeCalculated=E.max+"px"),$+=parseInt(E.sizeCalculated))}let z=parseInt(_)-parseInt($);if(0 table > tbody > tr:nth-child(1) td.w2ui-head-last").css("width",w2utils.scrollBarSize()+"px").show();let O=1;this.show.lineNumbers&&(O+=g),this.show.selectColumn&&(O+=26),this.show.expandColumn&&(O+=26);for(let e=0;e table > tbody > tr:nth-child(1) td").add(c.find(":scope > table > tbody > tr:nth-child(1) td")).each(e=>{query(e).hasClass("w2ui-col-number")&&query(e).css("width",g+"px");var t=query(e).attr("col");if(null!=t){if("start"==t){let t=0;for(let e=0;e table > tbody > tr").length&&u.find(":scope > table > tbody > tr:nth-child(1) td").add(c.find(":scope > table > tbody > tr:nth-child(1) td")).html("").css({height:"0",border:"0",padding:"0",margin:"0"}),p.find(":scope > table > tbody > tr:nth-child(1) td").add(f.find(":scope > table > tbody > tr:nth-child(1) td")).each(e=>{query(e).hasClass("w2ui-col-number")&&query(e).css("width",g+"px");var t=query(e).attr("col");if(null!=t){if("start"==t){let t=0;for(let e=0;e table > tbody > tr:nth-child(1) td").add(o.find(":scope > table > tbody > tr:nth-child(1) td")).each(e=>{query(e).hasClass("w2ui-col-number")&&query(e).css("width",g+"px");var t=query(e).attr("col");if(null!=t){if("start"==t){let t=0;for(let e=0;e + ${w2utils.lang("Advanced Search")} + + + + + + `;for(let t=0;t",s),s.label=s.caption);var l=``;i+=` + + + "}}return i+=` + + +
    ${w2utils.lang(s.label)||""}${l}`;let e;switch(s.type){case"text":case"alphanumeric":case"hex":case"color":case"list":case"combo":case"enum":e="width: 250px;",-1!=["hex","color"].indexOf(s.type)&&(e="width: 90px;"),i+=``;break;case"int":case"float":case"money":case"currency":case"percent":case"date":case"time":case"datetime":e="width: 90px;","datetime"==s.type&&(e="width: 140px;"),i+=` + `;break;case"select":i+=``}i+=s.text+"
    + + + + +
    `}getOperators(e,t){let i=this.operators[this.operatorsMap[e]]||[],s=(null!=t&&Array.isArray(t)&&(i=t),"");return i.forEach(e=>{let t=e,i=e;Array.isArray(e)?(t=e[1],i=e[0]):w2utils.isPlainObject(e)&&(t=e.text,i=e.oper),null==t&&(t=e),s+=` +`}),s}initOperator(e){let i;var t=this.searches[e],s=this.getSearchData(t.field),l=query(`#w2overlay-${this.name}-search-overlay`),r=l.find(`#grid_${this.name}_range_`+e);let a=l.find(`#grid_${this.name}_field_`+e),n=l.find(`#grid_${this.name}_field2_`+e);var o=l.find(`#grid_${this.name}_operator_`+e).val();switch(a.show(),r.hide(),o){case"between":r.show();break;case"null":case"not null":a.hide(),a.val(o),a.trigger("change")}switch(t.type){case"text":case"alphanumeric":var h=a[0]._w2field;h&&h.reset();break;case"int":case"float":case"hex":case"color":case"money":case"currency":case"percent":case"date":case"time":case"datetime":a[0]._w2field||(new w2field(t.type,{el:a[0],...t.options}),new w2field(t.type,{el:n[0],...t.options}),setTimeout(()=>{a.trigger("keydown"),n.trigger("keydown")},1));break;case"list":case"combo":case"enum":i=t.options,"list"==t.type&&(i.selected={}),"enum"==t.type&&(i.selected=[]),s&&(i.selected=s.value),a[0]._w2field||(h=new w2field(t.type,{el:a[0],...i}),s&&null!=s.text&&h.set({id:s.value,text:s.text}));break;case"select":i='';for(let e=0;e'+t+""}else i+='"}a.html(i)}}initSearches(){var s=query(`#w2overlay-${this.name}-search-overlay`);for(let t=0;t{w2utils.isPlainObject(e)&&(i[t]=e.oper)}),r&&r.operator&&(e=r.operator);var l=this.defaultOperator[this.operatorsMap[l.type]],l=(-1==i.indexOf(e)&&(e=l),s.find(`#grid_${this.name}_operator_`+t).val(e),this.initOperator(t),s.find(`#grid_${this.name}_field_`+t)),a=s.find(`#grid_${this.name}_field2_`+t);null!=r&&(Array.isArray(r.value)?["in","not in"].includes(r.operator)?l[0]._w2field.set(r.value):(l.val(r.value[0]).trigger("change"),a.val(r.value[1]).trigger("change")):null!=r.value&&l.val(r.value).trigger("change"))}s.find(".w2ui-grid-search-advanced *[rel=search]").on("keypress",e=>{13==e.keyCode&&(this.search(),w2tooltip.hide(this.name+"-search-overlay"))})}getColumnsHTML(){let h=this,e="",t="";var i,s,l;return this.show.columnHeaders&&(t=0 ",h.columnGroups[e]),h.columnGroups[e].text=h.columnGroups[e].caption);""!=h.columnGroups[h.columnGroups.length-1].text&&h.columnGroups.push({text:""});h.show.lineNumbers&&(t+='
     
    ');h.show.selectColumn&&(t+='
     
    ');h.show.expandColumn&&(t+='
     
    ');let r=0;s+=``,h.reorderRows&&(s+='
     
    ');for(let e=0;e",n),n.text=n.caption);let i=0;for(let e=r;e`);var o=w2utils.lang("function"==typeof n.text?n.text(n):n.text);l=``+e+`
    `+`
    `+(o||" ")+"
    "}else{o=w2utils.lang("function"==typeof a.text?a.text(a):a.text);l=``+`
    ${o||" "}
    `+""}n&&n.frozen?t+=l:s+=l}r+=a.span}return t+="",s+=``,[t,s]}(),s=r(!1),e=l[0]+i[0]+s[0],l[1]+i[1]+s[1]):(l=r(!0),e=l[0],l[1])),[e,t];function r(t){let i="",s="",l=(h.show.lineNumbers&&(i+='
    #
    '),h.show.selectColumn&&(i+='
    '+`
    "),h.show.expandColumn&&(i+='
     
    '),0),r=0,a;s+=``,h.reorderRows&&(s+='
     
    ');for(let e=0;e ",o),o.text=o.caption),null==o.size&&(o.size="100%"),e==r&&(a=h.columnGroups[l++]||{},r+=a.span),(eh.last.colEnd)&&!o.frozen||o.hidden||!0===a.main&&!t||(n=h.getColumnCellHTML(e),o&&o.frozen?i+=n:s+=n)}return i+='
     
    ',s+='
     
    ',i+="",s+="",[i,s]}}getColumnCellHTML(t){var i=this.columns[t];if(null==i)return"";var e=!this.reorderColumns||this.columnGroups&&this.columnGroups.length?"":" w2ui-col-reorderable ";let s="";for(let e=0;e'+(!1!==i.resizable?'
    ':"")+'
    '+(n||" ")+"
    "}columnTooltipShow(e,t){var i=query(this.box).find("#grid_"+this.name+"_column_"+e),e=this.columns[e],s=this.columnTooltip;w2tooltip.show({name:this.name+"-column-tooltip",anchor:i.get(0),html:e?.tooltip,position:s})}columnTooltipHide(e,t){w2tooltip.hide(this.name+"-column-tooltip")}getRecordsHTML(){let e=this.records.length;var t="object"!=typeof this.url?this.url:this.url.get,t=((e=0==this.searchData.length||t?e:this.last.searchIds.length)>this.vs_start?this.last.show_extra=this.vs_extra:this.last.show_extra=this.vs_start,query(this.box).find(`#grid_${this.name}_records`));let i=Math.floor((t.get(0)?.clientHeight||0)/this.recordHeight)+this.last.show_extra+1;(!this.fixedBody||i>e)&&(i=e);var s=this.getRecordHTML(-1,0);let l=""+s[0],r="
    "+s[1];l+='',r+='';for(let e=0;e
    ',r+=' ',this.last.range_start=0,this.last.range_end=i,[l,r]}getSummaryHTML(){if(0!==this.summary.length){var s=this.getRecordHTML(-1,0);let t=""+s[0],i="
    "+s[1];for(let e=0;ethis.last.scrollLeft&&null==l&&(l=e),t+s-30>this.last.scrollLeft+a&&null==r&&(r=e),t+=s);null==r&&(r=this.columns.length-1)}if(null!=l&&(l<0&&(l=0),r<0&&(r=0),l==r&&(0this.last.colStart)for(let e=this.last.colStart;er;e--)n.find("#grid_"+this.name+"_columns #grid_"+this.name+"_column_"+e).remove(),n.find("#grid_"+this.name+'_records td[col="'+e+'"]').remove(),n.find("#grid_"+this.name+'_summary td[col="'+e+'"]').remove();if(l=l;s--)this.columns[s]&&(this.columns[s].frozen||this.columns[s].hidden)||(e.after(this.getColumnCellHTML(s)),f.each(e=>{var t=query(e).parent().attr("index");let i='';null!=t&&(i=this.getCellHTML(parseInt(t),s,!1)),query(e).after(i)}),g.each(e=>{var t=query(e).parent().attr("index");let i='';null!=t&&(i=this.getCellHTML(parseInt(t),s,!0)),query(e).after(i)}));if(r>this.last.colEnd)for(let s=this.last.colEnd+1;s<=r;s++)this.columns[s]&&(this.columns[s].frozen||this.columns[s].hidden)||(t.before(this.getColumnCellHTML(s)),m.each(e=>{var t=query(e).parent().attr("index");let i='';null!=t&&(i=this.getCellHTML(parseInt(t),s,!1)),query(e).before(i)}),y.each(e=>{var t=query(e).parent().attr("index")||-1,t=this.getCellHTML(parseInt(t),s,!0);query(e).before(t)}));this.last.colStart=l,this.last.colEnd=r}else{this.last.colStart=l,this.last.colEnd=r;var o=this.getColumnsHTML(),w=this.getRecordsHTML(),c=this.getSummaryHTML(),p=n.find(`#grid_${this.name}_columns`);let e=n.find(`#grid_${this.name}_records`);var b=n.find(`#grid_${this.name}_frecords`);let t=n.find(`#grid_${this.name}_summary`);p.find("tbody").html(o[1]),b.html(w[0]),e.prepend(w[1]),null!=c&&t.html(c[1]),setTimeout(()=>{e.find(":scope > table").filter(":not(table:first-child)").remove(),t[0]&&(t[0].scrollLeft=this.last.scrollLeft)},1)}this.resizeRecords()}let v=this.records.length;if(v>this.total&&-1!==this.total&&(v=this.total),0!==(v=0==this.searchData.length||i?v:this.last.searchIds.length)&&0!==d.length&&0!==d.prop("clientHeight")){v>this.vs_start?this.last.show_extra=this.vs_extra:this.last.show_extra=this.vs_start;let e=Math.round(d.prop("scrollTop")/this.recordHeight+1),t=e+(Math.round(d.prop("clientHeight")/this.recordHeight)-1);if(e>v&&(e=v),t>=v-1&&(t=v),query(this.box).find("#grid_"+this.name+"_footer .w2ui-footer-right").html((this.show.statusRange?w2utils.formatNumber(this.offset+e)+"-"+w2utils.formatNumber(this.offset+t)+(-1!=this.total?" "+w2utils.lang("of")+" "+w2utils.formatNumber(this.total):""):"")+(i&&this.show.statusBuffered?" ("+w2utils.lang("buffered")+" "+w2utils.formatNumber(v)+(0this.total&&-1!=this.total&&(i=this.total);var x=d.find("#grid_"+this.name+"_rec_top"),_=d.find("#grid_"+this.name+"_rec_bottom"),q=u.find("#grid_"+this.name+"_frec_top"),C=u.find("#grid_"+this.name+"_frec_bottom"),p=(-1!=String(x.next().prop("id")).indexOf("_expanded_row")&&(x.next().remove(),q.next().remove()),this.total>i&&-1!=String(_.prev().prop("id")).indexOf("_expanded_row")&&(_.prev().remove(),C.prev().remove()),parseInt(x.next().attr("line"))),o=parseInt(_.prev().attr("line"));let e,s,l,r,a;if(p=p-this.last.show_extra+2&&1i))break;s.remove(),l.remove()}e=d.find("#grid_"+this.name+"_rec_top").next(),"bottom"==(r=e.attr("line"))&&(r=i);for(let e=parseInt(r)-1;e>=t;e--)this.records[e-1]&&((l=this.records[e-1].w2ui)&&!Array.isArray(l.children)&&(l.expanded=!1),a=this.getRecordHTML(e-1,e),x.after(a[1]),q.after(a[0]))}k(),setTimeout(()=>{this.refreshRanges()},0);b=(t-1)*this.recordHeight;let n=(v-i)*this.recordHeight;function k(){h.markSearch&&(clearTimeout(h.last.marker_timer),h.last.marker_timer=setTimeout(()=>{var t=[];for(let e=0;e{var t=query(h.box).find('td[col="'+e.col+'"]:not(.w2ui-head)');w2utils.marker(t,e.search)})},50))}n<0&&(n=0),x.css("height",b+"px"),q.css("height",b+"px"),_.css("height",n+"px"),C.css("height",n+"px"),this.last.range_start=t,this.last.range_end=i,Math.floor(d.prop("scrollTop")/this.recordHeight)+Math.floor(d.prop("clientHeight")/this.recordHeight)+10>v&&!0!==this.last.pull_more&&(v
    '),h.last.pull_more=!0,h.last.fetch.offset+=h.limit,h.request("load")}).find("td").html(h.autoLoad?'
    ':'
    '+w2utils.lang("Load ${count} more...",{count:h.limit})+"
    "))}}}getRecordHTML(r,a,n){let o="",h="";var d=this.last.selection;let u;if(-1==r){o+='
    ',h+='',this.show.lineNumbers&&(o+=''),this.show.selectColumn&&(o+=''),this.show.expandColumn&&(o+=''),h+='',this.reorderRows&&(h+='');for(let e=0;e';t.frozen&&!t.hidden?o+=i:t.hidden||ethis.last.colEnd||(h+=i)}o+='',h+=''}else{var c="object"!=typeof this.url?this.url:this.url.get;if(!0!==n){if(0=this.last.searchIds.length)return"";r=this.last.searchIds[r]}else if(r>=this.records.length)return"";u=this.records[r]}else{if(r>=this.summary.length)return"";u=this.summary[r]}if(!u)return"";null==u.recid&&null!=this.recid&&null!=(c=this.parseField(u,this.recid))&&(u.recid=c);let e=!1,t=(-1!=d.indexes.indexOf(r)&&(e=!0),u.w2ui?u.w2ui.style:""),i=(null!=t&&"string"==typeof t||(t=""),u.w2ui?u.w2ui.class:"");if(null!=i&&"string"==typeof i||(i=""),o+='",h+='",this.show.lineNumbers&&(o+='"),this.show.selectColumn&&(o+='"),this.show.expandColumn){let e="";e=!0===u.w2ui?.expanded?"-":"+","none"!=u.w2ui?.expanded&&Array.isArray(u.w2ui?.children)&&u.w2ui?.children.length||(e="+"),"spinner"==u.w2ui?.expanded&&(e='
    '),o+='"}h+='',this.reorderRows&&(h+='");let s=0,l=0;for(;;){let e=1;var p,f=this.columns[s];if(null==f)break;if(f.hidden)s++,0this.last.colEnd)||f.frozen){if(u.w2ui&&"object"==typeof u.w2ui.colspan){var m=parseInt(u.w2ui.colspan[f.field])||null;if(1=this.columns.length);e++)this.columns[e].hidden&&t++;e=m-t,l=m-1}}var g=this.getCellHTML(r,s,n,e);f.frozen?o+=g:h+=g}s++}}o+='',h+=''}return o+="",h+="",[o,h]}getLineHTML(e){return"
    "+e+"
    "}getCellHTML(i,s,l,e){let r=this,a=this.columns[s];if(null==a)return"";let n=(!0!==l?this.records:this.summary)[i],{value:t,style:o,className:h,attr:d,divAttr:u}=this.getCellValue(i,s,l,!0);var c=-1!==i?this.getCellEditable(i,s):"";let p="max-height: "+parseInt(this.recordHeight)+"px;"+(a.clipboardCopy?"margin-right: 20px":"");var f=!l&&n?.w2ui?.changes&&null!=n.w2ui.changes[a.field],m=this.last.selection;let g=!1,y="";if(-1!=m.indexes.indexOf(i)&&(g=!0),null==e&&(e=n?.w2ui?.colspan&&n.w2ui.colspan[a.field]?n.w2ui.colspan[a.field]:1),0===s&&Array.isArray(n?.w2ui?.children)){let t=0,e=this.get(n.w2ui.parent_recid,!0);for(;;){if(null==e)break;t++;var w=this.records[e].w2ui;if(null==w||null==w.parent_recid)break;e=this.get(w.parent_recid,!0)}if(n.w2ui.parent_recid)for(let e=0;e';var b=0`}if(!0===a.info&&(a.info={}),null!=a.info){let e="w2ui-icon-info",t=("function"==typeof a.info.icon?e=a.info.icon(n,{self:this,index:i,colIndex:s,summary:!!l}):"object"==typeof a.info.icon?e=a.info.icon[this.parseField(n,a.field)]||"":"string"==typeof a.info.icon&&(e=a.info.icon),a.info.style||"");"function"==typeof a.info.style?t=a.info.style(n,{self:this,index:i,colIndex:s,summary:!!l}):"object"==typeof a.info.style?t=a.info.style[this.parseField(n,a.field)]||"":"string"==typeof a.info.style&&(t=a.info.style),y+=``}let v=t,x=(c&&-1!=["checkbox","check"].indexOf(c.type)&&(p+="text-align: center;",v=``,y=""),null==(v=`
    ${y}${String(v)}
    `)&&(v=""),"string"==typeof a.render&&(b=a.render.toLowerCase().split(":"),-1!=["number","int","float","money","currency","percent","size"].indexOf(b[0]))&&(o+="text-align: right;"),n?.w2ui&&("object"==typeof n.w2ui.style&&("string"==typeof n.w2ui.style[s]&&(o+=n.w2ui.style[s]+";"),"string"==typeof n.w2ui.style[a.field])&&(o+=n.w2ui.style[a.field]+";"),"object"==typeof n.w2ui.class)&&("string"==typeof n.w2ui.class[s]&&(h+=n.w2ui.class[s]+" "),"string"==typeof n.w2ui.class[a.field])&&(h+=n.w2ui.class[a.field]+" "),!1);g&&m.columns[i]?.includes(s)&&(x=!0);let _;return a.clipboardCopy&&(_=''),v='
    ",v=-1===i&&!0===l?'":v}clipboardCopy(e,t,i){var s=(i?this.summary:this.records)[e],l=this.columns[t];let r=l?this.parseField(s,l.field):"";"function"==typeof l.clipboardCopy&&(r=l.clipboardCopy(s,{self:this,index:e,colIndex:t,summary:!!i})),query(this.box).find("#grid_"+this.name+"_focus").text(r).get(0).select(),document.execCommand("copy")}showBubble(s,l,r){var a=this.columns[l].info;if(a){let i="";var n=this.records[s],e=query(this.box).find(`${r?".w2ui-grid-summary":""} #grid_${this.name}_data_${s}_${l} .w2ui-info`);if(this.last.bubbleEl&&w2tooltip.hide(this.name+"-bubble"),this.last.bubbleEl=e,null==a.fields){a.fields=[];for(let e=0;e';else{let e=this.getColumn(h[0]),t=(e=null==e?{field:h[0],caption:h[0]}:e)?this.parseField(n,e.field):"";1a.maxLength&&(t=t.substr(0,a.maxLength)+"..."),i+="")}}i+="
    "+(!0!==n?this.getLineHTML(a,u):"")+"'+(!0===n||u.w2ui&&!0===u.w2ui.hideCheckBox?"":'
    ')+"
    '+(!0!==n?`
    ${e}
    `:"")+"
    '+(!0!==n?'
     
    ':"")+"
    "+v+(_&&w2utils.stripTags(v)?_:"")+"
    "+e.text+""+((0===t?"0":t)||"")+"
    "}else if(w2utils.isPlainObject(t)){for(var d in i='',t){var u=t[d];if(""==u||"-"==u||"--"==u||"---"==u)i+='';else{var c=String(u).split(":");let e=this.getColumn(c[0]),t=(e=null==e?{field:c[0],caption:c[0]}:e)?this.parseField(n,e.field):"";1a.maxLength&&(t=t.substr(0,a.maxLength)+"..."),i+="")}}i+="
    "+d+""+((0===t?"0":t)||"")+"
    "}return w2tooltip.show(w2utils.extend({name:this.name+"-bubble",html:i,anchor:e.get(0),position:"top|bottom",class:"w2ui-info-bubble",style:"",hideOn:["doc-click"]},a.options??{})).hide(()=>[this.last.bubbleEl=null])}}getCellEditable(e,t){var i=this.columns[t],s=this.records[e];if(!s||!i)return null;let l=s.w2ui?s.w2ui.editable:null;return!1===l?null:(null!=l&&!0!==l||"function"==typeof(l=0 '}status(i){if(null!=i)query(this.box).find(`#grid_${this.name}_footer`).find(".w2ui-footer-left").html(i);else{let t="";i=this.getSelection();if(0{query(this.box).find("#grid_"+this.name+"_empty_msg").remove(),w2utils.lock(...i)},10)}unlock(e){setTimeout(()=>{query(this.box).find(".w2ui-message").hasClass("w2ui-closing")||w2utils.unlock(this.box,e)},25)}stateSave(e){var t={columns:[],show:w2utils.clone(this.show),last:{search:this.last.search,multi:this.last.multi,logic:this.last.logic,label:this.last.label,field:this.last.field,scrollTop:this.last.scrollTop,scrollLeft:this.last.scrollLeft},sortData:[],searchData:[]};let l;for(let e=0;e{this.stateColProps[e]&&(l=void 0!==i[e]?i[e]:this.colTemplate[e]||null,s[e]=l)}),t.columns.push(s)}for(let e=0;e{s||(0=this.columns.length)return null==(e=this.nextRow(e))?e:this.nextCell(e,-1,i);var s=this.records[e].w2ui,l=this.columns[t],s=s&&s.colspan&&!isNaN(s.colspan[l.field])?parseInt(s.colspan[l.field]):1;if(null==l)return null;if(l&&l.hidden||0===s)return this.nextCell(e,t,i);if(i){l=this.getCellEditable(e,t);if(null==l||-1!=["checkbox","check"].indexOf(l.type))return this.nextCell(e,t,i)}return{index:e,colIndex:t}}prevCell(e,t,i){t-=1;if(t<0)return null==(e=this.prevRow(e))?e:this.prevCell(e,this.columns.length,i);if(t<0)return null;var s=this.records[e].w2ui,l=this.columns[t],s=s&&s.colspan&&!isNaN(s.colspan[l.field])?parseInt(s.colspan[l.field]):1;if(null==l)return null;if(l&&l.hidden||0===s)return this.prevCell(e,t,i);if(i){l=this.getCellEditable(e,t);if(null==l||-1!=["checkbox","check"].indexOf(l.type))return this.prevCell(e,t,i)}return{index:e,colIndex:t}}nextRow(e,t,i){var s=this.last.searchIds;let l=null;if(-1==(i=null==i?1:i))return this.records.length-1;if(e+ithis.records.length)break;e+=i}var r=this.records[e].w2ui,a=this.columns[t],r=r&&r.colspan&&null!=a&&!isNaN(r.colspan[a.field])?parseInt(r.colspan[a.field]):1;l=0===r?this.nextRow(e,t,i):e}return l}prevRow(e,t,i){var s=this.last.searchIds;let l=null;if(-1==(i=null==i?1:i))return 0;if(0<=e-i&&0===s.length||0s[0]){if(e-=i,0{-1==i.indexOf(e)&&-1!=["label","attr","style","text","span","page","column","anchor","group","groupStyle","groupTitleStyle","groupCollapsible"].indexOf(e)&&(t.html[e]=t[e],delete t[e])}),t}function h(t,i){let s=["style","html"];Object.keys(t).forEach(e=>{-1==s.indexOf(e)&&-1!=["span","column","attr","text","label"].indexOf(e)&&t[e]&&!i.html[e]&&(i.html[e]=t[e])})}r=[],Object.keys(e).forEach(i=>{let s=e[i];if("group"==s.type){if(s.text=i,w2utils.isPlainObject(s.fields)){let i=s.fields;s.fields=[],Object.keys(i).forEach(e=>{let t=i[e];t.field=e,s.fields.push(o(t))})}r.push(s)}else if("tab"==s.type){let e={id:i,text:i},t=(s.style&&(e.style=s.style),n.push(e),l(s.fields).fields);t.forEach(e=>{e.html=e.html||{},e.html.page=n.length-1,h(s,e)}),r.push(...t)}else s.field=i,r.push(o(s))})}r.forEach(s=>{if("group"==s.type){let i={group:s.text||"",groupStyle:s.style||"",groupTitleStyle:s.titleStyle||"",groupCollapsible:!0===s.collapsible};Array.isArray(s.fields)&&s.fields.forEach(e=>{let t=w2utils.clone(e);null==t.html&&(t.html={}),w2utils.extend(t.html,i),Array("span","column","attr","label","page").forEach(e=>{null==t.html[e]&&null!=s[e]&&(t.html[e]=s[e])}),null==t.field&&null!=t.name&&(console.log("NOTICE: form field.name property is deprecated, please use field.field. Field ->",s),t.field=t.name),a.push(t)})}else{let e=w2utils.clone(s);null==e.field&&null!=e.name&&(console.log("NOTICE: form field.name property is deprecated, please use field.field. Field ->",s),e.field=e.name),a.push(e)}});return{fields:a,tabs:n}}(r),this.fields=e.fields,!n)&&0e.text()).then(e=>{this.formHTML=e,this.isGenerated=!0,this.box&&this.render(this.box)}):this.formURL||this.formHTML?this.formHTML&&(this.isGenerated=!0):(this.formHTML=this.generateHTML(),this.isGenerated=!0),"string"==typeof this.box&&(this.box=query(this.box).get(0)),this.box&&this.render(this.box)}get(t,i){if(0===arguments.length){var s=[];for(let e=0;ee[t],s)}catch(e){}return e}return this.record[t]}setValue(e,l){if((""===l||null==l||Array.isArray(l)&&0===l.length||w2utils.isPlainObject(l)&&0==Object.keys(l).length)&&(l=null),!this.nestedFields)return this.record[e]=l,!0;try{let s=this.record;return String(e).split(".").map((e,t,i)=>{i.length-1!==t?s=s[e]||(s[e]={},s[e]):s[e]=l}),!0}catch(e){return!1}}getFieldValue(e){let s=this.get(e);if(null!=s){var l=s.el;let t=this.getValue(e);e=this.getValue(e,!0);let i=l.value;["int","float","percent","money","currency"].includes(s.type)&&(i=s.w2field.clean(i)),["radio"].includes(s.type)&&(r=query(l).closest("div").find("input:checked").get(0),i=r?s.options.items[query(r).data("index")].id:null),["toggle","checkbox"].includes(s.type)&&(i=l.checked),-1!==["check","checks"].indexOf(s.type)&&(i=[],0<(r=query(l).closest("div").find("input:checked")).length&&r.each(e=>{e=s.options.items[query(e).data("index")];i.push(e.id)}),Array.isArray(t)||(t=[]));var r=l._w2field?.selected;if(["list","enum","file"].includes(s.type)&&r){var a=r,n=t;if(Array.isArray(a)){i=[];for(let e=0;e{var t=query(e).find(".w2ui-map.key").val(),e=query(e).find(".w2ui-map.value").val();"map"==s.type?i[t]=e:i.push(e)})),{current:i,previous:t,original:e}}}setFieldValue(e,r){let a=this.get(e);if(null!=a){var s=a.el;switch(a.type){case"toggle":case"checkbox":s.checked=!!r;break;case"radio":{r=r?.id??r;let i=query(s).closest("div").find("input");a.options.items.forEach((e,t)=>{e.id===r&&i.filter(`[data-index="${t}"]`).prop("checked",!0)});break}case"check":case"checks":{r=(r=Array.isArray(r)?r:null!=r?[r]:[]).map(e=>e?.id??e);let i=query(s).closest("div").find("input");a.options.items.forEach((e,t)=>{i.filter(`[data-index="${t}"]`).prop("checked",!!r.includes(e.id))});break}case"list":case"combo":let t=r;null==t?.id&&Array.isArray(a.options?.items)&&a.options.items.forEach(e=>{e.id===r&&(t=e)}),t!=r&&this.setValue(a.name,t),"list"==a.type?(a.w2field.selected=t,a.w2field.refresh()):a.el.value=t?.text??r;break;case"enum":case"file":{let s=[...r=Array.isArray(r)?r:null!=r?[r]:[]],l=!1;s.forEach((t,i)=>{null==t?.id&&Array.isArray(a.options.items)&&a.options.items.forEach(e=>{e.id==t&&(s[i]=e,l=!0)})}),l&&this.setValue(a.name,s),a.w2field.selected=s,a.w2field.refresh();break}case"map":case"array":"map"!=a.type||null!=r&&w2utils.isPlainObject(r)||(this.setValue(a.field,{}),r=this.getValue(a.field)),"array"!=a.type||null!=r&&Array.isArray(r)||(this.setValue(a.field,[]),r=this.getValue(a.field));var i=query(a.el).parent().find(".w2ui-map-container");a.el.mapRefresh(r,i);break;case"div":case"custom":query(s).html(r);break;case"html":case"empty":break;default:s.value=r??""}}}show(){var t=[];for(let e=0;e{!function(e){let t=!0;return e.each(e=>{"none"!=e.style.display&&(t=!1)}),t}(query(e).find(".w2ui-field"))?query(e).show():query(e).hide()})}change(){Array.from(arguments).forEach(e=>{e=this.get(e);e.$el&&e.$el.change()})}reload(e){return("object"!=typeof this.url?this.url:this.url.get)&&null!=this.recid?this.request(e):("function"==typeof e&&e(),new Promise(e=>{e()}))}clear(){0!=arguments.length?Array.from(arguments).forEach(e=>{let s=this.record;String(e).split(".").map((e,t,i)=>{i.length-1!==t?s=s[e]:delete s[e]}),this.refresh(e)}):(this.recid=null,this.record={},this.original=null,this.refresh(),this.hideErrors())}error(e){var t=this.trigger("error",{target:this.name,message:e,fetchCtrl:this.last.fetchCtrl,fetchOptions:this.last.fetchOptions});!0!==t.isCancelled&&(setTimeout(()=>{this.message(e)},1),t.finish())}message(e){return w2utils.message({owner:this,box:this.box,after:".w2ui-form-header"},e)}confirm(e){return w2utils.confirm({owner:this,box:this.box,after:".w2ui-form-header"},e)}validate(e){null==e&&(e=!0);var t=[];for(let e=0;e{var i=w2utils.extend({anchorClass:"w2ui-error",class:"w2ui-light",position:"right|left",hideOn:["input"]},t.options);if(null!=t.field){let e=t.field.el;"radio"===t.field.type?e=query(t.field.el).closest("div").get(0):["enum","file"].includes(t.field.type),w2tooltip.show(w2utils.extend({anchor:e,name:`${this.name}-${t.field.field}-error`,html:t.error},i))}}),query(e[0].field.$el).parents(".w2ui-page").off(".hideErrors").on("scroll.hideErrors",e=>{this.hideErrors()}))}hideErrors(){this.fields.forEach(e=>{w2tooltip.hide(`${this.name}-${e.field}-error`)})}getChanges(){let e={};return e=null!=this.original&&"object"==typeof this.original&&0!==Object.keys(this.record).length?function e(t,i,s){if(Array.isArray(t)&&Array.isArray(i))for(;t.length{if(-1!=["list","combo","enum"].indexOf(e.type)){var t={nestedFields:!0,record:s};let i=this.getValue.call(t,e.field);w2utils.isPlainObject(i)&&null!=i.id&&this.setValue.call(t,e.field,i.id),Array.isArray(i)&&i.forEach((e,t)=>{w2utils.isPlainObject(e)&&e.id&&(i[t]=e.id)})}var i;"map"==e.type&&(t={nestedFields:!0,record:s},(t=this.getValue.call(t,e.field))._order)&&delete t._order,"file"==e.type&&(t={nestedFields:!0,record:s},(i=this.getValue.call(t,e.field)??[]).forEach(e=>{delete e.file,delete e.modified}),this.setValue.call(t,e.field,i))}),!0===e&&Object.keys(s).forEach(e=>{this.get(e)||delete s[e]}),s}request(e,i){let s=this,l,r;var a=new Promise((e,t)=>{l=e,r=t});if("function"==typeof e&&(i=e,e=null),null==e&&(e={}),this.url&&("object"!=typeof this.url||this.url.get)){var n={action:"get"},e=(n.recid=this.recid,n.name=this.name,w2utils.extend(n,this.postData),w2utils.extend(n,e),this.trigger("request",{target:this.name,url:this.url,httpMethod:"GET",postData:n,httpHeaders:this.httpHeaders}));if(!0!==e.isCancelled){this.record={},this.original=null,this.lock(w2utils.lang(this.msgRefresh));let t=e.detail.url;if("object"==typeof t&&t.get&&(t=t.get),this.last.fetchCtrl)try{this.last.fetchCtrl.abort()}catch(e){}if(0!=Object.keys(this.routeData).length){var o=w2utils.parseRoute(t);if(0{200!=e?.status?e&&h(e):e.json().catch(h).then(e=>{var t=s.trigger("load",{target:s.name,fetchCtrl:this.last.fetchCtrl,fetchOptions:this.last.fetchOptions,data:e});!0!==t.isCancelled&&(null==e.error&&"error"===e.status&&(e.error=!0),e.record||Object.assign(e,{record:w2utils.clone(e)}),!0===e.error?s.error(w2utils.lang(e.message??this.msgServerError)):s.record=w2utils.clone(e.record),s.unlock(),t.finish(),s.refresh(),s.setFocus(),"function"==typeof i&&i(e),l(e))})}),e.finish(),a;function h(e){var t;"AbortError"!==e.name&&(s.unlock(),!0!==(t=s.trigger("error",{response:e,fetchCtrl:s.last.fetchCtrl,fetchOptions:s.last.fetchOptions})).isCancelled)&&(e.status&&200!=e.status?s.error(e.status+": "+e.statusText):(console.log("ERROR: Server request failed.",e,". ","Expected Response:",{error:!1,record:{field1:1,field2:"item"}},"OR:",{error:!0,message:"Error description"}),s.error(String(e))),t.finish(),r(e))}}}}submit(e,t){return this.save(e,t)}save(e,i){let s=this,l,r;var a=new Promise((e,t)=>{l=e,r=t}),n=("function"==typeof e&&(i=e,e=null),s.validate(!0));if(0===n.length)if(null==e&&(e={}),!s.url||"object"==typeof s.url&&!s.url.save)console.log("ERROR: Form cannot be saved because no url is defined.");else{s.lock(w2utils.lang(s.msgSaving)+' ');n={action:"save"},e=(n.recid=s.recid,n.name=s.name,w2utils.extend(n,s.postData),w2utils.extend(n,e),n.record=w2utils.clone(s.record),s.trigger("submit",{target:s.name,url:s.url,httpMethod:this.method??"POST",postData:n,httpHeaders:s.httpHeaders}));if(!0!==e.isCancelled){let t=e.detail.url;if("object"==typeof t&&t.save&&(t=t.save),s.last.fetchCtrl&&s.last.fetchCtrl.abort(),0{s.unlock(),200!=e?.status?h(e??{}):e.json().catch(h).then(e=>{var t=s.trigger("save",{target:s.name,fetchCtrl:this.last.fetchCtrl,fetchOptions:this.last.fetchOptions,data:e});!0!==t.isCancelled&&(!0===e.error?s.error(w2utils.lang(e.message??this.msgServerError)):s.original=null,t.finish(),s.refresh(),"function"==typeof i&&i(e),l(e))})}),e.finish(),a;function h(e){var t;"AbortError"!==e?.name&&(s.unlock(),!0!==(t=s.trigger("error",{response:e,fetchCtrl:s.last.fetchCtrl,fetchOptions:s.last.fetchOptions})).isCancelled)&&(e.status&&200!=e.status?s.error(e.status+": "+e.statusText):(console.log("ERROR: Server request failed.",e,". ","Expected Response:",{error:!1,record:{field1:1,field2:"item"}},"OR:",{error:!0,message:"Error description"}),s.error(String(e))),t.finish(),r())}}}}lock(e,t){var i=Array.from(arguments);i.unshift(this.box),w2utils.lock(...i)}unlock(e){var t=this.box;w2utils.unlock(t,e)}lockPage(e,t,i){e=query(this.box).find(".page-"+e);return!!e.length&&(w2utils.lock(e,t,i),!0)}unlockPage(e,t){e=query(this.box).find(".page-"+e);return!!e.length&&(w2utils.unlock(e,t),!0)}goto(e){this.page!==e&&(null!=e&&(this.page=e),!0===query(this.box).data("autoSize")&&(query(this.box).get(0).clientHeight=0),this.refresh())}generateHTML(){let s=[],t="",l,r,a,n;for(let e=0;e",h),h.html.label=h.html.caption),null==h.html.label&&(h.html.label=h.field),h.html=w2utils.extend({label:"",span:6,attr:"",text:"",style:"",page:0,column:0},h.html),null==l&&(l=h.html.page),null==r&&(r=h.html.column);let i=``;switch(h.type){case"pass":case"password":i=i.replace('type="text"','type="password"');break;case"checkbox":i=` + `;break;case"check":case"checks":{null==h.options.items&&null!=h.html.items&&(h.options.items=h.html.items);let t=h.options.items;i="",0<(t=Array.isArray(t)?t:[]).length&&(t=w2utils.normMenu.call(this,t,h));for(let e=0;e + +  ${t[e].text} + +
    `;break}case"radio":{i="",null==h.options.items&&null!=h.html.items&&(h.options.items=h.html.items);let t=h.options.items;0<(t=Array.isArray(t)?t:[]).length&&(t=w2utils.normMenu.call(this,t,h));for(let e=0;e + +  ${t[e].text} + +
    `;break}case"select":{i=`";break}case"textarea":i=``;break;case"toggle":i=` +
    `;break;case"map":case"array":h.html.key=h.html.key||{},h.html.value=h.html.value||{},h.html.tabindex_str=o,i=''+(h.html.text||"")+'
    ';break;case"div":case"custom":i='
    '+(h&&h.html&&h.html.html?h.html.html:"")+"
    ";break;case"html":case"empty":i=h&&h.html?(h.html.html||"")+(h.html.text||""):""}if(""!==t&&(l!=h.html.page||r!=h.html.column||h.html.group&&t!=h.html.group)&&(s[l][r]+="\n \n ",t=""),h.html.group&&t!=h.html.group){let e="";h.html.groupCollapsible&&(e=''),a+='\n
    \n
    "+e+w2utils.lang(h.html.group)+'
    \n
    ',t=h.html.group}if(null==h.html.anchor){let e=null!=h.html.span?"w2ui-span"+h.html.span:"",t=""+w2utils.lang("checkbox"!=h.type?h.html.label:h.html.text)+"";h.html.label||(t=""),a+='\n
    \n '+t+("empty"===h.type?i:"\n
    "+i+("array"!=h.type&&"map"!=h.type?w2utils.lang("checkbox"!=h.type?h.html.text:""):"")+"
    ")+"\n
    "}else s[h.html.page].anchors=s[h.html.page].anchors||{},s[h.html.page].anchors[h.html.anchor]='
    '+("empty"===h.type?i:"
    "+w2utils.lang("checkbox"!=h.type?h.html.label:h.html.text,!0)+i+w2utils.lang("checkbox"!=h.type?h.html.text:"")+"
    ")+"
    ";null==s[h.html.page]&&(s[h.html.page]={}),null==s[h.html.page][h.html.column]&&(s[h.html.page][h.html.column]=""),s[h.html.page][h.html.column]+=a,l=h.html.page,r=h.html.column}if(""!==t&&(s[l][r]+="\n
    \n
    "),this.tabs.tabs)for(let e=0;e",d),d.text=d.caption),d.text&&(u.text=d.text),d.style&&(u.style=d.style),d.class&&(u.class=d.class)):(u.text=i,-1!==["save","update","create"].indexOf(i.toLowerCase())?u.class="w2ui-btn-blue":u.class=""),e+='\n ",n++}e+="\n"}a="";for(let i=0;i',!s[i])return console.log(`ERROR: Page ${i} does not exist`),!1;s[i].before&&(a+=s[i].before),a+='
    ',Object.keys(s[i]).sort().forEach((e,t)=>{e==parseInt(e)&&(a+='
    '+(s[i][e]||"")+"\n
    ")}),a+="\n
    ",s[i].after&&(a+=s[i].after),a+="\n",s[i].anchors&&Object.keys(s[i].anchors).forEach((e,t)=>{a=a.replace(e,s[i].anchors[e])})}return a+=e}toggleGroup(e,t){var i,e=query(this.box).find('.w2ui-group-title[data-group="'+w2utils.base64encode(e)+'"]');0!==e.length&&(i=query(e.prop("nextElementSibling")),(t=void 0===t?"none"==i.css("display"):t)?(i.show(),e.find("span").addClass("w2ui-icon-collapse").removeClass("w2ui-icon-expand")):(i.hide(),e.find("span").addClass("w2ui-icon-expand").removeClass("w2ui-icon-collapse")))}action(e,t){var i=this.actions[e];let s=i;w2utils.isPlainObject(i)&&i.onClick&&(s=i.onClick);e=this.trigger("action",{target:e,action:i,originalEvent:t});!0!==e.isCancelled&&("function"==typeof s&&s.call(this,t),e.finish())}resize(){let o=this;var e=this.trigger("resize",{target:this.name});if(!0!==e.isCancelled){let s=query(this.box).find(":scope > div .w2ui-form-header"),l=query(this.box).find(":scope > div .w2ui-form-toolbar"),r=query(this.box).find(":scope > div .w2ui-form-tabs"),a=query(this.box).find(":scope > div .w2ui-page");var t=query(this.box).find(":scope > div .w2ui-page.page-"+this.page+" > div");let n=query(this.box).find(":scope > div .w2ui-buttons");var{headerHeight:i,tbHeight:h,tabsHeight:d}=u();function u(){var e=""!==o.header?w2utils.getSize(s,"height"):0,t=Array.isArray(o.toolbar?.items)&&0("string"!=typeof e&&console.log("ERROR: Arguments in refresh functions should be field names"),this.get(e,!0))).filter((e,t)=>null!=e):(query(this.box).find("input, textarea, select").each(e=>{var t=null!=query(e).attr("name")?query(e).attr("name"):query(e).attr("id"),i=this.get(t);if(i){var s=query(e).closest(".w2ui-page");if(0{query(e).off("click").on("click",function(e){let t=this.value;this.id&&(t=this.id),this.name&&(t=this.name),c.action(t,e)})});for(let e=0;e{t+=``}),s.$el.html(t)}this.W2FIELD_TYPES.includes(s.type)&&(s.w2field=s.w2field??new w2field(w2utils.extend({},s.options,{type:s.type})),s.w2field.render(s.el)),["map","array"].includes(s.type)&&!function(d){let u;d.el.mapAdd=function(e,t,i){var s=(e.disabled?" readOnly ":"")+(e.html.tabindex_str||""),i=` +
    + ${"map"==e.type?` + ${e.html.key.text||""} + `:""} + + ${e.html.value.text||""} +
    `;t.append(i)},d.el.mapRefresh=function(l,r){let a,n,o;var h;"map"==d.type&&(null==(l=w2utils.isPlainObject(l)?l:{})._order&&(l._order=Object.keys(l)),a=l._order),"array"==d.type&&(Array.isArray(l)||(l=[]),a=l.map((e,t)=>t));for(let e=r.find(".w2ui-map-field").length-1;e>=a.length;e--)r.find(`div[data-index='${e}']`).remove();for(let s=0;se.key==t)).length&&(i=h[0].value),n.val(t),o.val(i),!0!==d.disabled&&!1!==d.disabled||(n.prop("readOnly",!!d.disabled),o.prop("readOnly",!!d.disabled))}var e=a.length,t=r.find(`div[data-index='${e}']`),e=(0!==t.length||n&&""==n.val()&&""==o.val()||n&&(!0===n.prop("readOnly")||!0===n.prop("disabled"))||d.el.mapAdd(d,r,e),!0!==d.disabled&&!1!==d.disabled||(t.find(".key").prop("readOnly",!!d.disabled),t.find(".value").prop("readOnly",!!d.disabled)),query(d.el).get(0)?.nextSibling);query(e).find("input.w2ui-map").off(".mapChange").on("keyup.mapChange",function(e){var t=query(e.target).closest(".w2ui-map-field"),i=t.get(0).nextElementSibling,t=t.get(0).previousElementSibling,s=(13==e.keyCode&&((s=u??i)instanceof HTMLElement&&0<(s=query(s).find("input")).length&&s.get(0).focus(),u=void 0),query(e.target).hasClass("key")?"key":"value");38==e.keyCode&&t&&(query(t).find("input."+s).get(0).select(),e.preventDefault()),40==e.keyCode&&i&&(query(i).find("input."+s).get(0).select(),e.preventDefault())}).on("keydown.mapChange",function(e){38!=e.keyCode&&40!=e.keyCode||e.preventDefault()}).on("input.mapChange",function(e){var e=query(e.target).closest("div"),t=e.data("index"),i=e.get(0).nextElementSibling;if(""==e.find("input").val()||i){if(""==e.find("input").val()&&i){let t=!0;query(i).find("input").each(e=>{""!=e.value&&(t=!1)}),t&&query(i).remove()}}else d.el.mapAdd(d,r,parseInt(t)+1)}).on("change.mapChange",function(e){null==c.original&&(0{t._order.push(e.value)}),c.trigger("change",{target:d.field,field:d.field,originalEvent:e,value:{current:t,previous:i,original:s}}));!0!==l.isCancelled&&("map"==d.type&&(t._order=t._order.filter(e=>""!==e),delete t[""]),"array"==d.type&&(t=t.filter(e=>""!==e)),""==query(e.target).parent().find("input").val()&&(u=e.target),c.setValue(d.field,t),d.el.mapRefresh(t,r),l.finish())})}}(s),this.setFieldValue(s.field,this.getValue(s.name))}}return t.finish(),this.resize(),Date.now()-e}}}render(e){var t=Date.now();let i=this;"string"==typeof e&&(e=query(e).get(0));var s=this.trigger("render",{target:this.name,box:e??this.box});if(!0!==s.isCancelled&&(null!=e&&(0'+(""!==this.header?'
    '+w2utils.lang(this.header)+"
    ":"")+' '+this.formHTML+"",e=(query(this.box).attr("name",this.name).addClass("w2ui-reset w2ui-form").html(e),0this.refresh()):this.refresh(),this.last.observeResize=new ResizeObserver(()=>{this.resize()}),this.last.observeResize.observe(this.box),-1!=this.focus){let e=0,t=()=>{0 input, select, textarea, div > label:nth-child(1) > [type=radio]").filter(":not(.file-input)");null==i[e].offsetParent&&i.length>=e;)e++;i[e]&&(t=query(i[e]))}else"string"==typeof e&&(t=query(this.box).find(`[name='${e}']`));return 0 `,arrow:!1,advanced:null,transparent:!0},this.options=w2utils.extend({},e,t),t=this.options;break;case"date":e={format:w2utils.settings.dateFormat,keyboard:!0,autoCorrect:!0,start:null,end:null,blockDates:[],blockWeekdays:[],colored:{},btnNow:!0},this.options=w2utils.extend({type:"date"},e,t),t=this.options,null==query(this.el).attr("placeholder")&&query(this.el).attr("placeholder",t.format);break;case"time":e={format:w2utils.settings.timeFormat,keyboard:!0,autoCorrect:!0,start:null,end:null,btnNow:!0,noMinutes:!1},this.options=w2utils.extend({type:"time"},e,t),t=this.options,null==query(this.el).attr("placeholder")&&query(this.el).attr("placeholder",t.format);break;case"datetime":e={format:w2utils.settings.dateFormat+"|"+w2utils.settings.timeFormat,keyboard:!0,autoCorrect:!0,start:null,end:null,startTime:null,endTime:null,blockDates:[],blockWeekdays:[],colored:{},btnNow:!0,noMinutes:!1},this.options=w2utils.extend({type:"datetime"},e,t),t=this.options,null==query(this.el).attr("placeholder")&&query(this.el).attr("placeholder",t.placeholder||t.format);break;case"list":case"combo":e={items:[],selected:{},url:null,recId:null,recText:null,method:null,debounce:250,postData:{},minLength:1,cacheMax:250,maxDropHeight:350,maxDropWidth:null,minDropWidth:null,match:"begins",icon:null,iconStyle:"",align:"both",altRows:!0,renderDrop:null,compare:null,filter:!0,hideSelected:!1,prefix:"",suffix:"",msgNoItems:"No matches",msgSearch:"Type to search...",openOnFocus:!1,markSearch:!1,onSearch:null,onRequest:null,onLoad:null,onError:null},"function"==typeof t.items&&(t._items_fun=t.items),t.items=w2utils.normMenu.call(this,t.items),"list"===this.type&&(query(this.el).addClass("w2ui-select"),!w2utils.isPlainObject(t.selected))&&Array.isArray(t.items)&&t.items.forEach(e=>{e&&e.id===t.selected&&(t.selected=w2utils.clone(e))}),t=w2utils.extend({},e,t),this.options=t,w2utils.isPlainObject(t.selected)||(t.selected={}),this.selected=t.selected,query(this.el).attr("autocapitalize","off").attr("autocomplete","off").attr("autocorrect","off").attr("spellcheck","false"),null!=t.selected.text&&query(this.el).val(t.selected.text);break;case"enum":e={items:[],selected:[],max:0,url:null,recId:null,recText:null,debounce:250,method:null,postData:{},minLength:1,cacheMax:250,maxItemWidth:250,maxDropHeight:350,maxDropWidth:null,match:"contains",align:"",altRows:!0,openOnFocus:!1,markSearch:!1,renderDrop:null,renderItem:null,compare:null,filter:!0,hideSelected:!0,style:"",msgNoItems:"No matches",msgSearch:"Type to search...",onSearch:null,onRequest:null,onLoad:null,onError:null,onClick:null,onAdd:null,onNew:null,onRemove:null,onMouseEnter:null,onMouseLeave:null,onScroll:null},"function"==typeof(t=w2utils.extend({},e,t,{suffix:""})).items&&(t._items_fun=t.items),t.items=w2utils.normMenu.call(this,t.items),t.selected=w2utils.normMenu.call(this,t.selected),this.options=t,Array.isArray(t.selected)||(t.selected=[]),this.selected=t.selected;break;case"file":e={selected:[],max:0,maxSize:0,maxFileSize:0,maxItemWidth:250,maxDropHeight:350,maxDropWidth:null,readContent:!0,silent:!0,align:"both",altRows:!0,renderItem:null,style:"",onClick:null,onAdd:null,onRemove:null,onMouseEnter:null,onMouseLeave:null},t=w2utils.extend({},e,t),this.options=t,Array.isArray(t.selected)||(t.selected=[]),this.selected=t.selected,null==query(this.el).attr("placeholder")&&query(this.el).attr("placeholder",w2utils.lang("Attach files by dragging and dropping or Click to Select"))}query(this.el).css("box-sizing","border-box").addClass("w2field w2ui-input").off(".w2field").on("change.w2field",e=>{this.change(e)}).on("click.w2field",e=>{this.click(e)}).on("focus.w2field",e=>{this.focus(e)}).on("blur.w2field",e=>{"list"!==this.type&&this.blur(e)}).on("keydown.w2field",e=>{this.keyDown(e)}).on("keyup.w2field",e=>{this.keyUp(e)}),this.addPrefix(),this.addSuffix(),this.addSearch(),this.addMultiSearch(),this.change(new Event("change"))}else console.log("ERROR: w2field could only be applied to INPUT or TEXTAREA.",this.el)}get(){let e;return e=-1!==["list","enum","file"].indexOf(this.type)?this.selected:query(this.el).val()}set(e,t){-1!==["list","enum","file"].indexOf(this.type)?("list"!==this.type&&t?(Array.isArray(this.selected)||(this.selected=[]),this.selected.push(e),(t=w2menu.get(this.el.id+"_menu"))&&(t.options.selected=this.selected)):(null==e&&(e=[]),t="enum"!==this.type||Array.isArray(e)?e:[e],this.selected=t),query(this.el).trigger("input").trigger("change"),this.refresh()):query(this.el).val(e)}setIndex(e,t){if(-1!==["list","enum"].indexOf(this.type)){var i=this.options.items;if(i&&i[e])return"list"==this.type&&(this.selected=i[e]),"enum"==this.type&&(t||(this.selected=[]),this.selected.push(i[e])),(t=w2menu.get(this.el.id+"_menu"))&&(t.options.selected=this.selected),query(this.el).trigger("input").trigger("change"),this.refresh(),!0}return!1}refresh(){let s=this.options;var e=Date.now(),t=getComputedStyle(this.el);if("list"==this.type){if(query(this.el).parent().css("white-space","nowrap"),this.helpers.prefix&&this.helpers.prefix.hide(),!this.helpers.search)return;null==this.selected&&s.icon?s.prefix=` + + `:s.prefix="",this.addPrefix();let e=query(this.helpers.search_focus);var i=query(e[0].previousElementSibling);e.css({outline:"none"}),""===e.val()?(e.css("opacity",0),i.css("opacity",0),this.selected?.id?(a=this.selected.text,r=this.findItemIndex(s.items,this.selected.id),null!=a&&query(this.el).val(w2utils.lang(a)).data({selected:a,selectedIndex:r[0]})):(this.el.value="",query(this.el).removeData("selected selectedIndex"))):(e.css("opacity",1),i.css("opacity",1),query(this.el).val(""),setTimeout(()=>{this.helpers.prefix&&this.helpers.prefix.hide(),s.icon?(e.css("margin-left","17px"),query(this.helpers.search).find(".w2ui-icon-search").addClass("show-search")):(e.css("margin-left","0px"),query(this.helpers.search).find(".w2ui-icon-search").removeClass("show-search"))},1)),query(this.el).prop("readOnly")||query(this.el).prop("disabled")?setTimeout(()=>{this.helpers.prefix&&query(this.helpers.prefix).css("opacity","0.6"),this.helpers.suffix&&query(this.helpers.suffix).css("opacity","0.6")},1):setTimeout(()=>{this.helpers.prefix&&query(this.helpers.prefix).css("opacity","1"),this.helpers.suffix&&query(this.helpers.suffix).css("opacity","1")},1)}let l=this.helpers.multi;if(["enum","file"].includes(this.type)&&l){let i="";Array.isArray(this.selected)&&this.selected.forEach((e,t)=>{null!=e&&(i+=` +
    + ${"function"==typeof s.renderItem?s.renderItem(e,t,`
      
    `):` + ${e.icon?``:""} +
      
    + ${("enum"===this.type?e.text:e.name)??e.id??e} + ${e.size?` - ${w2utils.formatSize(e.size)}`:""} + `} +
    `)});var r,a=l.find(".w2ui-multi-items");s.style&&l.attr("style",l.attr("style")+";"+s.style),query(this.el).css("z-index","-1"),query(this.el).prop("readOnly")||query(this.el).prop("disabled")?setTimeout(()=>{l[0].scrollTop=0,l.addClass("w2ui-readonly").find(".li-item").css("opacity","0.9").parent().find(".li-search").hide().find("input").prop("readOnly",!0).closest(".w2ui-multi-items").find(".w2ui-list-remove").hide()},1):setTimeout(()=>{l.removeClass("w2ui-readonly").find(".li-item").css("opacity","1").parent().find(".li-search").show().find("input").prop("readOnly",!1).closest(".w2ui-multi-items").find(".w2ui-list-remove").show()},1),0${query(this.el).attr("placeholder")}`)),l.off(".w2item").on("scroll.w2item",e=>{e=this.trigger("scroll",{target:this.el,originalEvent:e});!0!==e.isCancelled&&(w2tooltip.hide(this.el.id+"_preview"),e.finish())}).find(".li-item").on("click.w2item",e=>{var i=query(e.target).closest(".li-item"),s=i.attr("index"),l=this.selected[s];if(!query(i).hasClass("li-search")){e.stopPropagation();let t;if(query(e.target).hasClass("w2ui-list-remove"))query(this.el).prop("readOnly")||query(this.el).prop("disabled")||!0!==(t=this.trigger("remove",{target:this.el,originalEvent:e,item:l})).isCancelled&&(this.selected.splice(s,1),query(this.el).trigger("input").trigger("change"),query(e.target).remove());else if(!0!==(t=this.trigger("click",{target:this.el,originalEvent:e.originalEvent,item:l})).isCancelled){let e=l.tooltip;if("file"===this.type&&(/image/i.test(l.type)&&(e=` +
    + +
    `),e+=` +
    +
    ${w2utils.lang("Name")}:
    +
    ${l.name}
    +
    ${w2utils.lang("Size")}:
    +
    ${w2utils.formatSize(l.size)}
    +
    ${w2utils.lang("Type")}:
    +
    ${l.type}
    +
    ${w2utils.lang("Modified")}:
    +
    ${w2utils.date(l.modified)}
    +
    `),e){let t=this.el.id+"_preview";w2tooltip.show({name:t,anchor:i.get(0),html:e,hideOn:["doc-click"],class:""}).show(e=>{query(`#w2overlay-${t} img`).on("load",function(e){var t=this.clientWidth,i=this.clientHeight;t<300&i<300||(i<=t&&300{var t=query(e.target).closest(".li-item");query(t).hasClass("li-search")||(t=this.selected[query(e.target).attr("index")],!0!==(e=this.trigger("mouseEnter",{target:this.el,originalEvent:e,item:t})).isCancelled&&e.finish())}).on("mouseleave.w2item",e=>{var t=query(e.target).closest(".li-item");query(t).hasClass("li-search")||(t=this.selected[query(e.target).attr("index")],!0!==(e=this.trigger("mouseLeave",{target:this.el,originalEvent:e,item:t})).isCancelled&&e.finish())}),"enum"===this.type?this.helpers.multi.find("input").css({width:"15px"}):this.helpers.multi.find(".li-search").hide(),this.resize()}return Date.now()-e}resize(){var e=this.el.clientWidth,t=getComputedStyle(this.el),i=this.helpers.search,s=this.helpers.multi,l=this.helpers.suffix,r=this.helpers.prefix,i=(i&&query(i).css("width",e),s&&query(s).css("width",e-parseInt(t["margin-left"],10)-parseInt(t["margin-right"],10)),l&&this.addSuffix(),r&&this.addPrefix(),this.helpers.multi);if(["enum","file"].includes(this.type)&&i){query(this.el).css("height","auto");let e=query(i).find(":scope div.w2ui-multi-items").get(0).clientHeight+5;(e=(e=e<20?20:e)>this.tmp["max-height"]?this.tmp["max-height"]:e)e&&(e=s),query(i).css({height:e+"px",overflow:e==this.tmp["max-height"]?"auto":"hidden"}),query(i).css("height",e+"px"),query(this.el).css({height:e+"px"})}this.tmp.current_width=e}reset(){null!=this.tmp&&(query(this.el).css("height","auto"),Array("padding-left","padding-right","background-color","border-color").forEach(e=>{this.tmp&&null!=this.tmp["old-"+e]&&(query(this.el).css(e,this.tmp["old-"+e]),delete this.tmp["old-"+e])}),clearInterval(this.tmp.sizeTimer)),query(this.el).val(this.clean(query(this.el).val())).removeClass("w2field").removeData("selected selectedIndex").off(".w2field"),Object.keys(this.helpers).forEach(e=>{query(this.helpers[e]).remove()}),this.helpers={}}clean(e){var t;return e="number"!=typeof e&&(t=this.options,e=String(e).trim(),["int","float","money","currency","percent"].includes(this.type))?""!==(e="string"==typeof e?(e=t.autoFormat&&(["money","currency"].includes(this.type)&&(e=String(e).replace(t.moneyRE,"")),"percent"===this.type&&(e=String(e).replace(t.percentRE,"")),["int","float"].includes(this.type))?String(e).replace(t.numberRE,""):e).replace(/\s+/g,"").replace(new RegExp(t.groupSymbol,"g"),"").replace(t.decimalSymbol,"."):e)&&w2utils.isFloat(e)?Number(e):"":e}format(e){var t=this.options;if(t.autoFormat&&""!==e){switch(this.type){case"money":case"currency":""!==(e=w2utils.formatNumber(e,t.currencyPrecision,!0))&&(e=t.currencyPrefix+e+t.currencySuffix);break;case"percent":""!==(e=w2utils.formatNumber(e,t.precision,!0))&&(e+="%");break;case"float":e=w2utils.formatNumber(e,t.precision,!0);break;case"int":e=w2utils.formatNumber(e,0,!0)}var i=parseInt(1e3).toLocaleString(w2utils.settings.locale,{useGrouping:!0}).slice(1,2);i!==this.options.groupSymbol&&(e=e.replaceAll(i,this.options.groupSymbol))}return e}change(e){if(-1!==["int","float","money","currency","percent"].indexOf(this.type)){var t=query(this.el).val(),i=this.format(this.clean(query(this.el).val()));if(""!==t&&t!=i)return query(this.el).val(i),e.stopPropagation(),e.preventDefault(),!1}if("color"===this.type){let e=query(this.el).val();"rgb"!==e.substr(0,3).toLowerCase()&&(e="#"+e,8!==(t=query(this.el).val().length))&&6!==t&&3!==t&&(e="");i=query(this.el).get(0).nextElementSibling;query(i).find("div").css("background-color",e),query(this.el).hasClass("has-focus")&&this.updateOverlay()}if(-1!==["list","enum","file"].indexOf(this.type)&&this.refresh(),-1!==["date","time","datetime"].indexOf(this.type)){let e=parseInt(this.el.value);w2utils.isInt(this.el.value)&&3e3{this.updateOverlay()},100)}var t;"file"==this.type&&(t=query(this.el).get(0).previousElementSibling,query(t).addClass("has-focus")),query(this.el).addClass("has-focus")}}blur(e){var i,s=query(this.el).val().trim();if(query(this.el).removeClass("has-focus"),["int","float","money","currency","percent"].includes(this.type)&&""!==s){let e=s,t="";this.isStrValid(s)?(i=this.clean(s),null!=this.options.min&&i= "+this.options.min),null!=this.options.max&&i>this.options.max&&(e=this.options.max,t="Should be <= "+this.options.max)):e="",this.options.autoCorrect&&(query(this.el).val(e).trigger("input").trigger("change"),t)&&(w2tooltip.show({name:this.el.id+"_error",anchor:this.el,html:t}),setTimeout(()=>{w2tooltip.hide(this.el.id+"_error")},3e3))}["date","time","datetime"].includes(this.type)&&this.options.autoCorrect&&""!==s&&(i="date"==this.type?w2utils.isDate:"time"==this.type?w2utils.isTime:w2utils.isDateTime,w2date.inRange(this.el.value,this.options)&&i.bind(w2utils)(this.el.value,this.options.format)||query(this.el).val("").trigger("input").trigger("change")),"enum"===this.type&&query(this.helpers.multi).find("input").val("").css("width","15px"),"file"==this.type&&(s=this.el.previousElementSibling,query(s).removeClass("has-focus")),"list"===this.type&&(this.el.value=this.selected?.text??"")}keyDown(t,i){var e,s=this.options,i=t.keyCode||i&&i.keyCode;let l=!1,r,a,n,o,h,d;if(["int","float","money","currency","percent","hex","bin","color","alphanumeric"].includes(this.type)&&!(t.metaKey||t.ctrlKey||t.altKey||this.isStrValid(t.key??"1",!0)||[9,8,13,27,37,38,39,40,46].includes(t.keyCode)))return t.preventDefault(),t.stopPropagation?t.stopPropagation():t.cancelBubble=!0,!1;if(["int","float","money","currency","percent"].includes(this.type)){if(!s.keyboard||query(this.el).prop("readOnly")||query(this.el).prop("disabled"))return;switch(r=parseFloat(query(this.el).val().replace(s.moneyRE,""))||0,a=s.step,(t.ctrlKey||t.metaKey)&&(a=10*s.step),i){case 38:t.shiftKey||(h=r+a<=s.max||null==s.max?Number((r+a).toFixed(12)):s.max,query(this.el).val(h).trigger("input").trigger("change"),l=!0);break;case 40:t.shiftKey||(h=r-a>=s.min||null==s.min?Number((r-a).toFixed(12)):s.min,query(this.el).val(h).trigger("input").trigger("change"),l=!0)}l&&(t.preventDefault(),this.moveCaret2end())}if(["date","datetime"].includes(this.type)){if(!s.keyboard||query(this.el).prop("readOnly")||query(this.el).prop("disabled"))return;var u=("date"==this.type?w2utils.isDate:w2utils.isDateTime).bind(w2utils),c=("date"==this.type?w2utils.formatDate:w2utils.formatDateTime).bind(w2utils);switch(n=864e5,a=1,(t.ctrlKey||t.metaKey)&&(a=10),(o=u(query(this.el).val(),s.format,!0))||(o=new Date,n=0),i){case 38:t.shiftKey||(10==a?o.setMonth(o.getMonth()+1):o.setTime(o.getTime()+n),d=c(o.getTime(),s.format),query(this.el).val(d).trigger("input").trigger("change"),l=!0);break;case 40:t.shiftKey||(10==a?o.setMonth(o.getMonth()-1):o.setTime(o.getTime()-n),d=c(o.getTime(),s.format),query(this.el).val(d).trigger("input").trigger("change"),l=!0)}l&&(t.preventDefault(),this.moveCaret2end(),this.updateOverlay())}if("time"===this.type){if(!s.keyboard||query(this.el).prop("readOnly")||query(this.el).prop("disabled"))return;a=t.ctrlKey||t.metaKey?60:1,r=query(this.el).val();let e=w2date.str2min(r)||w2date.str2min((new Date).getHours()+":"+((new Date).getMinutes()-1));switch(i){case 38:t.shiftKey||(e+=a,l=!0);break;case 40:t.shiftKey||(e-=a,l=!0)}l&&(t.preventDefault(),query(this.el).val(w2date.min2str(e)).trigger("input").trigger("change"),this.moveCaret2end())}if(["list","enum"].includes(this.type))switch(i){case 8:case 46:"list"==this.type?""==query(this.helpers.search_focus).val()&&(this.selected=null,w2menu.hide(this.el.id+"_menu"),query(this.el).val("").trigger("input").trigger("change")):""==query(this.helpers.multi).find("input").val()&&(w2menu.hide(this.el.id+"_menu"),this.selected.pop(),(e=w2menu.get(this.el.id+"_menu"))&&(e.options.selected=this.selected),this.refresh());break;case 9:case 16:break;case 27:w2menu.hide(this.el.id+"_menu"),this.refresh()}}keyUp(t){if("list"==this.type){let e=query(this.helpers.search_focus);""!==e.val()?query(this.el).attr("placeholder",""):query(this.el).attr("placeholder",this.tmp.pholder),13==t.keyCode&&setTimeout(()=>{e.val(""),w2menu.hide(this.el.id+"_menu"),this.refresh()},1),[38,40].includes(t.keyCode)&&!this.tmp.overlay.overlay.displayed&&this.updateOverlay(),this.refresh()}var e,i;"combo"==this.type&&this.updateOverlay(),"enum"==this.type&&(e=this.helpers.multi.find("input"),i=getComputedStyle(e.get(0)),i=w2utils.getStrWidth(e.val(),`font-family: ${i["font-family"]}; font-size: ${i["font-size"]};`),e.css({width:i+15+"px"}),this.resize(),[38,40].includes(t.keyCode))&&!this.tmp.overlay?.overlay?.displayed&&this.updateOverlay()}findItemIndex(e,i,s){let l=[];var t;return s=s||[],["list","combo","enum"].includes(this.type)&&this.options.url&&(t=w2menu.get(this.el.id+"_menu"))&&(e=t.options.items,this.options.items=e),e.forEach((e,t)=>{e.id===i&&(l=s.concat([t]),this.options.index=[t]),0==l.length&&e.items&&0{e=e.detail.color;query(this.el).val(e).trigger("input").trigger("change")}).liveUpdate(e=>{e=e.detail.color;query(this.helpers.suffix).find(":scope > div").css("background-color","#"+e)})}if(["list","combo","enum"].includes(this.type)){var t;this.el;let s=this.el;"enum"===this.type&&(t=this.helpers.multi.get(0),s=query(t).find("input").get(0)),"list"===this.type&&(t=this.selected,w2utils.isPlainObject(t)&&0{var t,i;["list","combo"].includes(this.type)?(this.selected=e.detail.item,query(s).val(""),query(this.el).val(this.selected.text).trigger("input").trigger("change"),this.focus({showMenu:!1})):(i=this.selected,(t=e.detail?.item)&&!0!==(e=this.trigger("add",{target:this.el,item:t,originalEvent:e})).isCancelled&&(i.length>=l.max&&0{e=e.detail.date;null!=e&&query(this.el).val(e).trigger("input").trigger("change")})}isStrValid(e,t){let i=!0;switch(this.type){case"int":i=!(!t||!["-",this.options.groupSymbol].includes(e))||w2utils.isInt(e.replace(this.options.numberRE,""));break;case"percent":e=e.replace(/%/g,"");case"float":i=!(!t||!["-","",this.options.decimalSymbol,this.options.groupSymbol].includes(e))||w2utils.isFloat(e.replace(this.options.numberRE,""));break;case"money":case"currency":i=!(!t||!["-",this.options.decimalSymbol,this.options.groupSymbol,this.options.currencyPrefix,this.options.currencySuffix].includes(e))||w2utils.isFloat(e.replace(this.options.moneyRE,""));break;case"bin":i=w2utils.isBin(e);break;case"color":case"hex":i=w2utils.isHex(e);break;case"alphanumeric":i=w2utils.isAlphaNumeric(e)}return i}addPrefix(){var e,t;this.options.prefix&&(t=getComputedStyle(this.el),null==this.tmp["old-padding-left"]&&(this.tmp["old-padding-left"]=t["padding-left"]),this.helpers.prefix&&query(this.helpers.prefix).remove(),query(this.el).before(`
    ${this.options.prefix}
    `),e=query(this.el).get(0).previousElementSibling,query(e).css({color:t.color,"font-family":t["font-family"],"font-size":t["font-size"],height:this.el.clientHeight+"px","padding-top":t["padding-top"],"padding-bottom":t["padding-bottom"],"padding-left":this.tmp["old-padding-left"],"padding-right":0,"margin-top":parseInt(t["margin-top"],10)+2+"px","margin-bottom":parseInt(t["margin-bottom"],10)+1+"px","margin-left":t["margin-left"],"margin-right":0,"z-index":1}),query(this.el).css("padding-left",e.clientWidth+"px !important"),this.helpers.prefix=e)}addSuffix(){if(this.options.suffix||this.options.arrow){let e,t=this;var i=getComputedStyle(this.el),s=(null==this.tmp["old-padding-right"]&&(this.tmp["old-padding-right"]=i["padding-right"]),parseInt(i["padding-right"]||0));this.options.arrow&&(this.helpers.arrow&&query(this.helpers.arrow).remove(),query(this.el).after('
     
    '),e=query(this.el).get(0).nextElementSibling,query(e).css({color:i.color,"font-family":i["font-family"],"font-size":i["font-size"],height:this.el.clientHeight+"px",padding:0,"margin-top":parseInt(i["margin-top"],10)+1+"px","margin-bottom":0,"border-left":"1px solid silver",width:"16px",transform:"translateX(-100%)"}).on("mousedown",function(e){query(e.target).hasClass("arrow-up")&&t.keyDown(e,{keyCode:38}),query(e.target).hasClass("arrow-down")&&t.keyDown(e,{keyCode:40})}),s+=e.clientWidth,query(this.el).css("padding-right",s+"px !important"),this.helpers.arrow=e),""!==this.options.suffix&&(this.helpers.suffix&&query(this.helpers.suffix).remove(),query(this.el).after(`
    ${this.options.suffix}
    `),e=query(this.el).get(0).nextElementSibling,query(e).css({color:i.color,"font-family":i["font-family"],"font-size":i["font-size"],height:this.el.clientHeight+"px","padding-top":i["padding-top"],"padding-bottom":i["padding-bottom"],"padding-left":0,"padding-right":i["padding-right"],"margin-top":parseInt(i["margin-top"],10)+2+"px","margin-bottom":parseInt(i["margin-bottom"],10)+1+"px",transform:"translateX(-100%)"}),query(this.el).css("padding-right",e.clientWidth+"px !important"),this.helpers.suffix=e)}}addSearch(){if("list"===this.type){this.helpers.search&&query(this.helpers.search).remove();let e=parseInt(query(this.el).attr("tabIndex")),t=(isNaN(e)||-1===e||(this.tmp["old-tabIndex"]=e),null!=(e=this.tmp["old-tabIndex"]?this.tmp["old-tabIndex"]:e)&&!isNaN(e)||(e=0),"");var i=` +
    + + +
    `,i=(query(this.el).attr("tabindex",-1).before(i),query(this.el).get(0).previousElementSibling),s=(this.helpers.search=i,this.helpers.search_focus=query(i).find("input").get(0),getComputedStyle(this.el));query(i).css({width:this.el.clientWidth+"px","margin-top":s["margin-top"],"margin-left":s["margin-left"],"margin-bottom":s["margin-bottom"],"margin-right":s["margin-right"]}).find("input").css({cursor:"default",width:"100%",opacity:1,padding:s.padding,margin:s.margin,border:"1px solid transparent","background-color":"transparent"}),query(i).find("input").off(".helper").on("focus.helper",e=>{query(e.target).val(""),this.tmp.pholder=query(this.el).attr("placeholder")??"",this.focus(e),e.stopPropagation()}).on("blur.helper",e=>{query(e.target).val(""),null!=this.tmp.pholder&&query(this.el).attr("placeholder",this.tmp.pholder),this.blur(e),e.stopPropagation()}).on("keydown.helper",e=>{this.keyDown(e)}).on("keyup.helper",e=>{this.keyUp(e)}),query(i).on("click",e=>{query(e.target).find("input").focus()})}}addMultiSearch(){if(["enum","file"].includes(this.type)){query(this.helpers.multi).remove();let e="";var l,r,a=getComputedStyle(this.el),n=w2utils.stripSpaces(` + margin-top: 0px; + margin-bottom: 0px; + margin-left: ${a["margin-left"]}; + margin-right: ${a["margin-right"]}; + width: ${w2utils.getSize(this.el,"width")-parseInt(a["margin-left"],10)-parseInt(a["margin-right"],10)}px; + `);null==this.tmp["min-height"]&&(l=this.tmp["min-height"]=parseInt(("none"!=a["min-height"]?a["min-height"]:0)||0),r=parseInt(a.height),this.tmp["min-height"]=Math.max(l,r)),null==this.tmp["max-height"]&&"none"!=a["max-height"]&&(this.tmp["max-height"]=parseInt(a["max-height"]));let t="",i=(null!=query(this.el).attr("id")&&(t=`id="${query(this.el).attr("id")}_search"`),parseInt(query(this.el).attr("tabIndex"))),s=(isNaN(i)||-1===i||(this.tmp["old-tabIndex"]=i),null!=(i=this.tmp["old-tabIndex"]?this.tmp["old-tabIndex"]:i)&&!isNaN(i)||(i=0),"enum"===this.type&&(e=` +
    +
    + +
    +
    `),"file"===this.type&&(e=` +
    +
    + +
    +
    + +
    +
    `),this.tmp["old-background-color"]=a["background-color"],this.tmp["old-border-color"]=a["border-color"],query(this.el).before(e).css({"border-color":"transparent","background-color":"transparent"}),query(this.el.previousElementSibling));this.helpers.multi=s,query(this.el).attr("tabindex",-1),s.on("click",e=>{this.focus(e)}),s.find("input:not(.file-input)").on("click",e=>{this.click(e)}).on("focus",e=>{this.focus(e)}).on("blur",e=>{this.blur(e)}).on("keydown",e=>{this.keyDown(e)}).on("keyup",e=>{this.keyUp(e)}),"file"===this.type&&s.find("input.file-input").off(".drag").on("click.drag",e=>{e.stopPropagation(),query(this.el).prop("readOnly")||query(this.el).prop("disabled")||this.focus(e)}).on("dragenter.drag",e=>{query(this.el).prop("readOnly")||query(this.el).prop("disabled")||s.addClass("w2ui-file-dragover")}).on("dragleave.drag",e=>{query(this.el).prop("readOnly")||query(this.el).prop("disabled")||s.removeClass("w2ui-file-dragover")}).on("drop.drag",e=>{query(this.el).prop("readOnly")||query(this.el).prop("disabled")||(s.removeClass("w2ui-file-dragover"),Array.from(e.dataTransfer.files).forEach(e=>{this.addFile(e)}),this.focus(e),e.preventDefault(),e.stopPropagation())}).on("dragover.drag",e=>{e.preventDefault(),e.stopPropagation()}).on("change.drag",e=>{void 0!==e.target.files&&Array.from(e.target.files).forEach(e=>{this.addFile(e)}),this.focus(e)}),this.refresh()}}addFile(t){var e=this.options,s=this.selected;let l={name:t.name,type:t.type,modified:t.lastModifiedDate,size:t.size,content:null,file:t},i=0,r=0,a=[],n=(Array.isArray(s)&&s.forEach(e=>{e.name==t.name&&e.size==t.size&&a.push(w2utils.lang('The file "${name}" (${size}) is already added.',{name:t.name,size:w2utils.formatSize(t.size)})),i+=e.size,r++}),0!==e.maxFileSize&&l.size>e.maxFileSize&&a.push(w2utils.lang("Maximum file size is ${size}",{size:w2utils.formatSize(e.maxFileSize)})),0!==e.maxSize&&i+l.size>e.maxSize&&a.push(w2utils.lang("Maximum total size is ${size}",{size:w2utils.formatSize(e.maxSize)})),0!==e.max&&r>=e.max&&a.push(w2utils.lang("Maximum number of files is ${count}",{count:e.max})),this.trigger("add",{target:this.el,file:l,total:r,totalSize:i,errors:a}));if(!0!==n.isCancelled)if(!0!==e.silent&&0")}),console.log("ERRORS (while adding files): ",a);else if(s.push(l),"undefined"!=typeof FileReader&&!0===e.readContent){s=new FileReader;let i=this;s.onload=function(e){var e=e.target.result,t=e.indexOf(",");l.content=e.substr(t+1),i.refresh(),query(i.el).trigger("input").trigger("change"),n.finish()},s.readAsDataURL(t)}else this.refresh(),query(this.el).trigger("input").trigger("change"),n.finish()}moveCaret2end(){setTimeout(()=>{this.el.setSelectionRange(this.el.value.length,this.el.value.length)},0)}}export{w2ui,w2utils,query,w2locale,w2event,w2base,w2popup,w2alert,w2confirm,w2prompt,Dialog,w2tooltip,w2menu,w2color,w2date,Tooltip,w2toolbar,w2sidebar,w2tabs,w2layout,w2grid,w2form,w2field}; \ No newline at end of file diff --git a/src/resources/w2ui-2.0/w2ui-2.0.js b/src/resources/w2ui-2.0/w2ui-2.0.js new file mode 100644 index 0000000..a713839 --- /dev/null +++ b/src/resources/w2ui-2.0/w2ui-2.0.js @@ -0,0 +1,22230 @@ +/* w2ui 2.0.0 (4/26/2023, 10:40:17 AM) (c) http://w2ui.com, vitmalina@gmail.com */ +/** + * Part of w2ui 2.0 library + * - Dependencies: w2utils + * - on/off/trigger methods id not showing in help + * - refactored with event object + */ + +class w2event { + constructor(owner, edata) { + Object.assign(this, { + type: edata.type ?? null, + detail: edata, + owner, + target: edata.target ?? null, + phase: edata.phase ?? 'before', + object: edata.object ?? null, + execute: null, + isStopped: false, + isCancelled: false, + onComplete: null, + listeners: [] + }) + delete edata.type + delete edata.target + delete edata.object + this.complete = new Promise((resolve, reject) => { + this._resolve = resolve + this._reject = reject + }) + // needed empty catch function so that promise will not show error in the console + this.complete.catch(() => {}) + } + finish(detail) { + if (detail) { + w2utils.extend(this.detail, detail) + } + this.phase = 'after' + this.owner.trigger.call(this.owner, this) + } + done(func) { + this.listeners.push(func) + } + preventDefault() { + this._reject() + this.isCancelled = true + } + stopPropagation() { + this.isStopped = true + } +} +class w2base { + /** + * Initializes base object for w2ui, registers it with w2ui object + * + * @param {string} name - name of the object + * @returns + */ + constructor(name) { + this.activeEvents = [] // events that are currently processing + this.listeners = [] // event listeners + // register globally + if (typeof name !== 'undefined') { + if (!w2utils.checkName(name)) return + w2ui[name] = this + } + this.debug = false // if true, will trigger all events + } + /** + * Adds event listener, supports event phase and event scoping + * + * @param {*} edata - an object or string, if string "eventName:phase.scope" + * @param {*} handler + * @returns itself + */ + on(events, handler) { + if (typeof events == 'string') { + events = events.split(/[,\s]+/) // separate by comma or space + } else { + events = [events] + } + events.forEach(edata => { + let name = typeof edata == 'string' ? edata : (edata.type + ':' + edata.execute + '.' + edata.scope) + if (typeof edata == 'string') { + let [eventName, scope] = edata.split('.') + let [type, execute] = eventName.replace(':complete', ':after').replace(':done', ':after').split(':') + edata = { type, execute: execute ?? 'before', scope } + } + edata = w2utils.extend({ type: null, execute: 'before', onComplete: null }, edata) + // errors + if (!edata.type) { console.log('ERROR: You must specify event type when calling .on() method of '+ this.name); return } + if (!handler) { console.log('ERROR: You must specify event handler function when calling .on() method of '+ this.name); return } + if (!Array.isArray(this.listeners)) this.listeners = [] + this.listeners.push({ name, edata, handler }) + if (this.debug) { + console.log('w2base: add event', { name, edata, handler }) + } + }) + return this + } + /** + * Removes event listener, supports event phase and event scoping + * + * @param {*} edata - an object or string, if string "eventName:phase.scope" + * @param {*} handler + * @returns itself + */ + off(events, handler) { + if (typeof events == 'string') { + events = events.split(/[,\s]+/) // separate by comma or space + } else { + events = [events] + } + events.forEach(edata => { + let name = typeof edata == 'string' ? edata : (edata.type + ':' + edata.execute + '.' + edata.scope) + if (typeof edata == 'string') { + let [eventName, scope] = edata.split('.') + let [type, execute] = eventName.replace(':complete', ':after').replace(':done', ':after').split(':') + edata = { type: type || '*', execute: execute || '', scope: scope || '' } + } + edata = w2utils.extend({ type: null, execute: null, onComplete: null }, edata) + // errors + if (!edata.type && !edata.scope) { console.log('ERROR: You must specify event type when calling .off() method of '+ this.name); return } + if (!handler) { handler = null } + let count = 0 + // remove listener + this.listeners = this.listeners.filter(curr => { + if ( (edata.type === '*' || edata.type === curr.edata.type) + && (edata.execute === '' || edata.execute === curr.edata.execute) + && (edata.scope === '' || edata.scope === curr.edata.scope) + && (edata.handler == null || edata.handler === curr.edata.handler) + ) { + count++ // how many listeners removed + return false + } else { + return true + } + }) + if (this.debug) { + console.log(`w2base: remove event (${count})`, { name, edata, handler }) + } + }) + return this // needed for chaining + } + /** + * Triggers even listeners for a specific event, loops through this.listeners + * + * @param {Object} edata - Object + * @returns modified edata + */ + trigger(eventName, edata) { + if (arguments.length == 1) { + edata = eventName + } else { + edata.type = eventName + edata.target = edata.target ?? this + } + if (w2utils.isPlainObject(edata) && edata.phase == 'after') { + // find event + edata = this.activeEvents.find(event => { + if (event.type == edata.type && event.target == edata.target) { + return true + } + return false + }) + if (!edata) { + console.log(`ERROR: Cannot find even handler for "${edata.type}" on "${edata.target}".`) + return + } + console.log('NOTICE: This syntax "edata.trigger({ phase: \'after\' })" is outdated. Use edata.finish() instead.') + } else if (!(edata instanceof w2event)) { + edata = new w2event(this, edata) + this.activeEvents.push(edata) + } + let args, fun, tmp + if (!Array.isArray(this.listeners)) this.listeners = [] + if (this.debug) { + console.log(`w2base: trigger "${edata.type}:${edata.phase}"`, edata) + } + // process events in REVERSE order + for (let h = this.listeners.length-1; h >= 0; h--) { + let item = this.listeners[h] + if (item != null && (item.edata.type === edata.type || item.edata.type === '*') && + (item.edata.target === edata.target || item.edata.target == null) && + (item.edata.execute === edata.phase || item.edata.execute === '*' || item.edata.phase === '*')) + { + // add extra params if there + Object.keys(item.edata).forEach(key => { + if (edata[key] == null && item.edata[key] != null) { + edata[key] = item.edata[key] + } + }) + // check handler arguments + args = [] + tmp = new RegExp(/\((.*?)\)/).exec(String(item.handler).split('=>')[0]) + if (tmp) args = tmp[1].split(/\s*,\s*/) + if (args.length === 2) { + item.handler.call(this, edata.target, edata) // old way for back compatibility + if (this.debug) console.log(' - call (old)', item.handler) + } else { + item.handler.call(this, edata) // new way + if (this.debug) console.log(' - call', item.handler) + } + if (edata.isStopped === true || edata.stop === true) return edata // back compatibility edata.stop === true + } + } + // main object events + let funName = 'on' + edata.type.substr(0,1).toUpperCase() + edata.type.substr(1) + if (edata.phase === 'before' && typeof this[funName] === 'function') { + fun = this[funName] + // check handler arguments + args = [] + tmp = new RegExp(/\((.*?)\)/).exec(String(fun).split('=>')[0]) + if (tmp) args = tmp[1].split(/\s*,\s*/) + if (args.length === 2) { + fun.call(this, edata.target, edata) // old way for back compatibility + if (this.debug) console.log(' - call: on[Event] (old)', fun) + } else { + fun.call(this, edata) // new way + if (this.debug) console.log(' - call: on[Event]', fun) + } + if (edata.isStopped === true || edata.stop === true) return edata // back compatibility edata.stop === true + } + // item object events + if (edata.object != null && edata.phase === 'before' && typeof edata.object[funName] === 'function') { + fun = edata.object[funName] + // check handler arguments + args = [] + tmp = new RegExp(/\((.*?)\)/).exec(String(fun).split('=>')[0]) + if (tmp) args = tmp[1].split(/\s*,\s*/) + if (args.length === 2) { + fun.call(this, edata.target, edata) // old way for back compatibility + if (this.debug) console.log(' - call: edata.object (old)', fun) + } else { + fun.call(this, edata) // new way + if (this.debug) console.log(' - call: edata.object', fun) + } + if (edata.isStopped === true || edata.stop === true) return edata + } + // execute onComplete + if (edata.phase === 'after') { + if (typeof edata.onComplete === 'function') edata.onComplete.call(this, edata) + for (let i = 0; i < edata.listeners.length; i++) { + if (typeof edata.listeners[i] === 'function') { + edata.listeners[i].call(this, edata) + if (this.debug) console.log(' - call: done', fun) + } + } + edata._resolve(edata) + if (this.debug) { + console.log(`w2base: trigger "${edata.type}:${edata.phase}"`, edata) + } + } + return edata + } +} +/** + * Part of w2ui 2.0 library + * - Dependencies: none + * + * These are the master locale settings that will be used by w2utils + * + * "locale" should be the IETF language tag in the form xx-YY, + * where xx is the ISO 639-1 language code ( see https://en.wikipedia.org/wiki/ISO_639-1 ) and + * YY is the ISO 3166-1 alpha-2 country code ( see https://en.wikipedia.org/wiki/ISO_3166-2 ) + */ +const w2locale = { + 'locale' : 'en-US', + 'dateFormat' : 'm/d/yyyy', + 'timeFormat' : 'hh:mi pm', + 'datetimeFormat' : 'm/d/yyyy|hh:mi pm', + 'currencyPrefix' : '$', + 'currencySuffix' : '', + 'currencyPrecision' : 2, + 'groupSymbol' : ',', // aka "thousands separator" + 'decimalSymbol' : '.', + 'shortmonths' : ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + 'fullmonths' : ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], + 'shortdays' : ['M', 'T', 'W', 'T', 'F', 'S', 'S'], + 'fulldays' : ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'], + 'weekStarts' : 'S', // can be "M" for Monday or "S" for Sunday + // phrases used in w2ui, should be empty for original language + // keep these up-to-date and in sorted order + // value = "---" to easier see what to translate + 'phrases': { + '${count} letters or more...': '---', + 'Add new record': '---', + 'Add New': '---', + 'Advanced Search': '---', + 'after': '---', + 'AJAX error. See console for more details.': '---', + 'All Fields': '---', + 'All': '---', + 'Any': '---', + 'Are you sure you want to delete ${count} ${records}?': '---', + 'Attach files by dragging and dropping or Click to Select': '---', + 'before': '---', + 'begins with': '---', + 'begins': '---', + 'between': '---', + 'buffered': '---', + 'Cancel': '---', + 'Close': '---', + 'Column': '---', + 'Confirmation': '---', + 'contains': '---', + 'Copied': '---', + 'Copy to clipboard': '---', + 'Current Date & Time': '---', + 'Delete selected records': '---', + 'Delete': '---', + 'Do you want to delete search item "${item}"?': '---', + 'Edit selected record': '---', + 'Edit': '---', + 'Empty list': '---', + 'ends with': '---', + 'ends': '---', + 'Field should be at least ${count} characters.': '---', + 'Hide': '---', + 'in': '---', + 'is not': '---', + 'is': '---', + 'less than': '---', + 'Line #': '---', + 'Load ${count} more...': '---', + 'Loading...': '---', + 'Maximum number of files is ${count}': '---', + 'Maximum total size is ${count}': '---', + 'Modified': '---', + 'more than': '---', + 'Multiple Fields': '---', + 'Name': '---', + 'No items found': '---', + 'No matches': '---', + 'No': '---', + 'none': '---', + 'Not a float': '---', + 'Not a hex number': '---', + 'Not a valid date': '---', + 'Not a valid email': '---', + 'Not alpha-numeric': '---', + 'Not an integer': '---', + 'Not in money format': '---', + 'not in': '---', + 'Notification': '---', + 'of': '---', + 'Ok': '---', + 'Opacity': '---', + 'Record ID': '---', + 'record': '---', + 'records': '---', + 'Refreshing...': '---', + 'Reload data in the list': '---', + 'Remove': '---', + 'Remove This Field': '---', + 'Request aborted.': '---', + 'Required field': '---', + 'Reset': '---', + 'Restore Default State': '---', + 'Returned data is not in valid JSON format.': '---', + 'Save changed records': '---', + 'Save Grid State': '---', + 'Save': '---', + 'Saved Searches': '---', + 'Saving...': '---', + 'Search took ${count} seconds': '---', + 'Search': '---', + 'Select Hour': '---', + 'Select Minute': '---', + 'selected': '---', + 'Server Response ${count} seconds': '---', + 'Show/hide columns': '---', + 'Show': '---', + 'Size': '---', + 'Skip': '---', + 'Sorting took ${count} seconds': '---', + 'Type to search...': '---', + 'Type': '---', + 'Yes': '---', + 'Yesterday': '---', + 'Your remote data source record count has changed, reloading from the first record.': '---' + } +} +/* mQuery 0.7 (nightly) (10/10/2022, 11:30:36 AM), vitmalina@gmail.com */ +class Query { + static version = 0.7 + constructor(selector, context, previous) { + this.context = context ?? document + this.previous = previous ?? null + let nodes = [] + if (Array.isArray(selector)) { + nodes = selector + } else if (selector instanceof Node || selector instanceof Window) { // any html element or Window + nodes = [selector] + } else if (selector instanceof Query) { + nodes = selector.nodes + } else if (typeof selector == 'string') { + if (typeof this.context.querySelector != 'function') { + throw new Error('Invalid context') + } + nodes = Array.from(this.context.querySelectorAll(selector)) + } else if (selector == null) { + nodes = [] + } else { + // if selector is itterable, then try to create nodes from it, also supports jQuery + let arr = Array.from(selector ?? []) + if (typeof selector == 'object' && Array.isArray(arr)) { + nodes = arr + } else { + throw new Error(`Invalid selector "${selector}"`) + } + } + this.nodes = nodes + this.length = nodes.length + // map nodes to object propoerties + this.each((node, ind) => { + this[ind] = node + }) + } + static _fragment(html) { + let tmpl = document.createElement('template') + tmpl.innerHTML = html + tmpl.content.childNodes.forEach(node => { + let newNode = Query._scriptConvert(node) + if (newNode != node) { + tmpl.content.replaceChild(newNode, node) + } + }) + return tmpl.content + } + // innerHTML, append, etc. script tags will not be executed unless they are proper script tags + static _scriptConvert(node) { + let convert = (txtNode) => { + let doc = txtNode.ownerDocument + let scNode = doc.createElement('script') + scNode.text = txtNode.text + let attrs = txtNode.attributes + for (let i = 0; i < attrs.length; i++) { + scNode.setAttribute(attrs[i].name, attrs[i].value) + } + return scNode + } + if (node.tagName == 'SCRIPT') { + node = convert(node) + } + if (node.querySelectorAll) { + node.querySelectorAll('script').forEach(textNode => { + textNode.parentNode.replaceChild(convert(textNode), textNode) + }) + } + return node + } + static _fixProp(name) { + let fixes = { + cellpadding: 'cellPadding', + cellspacing: 'cellSpacing', + class: 'className', + colspan: 'colSpan', + contenteditable: 'contentEditable', + for: 'htmlFor', + frameborder: 'frameBorder', + maxlength: 'maxLength', + readonly: 'readOnly', + rowspan: 'rowSpan', + tabindex: 'tabIndex', + usemap: 'useMap' + } + return fixes[name] ? fixes[name] : name + } + _insert(method, html) { + let nodes = [] + let len = this.length + if (len < 1) return + let self = this + // TODO: need good unit test coverage for this function + if (typeof html == 'string') { + this.each(node => { + let clone = Query._fragment(html) + nodes.push(...clone.childNodes) + node[method](clone) + }) + } else if (html instanceof Query) { + let single = (len == 1) // if inserting into a single container, then move it there + html.each(el => { + this.each(node => { + // if insert before a single node, just move new one, else clone and move it + let clone = (single ? el : el.cloneNode(true)) + nodes.push(clone) + node[method](clone) + Query._scriptConvert(clone) + }) + }) + if (!single) html.remove() + } else if (html instanceof Node) { // any HTML element + this.each(node => { + // if insert before a single node, just move new one, else clone and move it + let clone = (len === 1 ? html : Query._fragment(html.outerHTML)) + nodes.push(...(len === 1 ? [html] : clone.childNodes)) + node[method](clone) + }) + if (len > 1) html.remove() + } else { + throw new Error(`Incorrect argument for "${method}(html)". It expects one string argument.`) + } + if (method == 'replaceWith') { + self = new Query(nodes, this.context, this) // must return a new collection + } + return self + } + _save(node, name, value) { + node._mQuery = node._mQuery ?? {} + if (Array.isArray(value)) { + node._mQuery[name] = node._mQuery[name] ?? [] + node._mQuery[name].push(...value) + } else if (value != null) { + node._mQuery[name] = value + } else { + delete node._mQuery[name] + } + } + get(index) { + if (index < 0) index = this.length + index + let node = this[index] + if (node) { + return node + } + if (index != null) { + return null + } + return this.nodes + } + eq(index) { + if (index < 0) index = this.length + index + let nodes = [this[index]] + if (nodes[0] == null) nodes = [] + return new Query(nodes, this.context, this) // must return a new collection + } + then(fun) { + let ret = fun(this) + return ret != null ? ret : this + } + find(selector) { + let nodes = [] + this.each(node => { + let nn = Array.from(node.querySelectorAll(selector)) + if (nn.length > 0) { + nodes.push(...nn) + } + }) + return new Query(nodes, this.context, this) // must return a new collection + } + filter(selector) { + let nodes = [] + this.each(node => { + if (node === selector + || (typeof selector == 'string' && node.matches && node.matches(selector)) + || (typeof selector == 'function' && selector(node)) + ) { + nodes.push(node) + } + }) + return new Query(nodes, this.context, this) // must return a new collection + } + next() { + let nodes = [] + this.each(node => { + let nn = node.nextElementSibling + if (nn) { nodes.push(nn) } + }) + return new Query(nodes, this.context, this) // must return a new collection + } + prev() { + let nodes = [] + this.each(node => { + let nn = node.previousElementSibling + if (nn) { nodes.push(nn)} + }) + return new Query(nodes, this.context, this) // must return a new collection + } + shadow(selector) { + let nodes = [] + this.each(node => { + // select shadow root if available + if (node.shadowRoot) nodes.push(node.shadowRoot) + }) + let col = new Query(nodes, this.context, this) + return selector ? col.find(selector) : col + } + closest(selector) { + let nodes = [] + this.each(node => { + let nn = node.closest(selector) + if (nn) { + nodes.push(nn) + } + }) + return new Query(nodes, this.context, this) // must return a new collection + } + host(all) { + let nodes = [] + // find shadow root or body + let top = (node) => { + if (node.parentNode) { + return top(node.parentNode) + } else { + return node + } + } + let fun = (node) => { + let nn = top(node) + nodes.push(nn.host ? nn.host : nn) + if (nn.host && all) fun(nn.host) + } + this.each(node => { + fun(node) + }) + return new Query(nodes, this.context, this) // must return a new collection + } + parent(selector) { + return this.parents(selector, true) + } + parents(selector, firstOnly) { + let nodes = [] + let add = (node) => { + if (nodes.indexOf(node) == -1) { + nodes.push(node) + } + if (!firstOnly && node.parentNode) { + return add(node.parentNode) + } + } + this.each(node => { + if (node.parentNode) add(node.parentNode) + }) + let col = new Query(nodes, this.context, this) + return selector ? col.filter(selector) : col + } + add(more) { + let nodes = more instanceof Query ? more.nodes : (Array.isArray(more) ? more : [more]) + return new Query(this.nodes.concat(nodes), this.context, this) // must return a new collection + } + each(func) { + this.nodes.forEach((node, ind) => { func(node, ind, this) }) + return this + } + append(html) { + return this._insert('append', html) + } + prepend(html) { + return this._insert('prepend', html) + } + after(html) { + return this._insert('after', html) + } + before(html) { + return this._insert('before', html) + } + replace(html) { + return this._insert('replaceWith', html) + } + remove() { + // remove from dom, but keep in current query + this.each(node => { node.remove() }) + return this + } + css(key, value) { + let css = key + let len = arguments.length + if (len === 0 || (len === 1 && typeof key == 'string')) { + if (this[0]) { + let st = this[0].style + // do not do computedStyleMap as it is not what on immediate element + if (typeof key == 'string') { + let pri = st.getPropertyPriority(key) + return st.getPropertyValue(key) + (pri ? '!' + pri : '') + } else { + return Object.fromEntries( + this[0].style.cssText + .split(';') + .filter(a => !!a) // filter non-empty + .map(a => { + return a.split(':').map(a => a.trim()) // trim strings + }) + ) + } + } else { + return undefined + } + } else { + if (typeof key != 'object') { + css = {} + css[key] = value + } + this.each((el, ind) => { + Object.keys(css).forEach(key => { + let imp = String(css[key]).toLowerCase().includes('!important') ? 'important' : '' + el.style.setProperty(key, String(css[key]).replace(/\!important/i, ''), imp) + }) + }) + return this + } + } + addClass(classes) { + this.toggleClass(classes, true) + return this + } + removeClass(classes) { + this.toggleClass(classes, false) + return this + } + toggleClass(classes, force) { + // split by comma or space + if (typeof classes == 'string') classes = classes.split(/[,\s]+/) + this.each(node => { + let classes2 = classes + // if not defined, remove all classes + if (classes2 == null && force === false) classes2 = Array.from(node.classList) + classes2.forEach(className => { + if (className !== '') { + let act = 'toggle' + if (force != null) act = force ? 'add' : 'remove' + node.classList[act](className) + } + }) + }) + return this + } + hasClass(classes) { + // split by comma or space + if (typeof classes == 'string') classes = classes.split(/[,\s]+/) + if (classes == null && this.length > 0) { + return Array.from(this[0].classList) + } + let ret = false + this.each(node => { + ret = ret || classes.every(className => { + return Array.from(node.classList ?? []).includes(className) + }) + }) + return ret + } + on(events, options, callback) { + if (typeof options == 'function') { + callback = options + options = undefined + } + let delegate + if (options?.delegate) { + delegate = options.delegate + delete options.delegate // not to pass to addEventListener + } + events = events.split(/[,\s]+/) // separate by comma or space + events.forEach(eventName => { + let [ event, scope ] = String(eventName).toLowerCase().split('.') + if (delegate) { + let fun = callback + callback = (event) => { + // event.target or any ancestors match delegate selector + let parent = query(event.target).parents(delegate) + if (parent.length > 0) { event.delegate = parent[0] } else { event.delegate = event.target } + if (event.target.matches(delegate) || parent.length > 0) { + fun(event) + } + } + } + this.each(node => { + this._save(node, 'events', [{ event, scope, callback, options }]) + node.addEventListener(event, callback, options) + }) + }) + return this + } + off(events, options, callback) { + if (typeof options == 'function') { + callback = options + options = undefined + } + events = (events ?? '').split(/[,\s]+/) // separate by comma or space + events.forEach(eventName => { + let [ event, scope ] = String(eventName).toLowerCase().split('.') + this.each(node => { + if (Array.isArray(node._mQuery?.events)) { + for (let i = node._mQuery.events.length - 1; i >= 0; i--) { + let evt = node._mQuery.events[i] + if (scope == null || scope === '') { + // if no scope, has to be exact match + if ((evt.event == event || event === '') && (evt.callback == callback || callback == null)) { + node.removeEventListener(evt.event, evt.callback, evt.options) + node._mQuery.events.splice(i, 1) + } + } else { + if ((evt.event == event || event === '') && evt.scope == scope) { + node.removeEventListener(evt.event, evt.callback, evt.options) + node._mQuery.events.splice(i, 1) + } + } + } + } + }) + }) + return this + } + trigger(name, options) { + let event, + mevent = ['click', 'dblclick', 'mousedown', 'mouseup', 'mousemove'], + kevent = ['keydown', 'keyup', 'keypress'] + if (name instanceof Event || name instanceof CustomEvent) { + // MouseEvent and KeyboardEvent are instances of Event, no need to explicitly add + event = name + } else if (mevent.includes(name)) { + event = new MouseEvent(name, options) + } else if (kevent.includes(name)) { + event = new KeyboardEvent(name, options) + } else { + event = new Event(name, options) + } + this.each(node => { node.dispatchEvent(event) }) + return this + } + attr(name, value) { + if (value === undefined && typeof name == 'string') { + return this[0] ? this[0].getAttribute(name) : undefined + } else { + let obj = {} + if (typeof name == 'object') obj = name; else obj[name] = value + this.each(node => { + Object.entries(obj).forEach(([nm, val]) => { node.setAttribute(nm, val) }) + }) + return this + } + } + removeAttr() { + this.each(node => { + Array.from(arguments).forEach(attr => { + node.removeAttribute(attr) + }) + }) + return this + } + prop(name, value) { + if (value === undefined && typeof name == 'string') { + return this[0] ? this[0][name] : undefined + } else { + let obj = {} + if (typeof name == 'object') obj = name; else obj[name] = value + this.each(node => { + Object.entries(obj).forEach(([nm, val]) => { + let prop = Query._fixProp(nm) + node[prop] = val + if (prop == 'innerHTML') { + Query._scriptConvert(node) + } + }) + }) + return this + } + } + removeProp() { + this.each(node => { + Array.from(arguments).forEach(prop => { delete node[Query._fixProp(prop)] }) + }) + return this + } + data(key, value) { + if (key instanceof Object) { + Object.entries(key).forEach(item => { this.data(item[0], item[1]) }) + return + } + if (key && key.indexOf('-') != -1) { + console.error(`Key "${key}" contains "-" (dash). Dashes are not allowed in property names. Use camelCase instead.`) + } + if (arguments.length < 2) { + if (this[0]) { + let data = Object.assign({}, this[0].dataset) + Object.keys(data).forEach(key => { + if (data[key].startsWith('[') || data[key].startsWith('{')) { + try { data[key] = JSON.parse(data[key]) } catch (e) {} + } + }) + return key ? data[key] : data + } else { + return undefined + } + } else { + this.each(node => { + if (value != null) { + node.dataset[key] = value instanceof Object ? JSON.stringify(value) : value + } else { + delete node.dataset[key] + } + }) + return this + } + } + removeData(key) { + if (typeof key == 'string') key = key.split(/[,\s]+/) + this.each(node => { + key.forEach(k => { delete node.dataset[k] }) + }) + return this + } + show() { + return this.toggle(true) + } + hide() { + return this.toggle(false) + } + toggle(force) { + return this.each(node => { + let prev = node.style.display + let dsp = getComputedStyle(node).display + let isHidden = (prev == 'none' || dsp == 'none') + if (isHidden && (force == null || force === true)) { // show + let def = node instanceof HTMLTableRowElement + ? 'table-row' + : node instanceof HTMLTableCellElement + ? 'table-cell' + : 'block' + node.style.display = node._mQuery?.prevDisplay ?? (prev == dsp && dsp != 'none' ? '' : def) + this._save(node, 'prevDisplay', null) + } + if (!isHidden && (force == null || force === false)) { // hide + if (dsp != 'none') this._save(node, 'prevDisplay', dsp) + node.style.setProperty('display', 'none') + } + }) + } + empty() { + return this.html('') + } + html(html) { + return this.prop('innerHTML', html) + } + text(text) { + return this.prop('textContent', text) + } + val(value) { + return this.prop('value', value) // must be prop + } + change() { + return this.trigger('change') + } + click() { + return this.trigger('click') + } +} +// create a new object each time +let query = function (selector, context) { + // if a function, use as onload event + if (typeof selector == 'function') { + if (document.readyState == 'complete') { + selector() + } else { + window.addEventListener('load', selector) + } + } else { + return new Query(selector, context) + } +} +// str -> doc-fragment +query.html = (str) => { let frag = Query._fragment(str); return query(frag.children, frag) } +query.version = Query.version +/** + * Part of w2ui 2.0 library + * - Dependencies: mQuery, w2utils, w2base, w2locale + * + * == TODO == + * - add w2utils.lang wrap for all captions in all buttons. + * - check transition (also with layout) + * - deprecate w2utils.tooltip + * + * == 2.0 changes + * - CSP - fixed inline events (w2utils.tooltip still has it) + * - transition returns a promise + * - removed jQuery + * - refactores w2utils.message() + * - added w2utils.confirm() + * - added isPlainObject + * - added stripSpaces + * - implemented marker + * - cssPrefix - deprecated + * - w2utils.debounce + * - w2utils.prepareParams + */ + +// variable that holds all w2ui objects +let w2ui = {} +class Utils { + constructor () { + this.version = '2.0.x' + this.tmp = {} + this.settings = this.extend({}, { + 'dataType' : 'HTTPJSON', // can be HTTP, HTTPJSON, RESTFULL, JSON (case sensitive) + 'dateStartYear' : 1950, // start year for date-picker + 'dateEndYear' : 2030, // end year for date picker + 'macButtonOrder' : false, // if true, Yes on the right side + 'warnNoPhrase' : false, // call console.warn if lang() encounters a missing phrase + }, w2locale, { phrases: null }), // if there are no phrases, then it is original language + this.i18nCompare = Intl.Collator().compare + this.hasLocalStorage = testLocalStorage() + // some internal variables + this.isMac = /Mac/i.test(navigator.platform) + this.isMobile = /(iphone|ipod|ipad|mobile|android)/i.test(navigator.userAgent) + this.isIOS = /(iphone|ipod|ipad)/i.test(navigator.platform) + this.isAndroid = /(android)/i.test(navigator.userAgent) + this.isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent) + // Formatters: Primarily used in grid + this.formatters = { + 'number'(value, params) { + if (parseInt(params) > 20) params = 20 + if (parseInt(params) < 0) params = 0 + if (value == null || value === '') return '' + return w2utils.formatNumber(parseFloat(value), params, true) + }, + 'float'(value, params) { + return w2utils.formatters.number(value, params) + }, + 'int'(value, params) { + return w2utils.formatters.number(value, 0) + }, + 'money'(value, params) { + if (value == null || value === '') return '' + let data = w2utils.formatNumber(Number(value), w2utils.settings.currencyPrecision) + return (w2utils.settings.currencyPrefix || '') + data + (w2utils.settings.currencySuffix || '') + }, + 'currency'(value, params) { + return w2utils.formatters.money(value, params) + }, + 'percent'(value, params) { + if (value == null || value === '') return '' + return w2utils.formatNumber(value, params || 1) + '%' + }, + 'size'(value, params) { + if (value == null || value === '') return '' + return w2utils.formatSize(parseInt(value)) + }, + 'date'(value, params) { + if (params === '') params = w2utils.settings.dateFormat + if (value == null || value === 0 || value === '') return '' + let dt = w2utils.isDateTime(value, params, true) + if (dt === false) dt = w2utils.isDate(value, params, true) + return '' + w2utils.formatDate(dt, params) + '' + }, + 'datetime'(value, params) { + if (params === '') params = w2utils.settings.datetimeFormat + if (value == null || value === 0 || value === '') return '' + let dt = w2utils.isDateTime(value, params, true) + if (dt === false) dt = w2utils.isDate(value, params, true) + return '' + w2utils.formatDateTime(dt, params) + '' + }, + 'time'(value, params) { + if (params === '') params = w2utils.settings.timeFormat + if (params === 'h12') params = 'hh:mi pm' + if (params === 'h24') params = 'h24:mi' + if (value == null || value === 0 || value === '') return '' + let dt = w2utils.isDateTime(value, params, true) + if (dt === false) dt = w2utils.isDate(value, params, true) + return '' + w2utils.formatTime(value, params) + '' + }, + 'timestamp'(value, params) { + if (params === '') params = w2utils.settings.datetimeFormat + if (value == null || value === 0 || value === '') return '' + let dt = w2utils.isDateTime(value, params, true) + if (dt === false) dt = w2utils.isDate(value, params, true) + return dt.toString ? dt.toString() : '' + }, + 'gmt'(value, params) { + if (params === '') params = w2utils.settings.datetimeFormat + if (value == null || value === 0 || value === '') return '' + let dt = w2utils.isDateTime(value, params, true) + if (dt === false) dt = w2utils.isDate(value, params, true) + return dt.toUTCString ? dt.toUTCString() : '' + }, + 'age'(value, params) { + if (value == null || value === 0 || value === '') return '' + let dt = w2utils.isDateTime(value, null, true) + if (dt === false) dt = w2utils.isDate(value, null, true) + return '' + w2utils.age(value) + (params ? (' ' + params) : '') + '' + }, + 'interval'(value, params) { + if (value == null || value === 0 || value === '') return '' + return w2utils.interval(value) + (params ? (' ' + params) : '') + }, + 'toggle'(value, params) { + return (value ? 'Yes' : '') + }, + 'password'(value, params) { + let ret = '' + for (let i = 0; i < value.length; i++) { + ret += '*' + } + return ret + } + } + return + function testLocalStorage() { + // test if localStorage is available, see issue #1282 + let str = 'w2ui_test' + try { + localStorage.setItem(str, str) + localStorage.removeItem(str) + return true + } catch (e) { + return false + } + } + } + isBin(val) { + let re = /^[0-1]+$/ + return re.test(val) + } + isInt(val) { + let re = /^[-+]?[0-9]+$/ + return re.test(val) + } + isFloat(val) { + if (typeof val === 'string') { + val = val.replace(this.settings.groupSymbol, '') + .replace(this.settings.decimalSymbol, '.') + } + return (typeof val === 'number' || (typeof val === 'string' && val !== '')) && !isNaN(Number(val)) + } + isMoney(val) { + if (typeof val === 'object' || val === '') return false + if (this.isFloat(val)) return true + let se = this.settings + let re = new RegExp('^'+ (se.currencyPrefix ? '\\' + se.currencyPrefix + '?' : '') + + '[-+]?'+ (se.currencyPrefix ? '\\' + se.currencyPrefix + '?' : '') + + '[0-9]*[\\'+ se.decimalSymbol +']?[0-9]+'+ (se.currencySuffix ? '\\' + se.currencySuffix + '?' : '') +'$', 'i') + if (typeof val === 'string') { + val = val.replace(new RegExp(se.groupSymbol, 'g'), '') + } + return re.test(val) + } + isHex(val) { + let re = /^(0x)?[0-9a-fA-F]+$/ + return re.test(val) + } + isAlphaNumeric(val) { + let re = /^[a-zA-Z0-9_-]+$/ + return re.test(val) + } + isEmail(val) { + let email = /^[a-zA-Z0-9._%\-+]+@[а-яА-Яa-zA-Z0-9.-]+\.[а-яА-Яa-zA-Z]+$/ + return email.test(val) + } + isIpAddress(val) { + let re = new RegExp('^' + + '((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}' + + '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' + + '$') + return re.test(val) + } + isDate(val, format, retDate) { + if (!val) return false + let dt = 'Invalid Date' + let month, day, year + if (format == null) format = this.settings.dateFormat + if (typeof val.getFullYear === 'function') { // date object + year = val.getFullYear() + month = val.getMonth() + 1 + day = val.getDate() + } else if (parseInt(val) == val && parseInt(val) > 0) { + val = new Date(parseInt(val)) + year = val.getFullYear() + month = val.getMonth() + 1 + day = val.getDate() + } else { + val = String(val) + // convert month formats + if (new RegExp('mon', 'ig').test(format)) { + format = format.replace(/month/ig, 'm').replace(/mon/ig, 'm').replace(/dd/ig, 'd').replace(/[, ]/ig, '/').replace(/\/\//g, '/').toLowerCase() + val = val.replace(/[, ]/ig, '/').replace(/\/\//g, '/').toLowerCase() + for (let m = 0, len = this.settings.fullmonths.length; m < len; m++) { + let t = this.settings.fullmonths[m] + val = val.replace(new RegExp(t, 'ig'), (parseInt(m) + 1)).replace(new RegExp(t.substr(0, 3), 'ig'), (parseInt(m) + 1)) + } + } + // format date + let tmp = val.replace(/-/g, '/').replace(/\./g, '/').toLowerCase().split('/') + let tmp2 = format.replace(/-/g, '/').replace(/\./g, '/').toLowerCase() + if (tmp2 === 'mm/dd/yyyy') { month = tmp[0]; day = tmp[1]; year = tmp[2] } + if (tmp2 === 'm/d/yyyy') { month = tmp[0]; day = tmp[1]; year = tmp[2] } + if (tmp2 === 'dd/mm/yyyy') { month = tmp[1]; day = tmp[0]; year = tmp[2] } + if (tmp2 === 'd/m/yyyy') { month = tmp[1]; day = tmp[0]; year = tmp[2] } + if (tmp2 === 'yyyy/dd/mm') { month = tmp[2]; day = tmp[1]; year = tmp[0] } + if (tmp2 === 'yyyy/d/m') { month = tmp[2]; day = tmp[1]; year = tmp[0] } + if (tmp2 === 'yyyy/mm/dd') { month = tmp[1]; day = tmp[2]; year = tmp[0] } + if (tmp2 === 'yyyy/m/d') { month = tmp[1]; day = tmp[2]; year = tmp[0] } + if (tmp2 === 'mm/dd/yy') { month = tmp[0]; day = tmp[1]; year = tmp[2] } + if (tmp2 === 'm/d/yy') { month = tmp[0]; day = tmp[1]; year = parseInt(tmp[2]) + 1900 } + if (tmp2 === 'dd/mm/yy') { month = tmp[1]; day = tmp[0]; year = parseInt(tmp[2]) + 1900 } + if (tmp2 === 'd/m/yy') { month = tmp[1]; day = tmp[0]; year = parseInt(tmp[2]) + 1900 } + if (tmp2 === 'yy/dd/mm') { month = tmp[2]; day = tmp[1]; year = parseInt(tmp[0]) + 1900 } + if (tmp2 === 'yy/d/m') { month = tmp[2]; day = tmp[1]; year = parseInt(tmp[0]) + 1900 } + if (tmp2 === 'yy/mm/dd') { month = tmp[1]; day = tmp[2]; year = parseInt(tmp[0]) + 1900 } + if (tmp2 === 'yy/m/d') { month = tmp[1]; day = tmp[2]; year = parseInt(tmp[0]) + 1900 } + } + if (!this.isInt(year)) return false + if (!this.isInt(month)) return false + if (!this.isInt(day)) return false + year = +year + month = +month + day = +day + dt = new Date(year, month - 1, day) + dt.setFullYear(year) + // do checks + if (month == null) return false + if (String(dt) === 'Invalid Date') return false + if ((dt.getMonth() + 1 !== month) || (dt.getDate() !== day) || (dt.getFullYear() !== year)) return false + if (retDate === true) return dt; else return true + } + isTime(val, retTime) { + // Both formats 10:20pm and 22:20 + if (val == null) return false + let max, am, pm + // -- process american format + val = String(val) + val = val.toUpperCase() + am = val.indexOf('AM') >= 0 + pm = val.indexOf('PM') >= 0 + let ampm = (pm || am) + if (ampm) max = 12; else max = 24 + val = val.replace('AM', '').replace('PM', '').trim() + // --- + let tmp = val.split(':') + let h = parseInt(tmp[0] || 0), m = parseInt(tmp[1] || 0), s = parseInt(tmp[2] || 0) + // accept edge case: 3PM is a good timestamp, but 3 (without AM or PM) is NOT: + if ((!ampm || tmp.length !== 1) && tmp.length !== 2 && tmp.length !== 3) { return false } + if (tmp[0] === '' || h < 0 || h > max || !this.isInt(tmp[0]) || tmp[0].length > 2) { return false } + if (tmp.length > 1 && (tmp[1] === '' || m < 0 || m > 59 || !this.isInt(tmp[1]) || tmp[1].length !== 2)) { return false } + if (tmp.length > 2 && (tmp[2] === '' || s < 0 || s > 59 || !this.isInt(tmp[2]) || tmp[2].length !== 2)) { return false } + // check the edge cases: 12:01AM is ok, as is 12:01PM, but 24:01 is NOT ok while 24:00 is (midnight; equivalent to 00:00). + // meanwhile, there is 00:00 which is ok, but 0AM nor 0PM are okay, while 0:01AM and 0:00AM are. + if (!ampm && max === h && (m !== 0 || s !== 0)) { return false } + if (ampm && tmp.length === 1 && h === 0) { return false } + if (retTime === true) { + if (pm && h !== 12) h += 12 // 12:00pm - is noon + if (am && h === 12) h += 12 // 12:00am - is midnight + return { + hours: h, + minutes: m, + seconds: s + } + } + return true + } + isDateTime(val, format, retDate) { + if (typeof val.getFullYear === 'function') { // date object + if (retDate !== true) return true + return val + } + let intVal = parseInt(val) + if (intVal === val) { + if (intVal < 0) return false + else if (retDate !== true) return true + else return new Date(intVal) + } + let tmp = String(val).indexOf(' ') + if (tmp < 0) { + if (String(val).indexOf('T') < 0 || String(new Date(val)) == 'Invalid Date') return false + else if (retDate !== true) return true + else return new Date(val) + } else { + if (format == null) format = this.settings.datetimeFormat + let formats = format.split('|') + let values = [val.substr(0, tmp), val.substr(tmp).trim()] + formats[0] = formats[0].trim() + if (formats[1]) formats[1] = formats[1].trim() + // check + let tmp1 = this.isDate(values[0], formats[0], true) + let tmp2 = this.isTime(values[1], true) + if (tmp1 !== false && tmp2 !== false) { + if (retDate !== true) return true + tmp1.setHours(tmp2.hours) + tmp1.setMinutes(tmp2.minutes) + tmp1.setSeconds(tmp2.seconds) + return tmp1 + } else { + return false + } + } + } + age(dateStr) { + let d1 + if (dateStr === '' || dateStr == null) return '' + if (typeof dateStr.getFullYear === 'function') { // date object + d1 = dateStr + } else if (parseInt(dateStr) == dateStr && parseInt(dateStr) > 0) { + d1 = new Date(parseInt(dateStr)) + } else { + d1 = new Date(dateStr) + } + if (String(d1) === 'Invalid Date') return '' + let d2 = new Date() + let sec = (d2.getTime() - d1.getTime()) / 1000 + let amount = '' + let type = '' + if (sec < 0) { + amount = 0 + type = 'sec' + } else if (sec < 60) { + amount = Math.floor(sec) + type = 'sec' + if (sec < 0) { amount = 0; type = 'sec' } + } else if (sec < 60*60) { + amount = Math.floor(sec/60) + type = 'min' + } else if (sec < 24*60*60) { + amount = Math.floor(sec/60/60) + type = 'hour' + } else if (sec < 30*24*60*60) { + amount = Math.floor(sec/24/60/60) + type = 'day' + } else if (sec < 365*24*60*60) { + amount = Math.floor(sec/30/24/60/60*10)/10 + type = 'month' + } else if (sec < 365*4*24*60*60) { + amount = Math.floor(sec/365/24/60/60*10)/10 + type = 'year' + } else if (sec >= 365*4*24*60*60) { + // factor in leap year shift (only older then 4 years) + amount = Math.floor(sec/365.25/24/60/60*10)/10 + type = 'year' + } + return amount + ' ' + type + (amount > 1 ? 's' : '') + } + interval(value) { + let ret = '' + if (value < 100) { + ret = '< 0.01 sec' + } else if (value < 1000) { + ret = (Math.floor(value / 10) / 100) + ' sec' + } else if (value < 10000) { + ret = (Math.floor(value / 100) / 10) + ' sec' + } else if (value < 60000) { + ret = Math.floor(value / 1000) + ' secs' + } else if (value < 3600000) { + ret = Math.floor(value / 60000) + ' mins' + } else if (value < 86400000) { + ret = Math.floor(value / 3600000 * 10) / 10 + ' hours' + } else if (value < 2628000000) { + ret = Math.floor(value / 86400000 * 10) / 10 + ' days' + } else if (value < 3.1536e+10) { + ret = Math.floor(value / 2628000000 * 10) / 10 + ' months' + } else { + ret = Math.floor(value / 3.1536e+9) / 10 + ' years' + } + return ret + } + date(dateStr) { + if (dateStr === '' || dateStr == null || (typeof dateStr === 'object' && !dateStr.getMonth)) return '' + let d1 = new Date(dateStr) + if (this.isInt(dateStr)) d1 = new Date(Number(dateStr)) // for unix timestamps + if (String(d1) === 'Invalid Date') return '' + let months = this.settings.shortmonths + let d2 = new Date() // today + let d3 = new Date() + d3.setTime(d3.getTime() - 86400000) // yesterday + let dd1 = months[d1.getMonth()] + ' ' + d1.getDate() + ', ' + d1.getFullYear() + let dd2 = months[d2.getMonth()] + ' ' + d2.getDate() + ', ' + d2.getFullYear() + let dd3 = months[d3.getMonth()] + ' ' + d3.getDate() + ', ' + d3.getFullYear() + let time = (d1.getHours() - (d1.getHours() > 12 ? 12 :0)) + ':' + (d1.getMinutes() < 10 ? '0' : '') + d1.getMinutes() + ' ' + (d1.getHours() >= 12 ? 'pm' : 'am') + let time2 = (d1.getHours() - (d1.getHours() > 12 ? 12 :0)) + ':' + (d1.getMinutes() < 10 ? '0' : '') + d1.getMinutes() + ':' + (d1.getSeconds() < 10 ? '0' : '') + d1.getSeconds() + ' ' + (d1.getHours() >= 12 ? 'pm' : 'am') + let dsp = dd1 + if (dd1 === dd2) dsp = time + if (dd1 === dd3) dsp = this.lang('Yesterday') + return ''+ dsp +'' + } + formatSize(sizeStr) { + if (!this.isFloat(sizeStr) || sizeStr === '') return '' + sizeStr = parseFloat(sizeStr) + if (sizeStr === 0) return 0 + let sizes = ['Bt', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB'] + let i = parseInt( Math.floor( Math.log(sizeStr) / Math.log(1024) ) ) + return (Math.floor(sizeStr / Math.pow(1024, i) * 10) / 10).toFixed(i === 0 ? 0 : 1) + ' ' + (sizes[i] || '??') + } + formatNumber(val, fraction, useGrouping) { + if (val == null || val === '' || typeof val === 'object') return '' + let options = { + minimumFractionDigits: parseInt(fraction), + maximumFractionDigits: parseInt(fraction), + useGrouping: !!useGrouping + } + if (fraction == null || fraction < 0) { + options.minimumFractionDigits = 0 + options.maximumFractionDigits = 20 + } + return parseFloat(val).toLocaleString(this.settings.locale, options) + } + formatDate(dateStr, format) { // IMPORTANT dateStr HAS TO BE valid JavaScript Date String + if (!format) format = this.settings.dateFormat + if (dateStr === '' || dateStr == null || (typeof dateStr === 'object' && !dateStr.getMonth)) return '' + let dt = new Date(dateStr) + if (this.isInt(dateStr)) dt = new Date(Number(dateStr)) // for unix timestamps + if (String(dt) === 'Invalid Date') return '' + let year = dt.getFullYear() + let month = dt.getMonth() + let date = dt.getDate() + return format.toLowerCase() + .replace('month', this.settings.fullmonths[month]) + .replace('mon', this.settings.shortmonths[month]) + .replace(/yyyy/g, ('000' + year).slice(-4)) + .replace(/yyy/g, ('000' + year).slice(-4)) + .replace(/yy/g, ('0' + year).slice(-2)) + .replace(/(^|[^a-z$])y/g, '$1' + year) // only y's that are not preceded by a letter + .replace(/mm/g, ('0' + (month + 1)).slice(-2)) + .replace(/dd/g, ('0' + date).slice(-2)) + .replace(/th/g, (date == 1 ? 'st' : 'th')) + .replace(/th/g, (date == 2 ? 'nd' : 'th')) + .replace(/th/g, (date == 3 ? 'rd' : 'th')) + .replace(/(^|[^a-z$])m/g, '$1' + (month + 1)) // only y's that are not preceded by a letter + .replace(/(^|[^a-z$])d/g, '$1' + date) // only y's that are not preceded by a letter + } + formatTime(dateStr, format) { // IMPORTANT dateStr HAS TO BE valid JavaScript Date String + if (!format) format = this.settings.timeFormat + if (dateStr === '' || dateStr == null || (typeof dateStr === 'object' && !dateStr.getMonth)) return '' + let dt = new Date(dateStr) + if (this.isInt(dateStr)) dt = new Date(Number(dateStr)) // for unix timestamps + if (this.isTime(dateStr)) { + let tmp = this.isTime(dateStr, true) + dt = new Date() + dt.setHours(tmp.hours) + dt.setMinutes(tmp.minutes) + } + if (String(dt) === 'Invalid Date') return '' + let type = 'am' + let hour = dt.getHours() + let h24 = dt.getHours() + let min = dt.getMinutes() + let sec = dt.getSeconds() + if (min < 10) min = '0' + min + if (sec < 10) sec = '0' + sec + if (format.indexOf('am') !== -1 || format.indexOf('pm') !== -1) { + if (hour >= 12) type = 'pm' + if (hour > 12) hour = hour - 12 + if (hour === 0) hour = 12 + } + return format.toLowerCase() + .replace('am', type) + .replace('pm', type) + .replace('hhh', (hour < 10 ? '0' + hour : hour)) + .replace('hh24', (h24 < 10 ? '0' + h24 : h24)) + .replace('h24', h24) + .replace('hh', hour) + .replace('mm', min) + .replace('mi', min) + .replace('ss', sec) + .replace(/(^|[^a-z$])h/g, '$1' + hour) // only y's that are not preceded by a letter + .replace(/(^|[^a-z$])m/g, '$1' + min) // only y's that are not preceded by a letter + .replace(/(^|[^a-z$])s/g, '$1' + sec) // only y's that are not preceded by a letter + } + formatDateTime(dateStr, format) { + let fmt + if (dateStr === '' || dateStr == null || (typeof dateStr === 'object' && !dateStr.getMonth)) return '' + if (typeof format !== 'string') { + fmt = [this.settings.dateFormat, this.settings.timeFormat] + } else { + fmt = format.split('|') + fmt[0] = fmt[0].trim() + fmt[1] = (fmt.length > 1 ? fmt[1].trim() : this.settings.timeFormat) + } + // older formats support + if (fmt[1] === 'h12') fmt[1] = 'h:m pm' + if (fmt[1] === 'h24') fmt[1] = 'h24:m' + return this.formatDate(dateStr, fmt[0]) + ' ' + this.formatTime(dateStr, fmt[1]) + } + stripSpaces(html) { + if (html == null) return html + switch (typeof html) { + case 'number': + break + case 'string': + html = String(html).replace(/(?:\r\n|\r|\n)/g, ' ').replace(/\s\s+/g, ' ').trim() + break + case 'object': + // does not modify original object, but creates a copy + if (Array.isArray(html)) { + html = this.extend([], html) + html.forEach((key, ind) => { + html[ind] = this.stripSpaces(key) + }) + } else { + html = this.extend({}, html) + Object.keys(html).forEach(key => { + html[key] = this.stripSpaces(html[key]) + }) + } + break + } + return html + } + stripTags(html) { + if (html == null) return html + switch (typeof html) { + case 'number': + break + case 'string': + html = String(html).replace(/<(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*>/ig, '') + break + case 'object': + // does not modify original object, but creates a copy + if (Array.isArray(html)) { + html = this.extend([], html) + html.forEach((key, ind) => { + html[ind] = this.stripTags(key) + }) + } else { + html = this.extend({}, html) + Object.keys(html).forEach(key => { + html[key] = this.stripTags(html[key]) + }) + } + break + } + return html + } + encodeTags(html) { + if (html == null) return html + switch (typeof html) { + case 'number': + break + case 'string': + html = String(html).replace(/&/g, '&').replace(/>/g, '>').replace(/ { + html[ind] = this.encodeTags(key) + }) + } else { + html = this.extend({}, html) + Object.keys(html).forEach(key => { + html[key] = this.encodeTags(html[key]) + }) + } + break + } + return html + } + decodeTags(html) { + if (html == null) return html + switch (typeof html) { + case 'number': + break + case 'string': + html = String(html).replace(/>/g, '>').replace(/</g, '<').replace(/"/g, '"').replace(/&/g, '&') + break + case 'object': + // does not modify original object, but creates a copy + if (Array.isArray(html)) { + html = this.extend([], html) + html.forEach((key, ind) => { + html[ind] = this.decodeTags(key) + }) + } else { + html = this.extend({}, html) + Object.keys(html).forEach(key => { + html[key] = this.decodeTags(html[key]) + }) + } + break + } + return html + } + escapeId(id) { + // This logic is borrowed from jQuery + if (id === '' || id == null) return '' + let re = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g + return (id + '').replace(re, (ch, asCodePoint) => { + if (asCodePoint) { + if (ch === '\0') return '\uFFFD' + return ch.slice( 0, -1 ) + '\\' + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + ' ' + } + return '\\' + ch + }) + } + unescapeId(id) { + // This logic is borrowed from jQuery + if (id === '' || id == null) return '' + let re = /\\[\da-fA-F]{1,6}[\x20\t\r\n\f]?|\\([^\r\n\f])/g + return id.replace(re, (escape, nonHex) => { + let high = '0x' + escape.slice( 1 ) - 0x10000 + return nonHex ? nonHex : high < 0 + ? String.fromCharCode(high + 0x10000 ) + : String.fromCharCode(high >> 10 | 0xD800, high & 0x3FF | 0xDC00) + }) + } + base64encode(input) { + // Fast Native support in Chrome since 2010 + return btoa(input) // binary to ascii + } + base64decode(input) { + // Fast Native support in Chrome since 2010 + return atob(input) // ascii to binary + } + async sha256(str) { + const utf8 = new TextEncoder().encode(str) + return crypto.subtle.digest('SHA-256', utf8).then((hashBuffer) => { + const hashArray = Array.from(new Uint8Array(hashBuffer)) + return hashArray.map((bytes) => bytes.toString(16).padStart(2, '0')).join('') + }) + } + transition(div_old, div_new, type, callBack) { + return new Promise((resolve, reject) => { + let styles = getComputedStyle(div_old) + let width = parseInt(styles.width) + let height = parseInt(styles.height) + let time = 0.5 + if (!div_old || !div_new) { + console.log('ERROR: Cannot do transition when one of the divs is null') + return + } + div_old.parentNode.style.cssText += 'perspective: 900px; overflow: hidden;' + div_old.style.cssText += '; position: absolute; z-index: 1019; backface-visibility: hidden' + div_new.style.cssText += '; position: absolute; z-index: 1020; backface-visibility: hidden' + switch (type) { + case 'slide-left': + // init divs + div_old.style.cssText += 'overflow: hidden; transform: translate3d(0, 0, 0)' + div_new.style.cssText += 'overflow: hidden; transform: translate3d('+ width + 'px, 0, 0)' + query(div_new).show() + // -- need a timing function because otherwise not working + setTimeout(() => { + div_new.style.cssText += 'transition: '+ time +'s; transform: translate3d(0, 0, 0)' + div_old.style.cssText += 'transition: '+ time +'s; transform: translate3d(-'+ width +'px, 0, 0)' + }, 1) + break + case 'slide-right': + // init divs + div_old.style.cssText += 'overflow: hidden; transform: translate3d(0, 0, 0)' + div_new.style.cssText += 'overflow: hidden; transform: translate3d(-'+ width +'px, 0, 0)' + query(div_new).show() + // -- need a timing function because otherwise not working + setTimeout(() => { + div_new.style.cssText += 'transition: '+ time +'s; transform: translate3d(0px, 0, 0)' + div_old.style.cssText += 'transition: '+ time +'s; transform: translate3d('+ width +'px, 0, 0)' + }, 1) + break + case 'slide-down': + // init divs + div_old.style.cssText += 'overflow: hidden; z-index: 1; transform: translate3d(0, 0, 0)' + div_new.style.cssText += 'overflow: hidden; z-index: 0; transform: translate3d(0, 0, 0)' + query(div_new).show() + // -- need a timing function because otherwise not working + setTimeout(() => { + div_new.style.cssText += 'transition: '+ time +'s; transform: translate3d(0, 0, 0)' + div_old.style.cssText += 'transition: '+ time +'s; transform: translate3d(0, '+ height +'px, 0)' + }, 1) + break + case 'slide-up': + // init divs + div_old.style.cssText += 'overflow: hidden; transform: translate3d(0, 0, 0)' + div_new.style.cssText += 'overflow: hidden; transform: translate3d(0, '+ height +'px, 0)' + query(div_new).show() + // -- need a timing function because otherwise not working + setTimeout(() => { + div_new.style.cssText += 'transition: '+ time +'s; transform: translate3d(0, 0, 0)' + div_old.style.cssText += 'transition: '+ time +'s; transform: translate3d(0, 0, 0)' + }, 1) + break + case 'flip-left': + // init divs + div_old.style.cssText += 'overflow: hidden; transform: rotateY(0deg)' + div_new.style.cssText += 'overflow: hidden; transform: rotateY(-180deg)' + query(div_new).show() + // -- need a timing function because otherwise not working + setTimeout(() => { + div_new.style.cssText += 'transition: '+ time +'s; transform: rotateY(0deg)' + div_old.style.cssText += 'transition: '+ time +'s; transform: rotateY(180deg)' + }, 1) + break + case 'flip-right': + // init divs + div_old.style.cssText += 'overflow: hidden; transform: rotateY(0deg)' + div_new.style.cssText += 'overflow: hidden; transform: rotateY(180deg)' + query(div_new).show() + // -- need a timing function because otherwise not working + setTimeout(() => { + div_new.style.cssText += 'transition: '+ time +'s; transform: rotateY(0deg)' + div_old.style.cssText += 'transition: '+ time +'s; transform: rotateY(-180deg)' + }, 1) + break + case 'flip-down': + // init divs + div_old.style.cssText += 'overflow: hidden; transform: rotateX(0deg)' + div_new.style.cssText += 'overflow: hidden; transform: rotateX(180deg)' + query(div_new).show() + // -- need a timing function because otherwise not working + setTimeout(() => { + div_new.style.cssText += 'transition: '+ time +'s; transform: rotateX(0deg)' + div_old.style.cssText += 'transition: '+ time +'s; transform: rotateX(-180deg)' + }, 1) + break + case 'flip-up': + // init divs + div_old.style.cssText += 'overflow: hidden; transform: rotateX(0deg)' + div_new.style.cssText += 'overflow: hidden; transform: rotateX(-180deg)' + query(div_new).show() + // -- need a timing function because otherwise not working + setTimeout(() => { + div_new.style.cssText += 'transition: '+ time +'s; transform: rotateX(0deg)' + div_old.style.cssText += 'transition: '+ time +'s; transform: rotateX(180deg)' + }, 1) + break + case 'pop-in': + // init divs + div_old.style.cssText += 'overflow: hidden; transform: translate3d(0, 0, 0)' + div_new.style.cssText += 'overflow: hidden; transform: translate3d(0, 0, 0); transform: scale(.8); opacity: 0;' + query(div_new).show() + // -- need a timing function because otherwise not working + setTimeout(() => { + div_new.style.cssText += 'transition: '+ time +'s; transform: scale(1); opacity: 1;' + div_old.style.cssText += 'transition: '+ time +'s;' + }, 1) + break + case 'pop-out': + // init divs + div_old.style.cssText += 'overflow: hidden; transform: translate3d(0, 0, 0); transform: scale(1); opacity: 1;' + div_new.style.cssText += 'overflow: hidden; transform: translate3d(0, 0, 0); opacity: 0;' + query(div_new).show() + // -- need a timing function because otherwise not working + setTimeout(() => { + div_new.style.cssText += 'transition: '+ time +'s; opacity: 1;' + div_old.style.cssText += 'transition: '+ time +'s; transform: scale(1.7); opacity: 0;' + }, 1) + break + default: + // init divs + div_old.style.cssText += 'overflow: hidden; transform: translate3d(0, 0, 0)' + div_new.style.cssText += 'overflow: hidden; translate3d(0, 0, 0); opacity: 0;' + query(div_new).show() + // -- need a timing function because otherwise not working + setTimeout(() => { + div_new.style.cssText += 'transition: '+ time +'s; opacity: 1;' + div_old.style.cssText += 'transition: '+ time +'s' + }, 1) + break + } + setTimeout(() => { + if (type === 'slide-down') { + query(div_old).css('z-index', '1019') + query(div_new).css('z-index', '1020') + } + if (div_new) { + query(div_new) + .css({ 'opacity': '1' }) + .css({ 'transition': '', 'transform' : '' }) + } + if (div_old) { + query(div_old) + .css({ 'opacity': '1' }) + .css({ 'transition': '', 'transform' : '' }) + } + if (typeof callBack === 'function') callBack() + resolve() + }, time * 1000) + }) + } + lock(box, options = {}) { + if (box == null) return + if (typeof options == 'string') { + options = { msg: options } + } + if (arguments[2]) { + options.spinner = arguments[2] + } + options = this.extend({ + spinner: false + }, options) + // for backward compatibility + if (box?.[0] instanceof Node) { + box = Array.isArray(box) ? box : box.get() + } + if (!options.msg && options.msg !== 0) options.msg = '' + this.unlock(box) + let el = query(box).get(0) + let pWidth = el.scrollWidth + let pHeight = el.scrollHeight + // if it is body and only has absolute elements, its height will be 0, need to lock entire window + if (el.tagName == 'BODY') { + if (pWidth < innerWidth) pWidth = innerWidth + if (pHeight < innerHeight) pHeight = innerHeight + } + query(box).prepend( + `
    ` + + '
    ' + ) + let $lock = query(box).find('.w2ui-lock') + let $mess = query(box).find('.w2ui-lock-msg') + if (!options.msg) { + $mess.css({ + 'background-color': 'transparent', + 'background-image': 'none', + 'border': '0px', + 'box-shadow': 'none' + }) + } + if (options.spinner === true) { + options.msg = `
    ` + + options.msg + } + if (options.msg) { + $mess.html(options.msg).css('display', 'block') + } else { + $mess.remove() + } + if (options.opacity != null) { + $lock.css('opacity', options.opacity) + } + $lock.css({ display: 'block' }) + if (options.bgColor) { + $lock.css({ 'background-color': options.bgColor }) + } + let styles = getComputedStyle($lock.get(0)) + let opacity = styles.opacity ?? 0.15 + $lock + .on('mousedown', function() { + if (typeof options.onClick == 'function') { + options.onClick() + } else { + $lock.css({ + 'transition': '.2s', + 'opacity': opacity * 1.5 + }) + } + }) + .on('mouseup', function() { + if (typeof options.onClick !== 'function') { + $lock.css({ + 'transition': '.2s', + 'opacity': opacity + }) + } + }) + .on('mousewheel', function(event) { + if (event) { + event.stopPropagation() + event.preventDefault() + } + }) + } + unlock(box, speed) { + if (box == null) return + clearTimeout(box._prevUnlock) + // for backward compatibility + if (box?.[0] instanceof Node) { + box = Array.isArray(box) ? box : box.get() + } + if (this.isInt(speed) && speed > 0) { + query(box).find('.w2ui-lock').css({ + transition: (speed/1000) + 's', + opacity: 0, + }) + let _box = query(box).get(0) + clearTimeout(_box._prevUnlock) + _box._prevUnlock = setTimeout(() => { + query(box).find('.w2ui-lock').remove() + }, speed) + query(box).find('.w2ui-lock-msg').remove() + } else { + query(box).find('.w2ui-lock').remove() + query(box).find('.w2ui-lock-msg').remove() + } + } + /** + * Opens a context message, similar in parameters as w2popup.open() + * + * Sample Calls + * w2utils.message({ box: '#div' }, 'message').ok(() => {}) + * w2utils.message({ box: '#div' }, { text: 'message', width: 300 }).ok(() => {}) + * w2utils.message({ box: '#div' }, { text: 'message', actions: ['Save'] }).Save(() => {}) + * + * Used in w2grid, w2form, w2layout (should be in w2popup too) + * should be called with .call(...) method + * + * @param where = { + * box, // where to open + * after, // title if any, adds title heights + * param // additional parameters, used in layouts for panel + * } + * @param options { + * width, // (int), width in px, if negative, then it is maxWidth - width + * height, // (int), height in px, if negative, then it is maxHeight - height + * text, // centered text + * body, // body of the message + * buttons, // buttons of the message + * html, // if body & buttons are not defined, then html is the entire message + * focus, // int or id with a selector, default is 0 + * hideOn, // ['esc', 'click'], default is ['esc'] + * actions, // array of actions (only if buttons is not defined) + * onOpen, // event when opened + * onClose, // event when closed + * onAction, // event on action + * } + */ + message(where, options) { + let closeTimer, openTimer, edata + let removeLast = () => { + let msgs = query(where?.box).find('.w2ui-message') + if (msgs.length == 0) return // no messages already + options = msgs.get(0)._msg_options || {} + if (typeof options?.close == 'function') { + options.close() + } + } + let closeComplete = (options) => { + let focus = options.box._msg_prevFocus + if (query(where.box).find('.w2ui-message').length <= 1) { + if (where.owner) { + where.owner.unlock(where.param, 150) + } else { + this.unlock(where.box, 150) + } + } else { + query(where.box).find(`#w2ui-message-${where.owner?.name}-${options.msgIndex-1}`).css('z-index', 1500) + } + if (focus) { + let msg = query(focus).closest('.w2ui-message') + if (msg.length > 0) { + let opt = msg.get(0)._msg_options + opt.setFocus(focus) + } else { + focus.focus() + } + } else { + if (typeof where.owner?.focus == 'function') where.owner.focus() + } + query(options.box).remove() + if (options.msgIndex === 0) { + head.css('z-index', options.tmp.zIndex) + query(where.box).css('overflow', options.tmp.overflow) + } + // event after + if (options.trigger) { + edata.finish() + } + } + if (typeof options == 'string' || typeof options == 'number') { + options = { + width : (String(options).length < 300 ? 350 : 550), + height: (String(options).length < 300 ? 170: 250), + text : String(options), + } + } + if (typeof options != 'object') { + removeLast() + return + } + if (options.text != null) options.body = `
    ${options.text}
    ` + if (options.width == null) options.width = 350 + if (options.height == null) options.height = 170 + if (options.hideOn == null) options.hideOn = ['esc'] + // mix in events + if (options.on == null) { + let opts = options + options = new w2base() + w2utils.extend(options, opts) // needs to be w2utils + } + options.on('open', (event) => { + w2utils.bindEvents(query(options.box).find('.w2ui-eaction'), options) // options is w2base object + query(event.detail.box).find('button, input, textarea, [name=hidden-first]') + .off('.message') + .on('keydown.message', function(evt) { + if (evt.keyCode == 27 && options.hideOn.includes('esc')) { + if (options.cancelAction) { + options.action(options.cancelAction) + } else { + options.close() + } + } + }) + // timeout is needed because messages opens over 0.3 seconds + setTimeout(() => options.setFocus(options.focus), 300) + }) + options.off('.prom') + let prom = { + self: options, + action(callBack) { + options.on('action.prom', callBack) + return prom + }, + close(callBack) { + options.on('close.prom', callBack) + return prom + }, + open(callBack) { + options.on('open.prom', callBack) + return prom + }, + then(callBack) { + options.on('open:after.prom', callBack) + return prom + } + } + if (options.actions == null && options.buttons == null && options.html == null) { + options.actions = { Ok(event) { event.detail.self.close() }} + } + options.off('.buttons') + if (options.actions != null) { + options.buttons = '' + Object.keys(options.actions).forEach((action) => { + let handler = options.actions[action] + let btnAction = action + if (typeof handler == 'function') { + options.buttons += `` + } + if (typeof handler == 'object') { + options.buttons += `` + btnAction = Array.isArray(options.actions) ? handler.text : action + } + if (typeof handler == 'string') { + options.buttons += `` + btnAction = handler + } + if (typeof btnAction == 'string') { + btnAction = btnAction[0].toLowerCase() + btnAction.substr(1).replace(/\s+/g, '') + } + prom[btnAction] = function (callBack) { + options.on('action.buttons', (event) => { + let target = event.detail.action[0].toLowerCase() + event.detail.action.substr(1).replace(/\s+/g, '') + if (target == btnAction) callBack(event) + }) + return prom + } + }) + } + // trim if any + Array('html', 'body', 'buttons').forEach(param => { + options[param] = String(options[param] ?? '').trim() + }) + if (options.body !== '' || options.buttons !== '') { + options.html = ` +
    ${options.body || ''}
    +
    ${options.buttons || ''}
    + ` + } + let styles = getComputedStyle(query(where.box).get(0)) + let pWidth = parseFloat(styles.width) + let pHeight = parseFloat(styles.height) + let titleHeight = 0 + if (query(where.after).length > 0) { + styles = getComputedStyle(query(where.after).get(0)) + titleHeight = parseInt(styles.display != 'none' ? parseInt(styles.height) : 0) + } + if (options.width > pWidth) options.width = pWidth - 10 + if (options.height > pHeight - titleHeight) options.height = pHeight - 10 - titleHeight + options.originalWidth = options.width + options.originalHeight = options.height + if (parseInt(options.width) < 0) options.width = pWidth + options.width + if (parseInt(options.width) < 10) options.width = 10 + if (parseInt(options.height) < 0) options.height = pHeight + options.height - titleHeight + if (parseInt(options.height) < 10) options.height = 10 + // negative value means margin + if (options.originalHeight < 0) options.height = pHeight + options.originalHeight - titleHeight + if (options.originalWidth < 0) options.width = pWidth + options.originalWidth * 2 // x 2 because there is left and right margin + let head = query(where.box).find(where.after) // needed for z-index manipulations + if (!options.tmp) { + options.tmp = { + zIndex: head.css('z-index'), + overflow: styles.overflow + } + } + // remove message + if (options.html === '' && options.body === '' && options.buttons === '') { + removeLast() + } else { + options.msgIndex = query(where.box).find('.w2ui-message').length + if (options.msgIndex === 0 && typeof this.lock == 'function') { + query(where.box).css('overflow', 'hidden') + if (where.owner) { // where.praram is used in the panel + where.owner.lock(where.param) + } else { + this.lock(where.box) + } + } + // send back previous messages + query(where.box).find('.w2ui-message').css('z-index', 1390) + head.css('z-index', 1501) + // add message + let content = ` +
    + + ${options.html} + +
    ` + if (query(where.after).length > 0) { + query(where.box).find(where.after).after(content) + } else { + query(where.box).prepend(content) + } + options.box = query(where.box).find(`#w2ui-message-${where.owner?.name}-${options.msgIndex}`)[0] + w2utils.bindEvents(options.box, this) + query(options.box) + .addClass('animating') + // remember options and prev focus + options.box._msg_options = options + options.box._msg_prevFocus = document.activeElement + // timeout is needs so that callBacks are setup + setTimeout(() => { + // before event + edata = options.trigger('open', { target: this.name, box: options.box, self: options }) + if (edata.isCancelled === true) { + query(where.box).find(`#w2ui-message-${where.owner?.name}-${options.msgIndex}`).remove() + if (options.msgIndex === 0) { + head.css('z-index', options.tmp.zIndex) + query(where.box).css('overflow', options.tmp.overflow) + } + return + } + // slide down + query(options.box).css({ + transition: '0.3s', + transform: 'translateY(0px)' + }) + }, 0) + // timeout is needed so that animation can finish + openTimer = setTimeout(() => { + // has to be on top of lock + query(where.box) + .find(`#w2ui-message-${where.owner?.name}-${options.msgIndex}`) + .removeClass('animating') + .css({ 'transition': '0s' }) + // event after + edata.finish() + }, 300) + } + // action handler + options.action = (action, event) => { + let click = options.actions[action] + if (click instanceof Object && click.onClick) click = click.onClick + // event before + let edata = options.trigger('action', { target: this.name, action, self: options, + originalEvent: event, value: options.input ? options.input.value : null }) + if (edata.isCancelled === true) return + // default actions + if (typeof click === 'function') click(edata) + // event after + edata.finish() + } + options.close = () => { + edata = options.trigger('close', { target: 'self', box: options.box, self: options }) + if (edata.isCancelled === true) return + clearTimeout(openTimer) + if (query(options.box).hasClass('animating')) { + clearTimeout(closeTimer) + closeComplete(options) + return + } + // default behavior + query(options.box) + .addClass('w2ui-closing animating') + .css({ + 'transition': '0.15s', + 'transform': 'translateY(-' + options.height + 'px)' + }) + if (options.msgIndex !== 0) { + // previous message + query(where.box).find(`#w2ui-message-${where.owner?.name}-${options.msgIndex-1}`).css('z-index', 1499) + } + closeTimer = setTimeout(() => { closeComplete(options) }, 150) + } + options.setFocus = (focus) => { + // in message or popup + let cnt = query(where.box).find('.w2ui-message').length - 1 + let box = query(where.box).find(`#w2ui-message-${where.owner?.name}-${cnt}`) + let sel = 'input, button, select, textarea, [contentEditable], .w2ui-input' + if (focus != null) { + let el = isNaN(focus) + ? box.find(sel).filter(focus).get(0) + : box.find(sel).get(focus) + el?.focus() + } else { + box.find('[name=hidden-first]').get(0)?.focus() + } + // clear focus if there are other messages + query(where.box) + .find('.w2ui-message') + .find(sel + ',[name=hidden-first],[name=hidden-last]') + .off('.keep-focus') + // keep focus/blur inside popup + query(box) + .find(sel + ',[name=hidden-first],[name=hidden-last]') + .on('blur.keep-focus', function (event) { + setTimeout(() => { + let focus = document.activeElement + let inside = query(box).find(sel).filter(focus).length > 0 + let name = query(focus).attr('name') + if (!inside && focus && focus !== document.body) { + query(box).find(sel).get(0)?.focus() + } + if (name == 'hidden-last') { + query(box).find(sel).get(0)?.focus() + } + if (name == 'hidden-first') { + query(box).find(sel).get(-1)?.focus() + } + }, 1) + }) + } + return prom + } + /** + * Shows small notification message at the bottom of the page, or containter that you specify + * in options.where (could be element or a selector) + * + * w2utils.notify('Document saved') + * w2utils.notify('Mesage sent ${udon}', { actions: { undo: function () {...} }}) + * + * @param {String/Object} options can be { + * text: string, // message, can be html + * where: el/selector, // element or selector where to show, default is document.body + * timeout: int, // timeout when to hide, if 0 - indefinite + * error: boolean, // add error clases + * class: string, // additional class strings + * actions: object // object with action functions, it should correspot to templated text: '... ${action} ...' + * } + * @returns promise + */ + notify(text, options) { + return new Promise(resolve => { + if (typeof text == 'object') { + options = text + text = options.text + } + options = options || {} + options.where = options.where ?? document.body + options.timeout = options.timeout ?? 15_000 // 15 secodns or will be hidden on route change + if (typeof this.tmp.notify_resolve == 'function') { + this.tmp.notify_resolve() + query(this.tmp.notify_where).find('#w2ui-notify').remove() + } + this.tmp.notify_resolve = resolve + this.tmp.notify_where = options.where + clearTimeout(this.tmp.notify_timer) + if (text) { + if (typeof options.actions == 'object') { + let actions = {} + Object.keys(options.actions).forEach(action => { + actions[action] = `${action}` + }) + text = this.execTemplate(text, actions) + } + let html = ` +
    +
    + ${text} + +
    +
    ` + query(options.where).append(html) + query(options.where).find('#w2ui-notify').find('.w2ui-notify-close') + .on('click', event => { + query(options.where).find('#w2ui-notify').remove() + resolve() + }) + if (options.actions) { + query(options.where).find('#w2ui-notify .w2ui-notify-link') + .on('click', event => { + let value = query(event.target).attr('value') + options.actions[value]() + query(options.where).find('#w2ui-notify').remove() + resolve() + }) + } + if (options.timeout > 0) { + this.tmp.notify_timer = setTimeout(() => { + query(options.where).find('#w2ui-notify').remove() + resolve() + }, options.timeout) + } + } + }) + } + confirm(where, options) { + if (typeof options == 'string') { + options = { text: options } + } + w2utils.normButtons(options, { yes: 'Yes', no: 'No' }) + let prom = w2utils.message(where, options) + if (prom) { + prom.action(event => { + event.detail.self.close() + }) + } + return prom + } + /** + * Normalizes yes, no buttons for confirmation dialog + * + * @param {*} options + * @returns options + */ + normButtons(options, btn) { + options.actions = options.actions ?? {} + let btns = Object.keys(btn) + btns.forEach(name => { + let action = options['btn_' + name] + if (action) { + btn[name] = { + text: w2utils.lang(action.text ?? ''), + class: action.class ?? '', + style: action.style ?? '', + attrs: action.attrs ?? '' + } + delete options['btn_' + name] + } + Array('text', 'class', 'style', 'attrs').forEach(suffix => { + if (options[name + '_' + suffix]) { + if (typeof btn[name] == 'string') { + btn[name] = { text: btn[name] } + } + btn[name][suffix] = options[name + '_' + suffix] + delete options[name + '_' + suffix] + } + }) + }) + if (btns.includes('yes') && btns.includes('no')) { + if (w2utils.settings.macButtonOrder) { + w2utils.extend(options.actions, { no: btn.no, yes: btn.yes }) + } else { + w2utils.extend(options.actions, { yes: btn.yes, no: btn.no }) + } + } + if (btns.includes('ok') && btns.includes('cancel')) { + if (w2utils.settings.macButtonOrder) { + w2utils.extend(options.actions, { cancel: btn.cancel, ok: btn.ok }) + } else { + w2utils.extend(options.actions, { ok: btn.ok, cancel: btn.cancel }) + } + } + return options + } + getSize(el, type) { + el = query(el) // for backward compatibility + let ret = 0 + if (el.length > 0) { + el = el[0] + let styles = getComputedStyle(el) + switch (type) { + case 'width' : + ret = parseFloat(styles.width) + if (styles.width === 'auto') ret = 0 + break + case 'height' : + ret = parseFloat(styles.height) + if (styles.height === 'auto') ret = 0 + break + default: + ret = parseFloat(styles[type] ?? 0) || 0 + break + } + } + return ret + } + getStrWidth(str, styles) { + query('body').append(` +
    + ${this.encodeTags(str)} +
    `) + let width = query('#_tmp_width')[0].clientWidth + query('#_tmp_width').remove() + return width + } + execTemplate(str, replace_obj) { + if (typeof str !== 'string' || !replace_obj || typeof replace_obj !== 'object') { + return str + } + return str.replace(/\${([^}]+)?}/g, function($1, $2) { return replace_obj[$2]||$2 }) + } + marker(el, items, options = { onlyFirst: false, wholeWord: false }) { + if (!Array.isArray(items)) { + if (items != null && items !== '') { + items = [items] + } else { + items = [] + } + } + let ww = options.wholeWord + query(el).each(el => { + clearMerkers(el) + items.forEach(str => { + if (typeof str !== 'string') str = String(str) + let replaceValue = (matched) => { // mark new + return '' + matched + '' + } + // escape regex special chars + str = str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&').replace(/&/g, '&') + .replace(//g, '<') + let regex = new RegExp((ww ? '\\b' : '') + str + (ww ? '\\b' : '')+ '(?!([^<]+)?>)', + 'i' + (!options.onlyFirst ? 'g' : '')) // only outside tags + el.innerHTML = el.innerHTML.replace(regex, replaceValue) + }) + }) + function clearMerkers(el) { + let markerRE = /\((.|\n|\r)*)\<\/span\>/ig + while (el.innerHTML.indexOf('='.includes(phrase)) { + return this.execTemplate(phrase, params) + } + let translation = this.settings.phrases[phrase] + if (translation == null) { + translation = phrase + if (this.settings.warnNoPhrase) { + if (!this.settings.missing) { + this.settings.missing = {} + } + this.settings.missing[phrase] = '---' // collect phrases for translation, warn once + this.settings.phrases[phrase] = '---' + console.log(`Missing translation for "%c${phrase}%c", see %c w2utils.settings.phrases %c with value "---"`, + 'color: orange', '', + 'color: #999', '') + } + } else if (translation === '---' && !this.settings.warnNoPhrase) { + translation = phrase + } + if (translation === '---') { + translation = `---` + } + return this.execTemplate(translation, params) + } + locale(locale, keepPhrases, noMerge) { + return new Promise((resolve, reject) => { + // if locale is an array we call this function recursively and merge the results + if (Array.isArray(locale)) { + this.settings.phrases = {} + let proms = [] + let files = {} + locale.forEach((file, ind) => { + if (file.length === 5) { + file = 'locale/'+ file.toLowerCase() +'.json' + locale[ind] = file + } + proms.push(this.locale(file, true, false)) + }) + Promise.allSettled(proms) + .then(res => { + // order of files is important to merge + res.forEach(r => { if (r.value) files[r.value.file] = r.value.data }) + locale.forEach(file => { + this.settings = this.extend({}, this.settings, files[file]) + }) + resolve() + }) + return + } + if (!locale) locale = 'en-us' + // if locale is an object, then merge it with w2utils.settings + if (locale instanceof Object) { + this.settings = this.extend({}, this.settings, w2locale, locale) + return + } + if (locale.length === 5) { + locale = 'locale/'+ locale.toLowerCase() +'.json' + } + // load from the file + fetch(locale, { method: 'GET' }) + .then(res => res.json()) + .then(data => { + if (noMerge !== true) { + if (keepPhrases) { + // keep phrases, useful for recursive calls + this.settings = this.extend({}, this.settings, data) + } else { + // clear phrases from language before merging + this.settings = this.extend({}, this.settings, w2locale, { phrases: {} }, data) + } + } + resolve({ file: locale, data }) + }) + .catch((err) => { + console.log('ERROR: Cannot load locale '+ locale) + reject(err) + }) + }) + } + scrollBarSize() { + if (this.tmp.scrollBarSize) return this.tmp.scrollBarSize + let html = ` +
    +
    1
    +
    + ` + query('body').append(html) + this.tmp.scrollBarSize = 100 - query('#_scrollbar_width > div')[0].clientWidth + query('#_scrollbar_width').remove() + return this.tmp.scrollBarSize + } + checkName(name) { + if (name == null) { + console.log('ERROR: Property "name" is required but not supplied.') + return false + } + if (w2ui[name] != null) { + console.log(`ERROR: Object named "${name}" is already registered as w2ui.${name}.`) + return false + } + if (!this.isAlphaNumeric(name)) { + console.log('ERROR: Property "name" has to be alpha-numeric (a-z, 0-9, dash and underscore).') + return false + } + return true + } + checkUniqueId(id, items, desc, obj) { + if (!Array.isArray(items)) items = [items] + let isUnique = true + items.forEach(item => { + if (item.id === id) { + console.log(`ERROR: The item id="${id}" is not unique within the ${desc} "${obj}".`, items) + isUnique = false + } + }) + return isUnique + } + /** + * Takes an object and encodes it into params string to be passed as a url + * { a: 1, b: 'str'} => "a=1&b=str" + * { a: 1, b: { c: 2 }} => "a=1&b[c]=2" + * { a: 1, b: {c: { k: 'dfdf' } } } => "a=1&b[c][k]=dfdf" + */ + encodeParams(obj, prefix = '') { + let str = '' + Object.keys(obj).forEach(key => { + if (str != '') str += '&' + if (typeof obj[key] == 'object') { + str += this.encodeParams(obj[key], prefix + key + (prefix ? ']' : '') + '[') + } else { + str += `${prefix}${key}${prefix ? ']' : ''}=${obj[key]}` + } + }) + return str + } + parseRoute(route) { + let keys = [] + let path = route + .replace(/\/\(/g, '(?:/') + .replace(/\+/g, '__plus__') + .replace(/(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?/g, (_, slash, format, key, capture, optional) => { + keys.push({ name: key, optional: !! optional }) + slash = slash || '' + return '' + (optional ? '' : slash) + '(?:' + (optional ? slash : '') + (format || '') + (capture || (format && '([^/.]+?)' || '([^/]+?)')) + ')' + (optional || '') + }) + .replace(/([\/.])/g, '\\$1') + .replace(/__plus__/g, '(.+)') + .replace(/\*/g, '(.*)') + return { + path : new RegExp('^' + path + '$', 'i'), + keys : keys + } + } + getCursorPosition(input) { + if (input == null) return null + let caretOffset = 0 + let doc = input.ownerDocument || input.document + let win = doc.defaultView || doc.parentWindow + let sel + if (['INPUT', 'TEXTAREA'].includes(input.tagName)) { + caretOffset = input.selectionStart + } else { + if (win.getSelection) { + sel = win.getSelection() + if (sel.rangeCount > 0) { + let range = sel.getRangeAt(0) + let preCaretRange = range.cloneRange() + preCaretRange.selectNodeContents(input) + preCaretRange.setEnd(range.endContainer, range.endOffset) + caretOffset = preCaretRange.toString().length + } + } else if ( (sel = doc.selection) && sel.type !== 'Control') { + let textRange = sel.createRange() + let preCaretTextRange = doc.body.createTextRange() + preCaretTextRange.moveToElementText(input) + preCaretTextRange.setEndPoint('EndToEnd', textRange) + caretOffset = preCaretTextRange.text.length + } + } + return caretOffset + } + setCursorPosition(input, pos, posEnd) { + if (input == null) return + let range = document.createRange() + let el, sel = window.getSelection() + if (['INPUT', 'TEXTAREA'].includes(input.tagName)) { + input.setSelectionRange(pos, posEnd ?? pos) + } else { + for (let i = 0; i < input.childNodes.length; i++) { + let tmp = query(input.childNodes[i]).text() + if (input.childNodes[i].tagName) { + tmp = query(input.childNodes[i]).html() + tmp = tmp.replace(/</g, '<') + .replace(/>/g, '>') + .replace(/&/g, '&') + .replace(/"/g, '"') + .replace(/ /g, ' ') + } + if (pos <= tmp.length) { + el = input.childNodes[i] + if (el.childNodes && el.childNodes.length > 0) el = el.childNodes[0] + if (el.childNodes && el.childNodes.length > 0) el = el.childNodes[0] + break + } else { + pos -= tmp.length + } + } + if (el == null) return + if (pos > el.length) pos = el.length + range.setStart(el, pos) + if (posEnd) { + range.setEnd(el, posEnd) + } else { + range.collapse(true) + } + sel.removeAllRanges() + sel.addRange(range) + } + } + parseColor(str) { + if (typeof str !== 'string') return null; else str = str.trim().toUpperCase() + if (str[0] === '#') str = str.substr(1) + let color = {} + if (str.length === 3) { + color = { + r: parseInt(str[0] + str[0], 16), + g: parseInt(str[1] + str[1], 16), + b: parseInt(str[2] + str[2], 16), + a: 1 + } + } else if (str.length === 6) { + color = { + r: parseInt(str.substr(0, 2), 16), + g: parseInt(str.substr(2, 2), 16), + b: parseInt(str.substr(4, 2), 16), + a: 1 + } + } else if (str.length === 8) { + color = { + r: parseInt(str.substr(0, 2), 16), + g: parseInt(str.substr(2, 2), 16), + b: parseInt(str.substr(4, 2), 16), + a: Math.round(parseInt(str.substr(6, 2), 16) / 255 * 100) / 100 // alpha channel 0-1 + } + } else if (str.length > 4 && str.substr(0, 4) === 'RGB(') { + let tmp = str.replace('RGB', '').replace(/\(/g, '').replace(/\)/g, '').split(',') + color = { + r: parseInt(tmp[0], 10), + g: parseInt(tmp[1], 10), + b: parseInt(tmp[2], 10), + a: 1 + } + } else if (str.length > 5 && str.substr(0, 5) === 'RGBA(') { + let tmp = str.replace('RGBA', '').replace(/\(/g, '').replace(/\)/g, '').split(',') + color = { + r: parseInt(tmp[0], 10), + g: parseInt(tmp[1], 10), + b: parseInt(tmp[2], 10), + a: parseFloat(tmp[3]) + } + } else { + // word color + return null + } + return color + } + // h=0..360, s=0..100, v=0..100 + hsv2rgb(h, s, v, a) { + let r, g, b, i, f, p, q, t + if (arguments.length === 1) { + s = h.s; v = h.v; a = h.a; h = h.h + } + h = h / 360 + s = s / 100 + v = v / 100 + i = Math.floor(h * 6) + f = h * 6 - i + p = v * (1 - s) + q = v * (1 - f * s) + t = v * (1 - (1 - f) * s) + switch (i % 6) { + case 0: r = v, g = t, b = p; break + case 1: r = q, g = v, b = p; break + case 2: r = p, g = v, b = t; break + case 3: r = p, g = q, b = v; break + case 4: r = t, g = p, b = v; break + case 5: r = v, g = p, b = q; break + } + return { + r: Math.round(r * 255), + g: Math.round(g * 255), + b: Math.round(b * 255), + a: (a != null ? a : 1) + } + } + // r=0..255, g=0..255, b=0..255 + rgb2hsv(r, g, b, a) { + if (arguments.length === 1) { + g = r.g; b = r.b; a = r.a; r = r.r + } + let max = Math.max(r, g, b), min = Math.min(r, g, b), + d = max - min, + h, + s = (max === 0 ? 0 : d / max), + v = max / 255 + switch (max) { + case min: h = 0; break + case r: h = (g - b) + d * (g < b ? 6: 0); h /= 6 * d; break + case g: h = (b - r) + d * 2; h /= 6 * d; break + case b: h = (r - g) + d * 4; h /= 6 * d; break + } + return { + h: Math.round(h * 360), + s: Math.round(s * 100), + v: Math.round(v * 100), + a: (a != null ? a : 1) + } + } + tooltip(html, options) { + let actions + let showOn = 'mouseenter' + let hideOn = 'mouseleave' + if (typeof html == 'object') { + options = html + } + options = options || {} + if (typeof html == 'string') { + options.html = html + } + if (options.showOn) { + showOn = options.showOn + delete options.showOn + } + if (options.hideOn) { + hideOn = options.hideOn + delete options.hideOn + } + if (!options.name) options.name = 'no-name' + // base64 is needed to avoid '"<> and other special chars conflicts + actions = ` on${showOn}="w2tooltip.show(this, ` + + `JSON.parse(w2utils.base64decode('${this.base64encode(JSON.stringify(options))}')))" ` + + `on${hideOn}="w2tooltip.hide('${options.name}')"` + return actions + } + // determins if it is plain Object, not DOM element, nor a function, event, etc. + isPlainObject(value) { + if (value == null) { // null or undefined + return false + } + if (Object.prototype.toString.call(value) !== '[object Object]') { + return false + } + if (value.constructor === undefined) { + return true + } + let proto = Object.getPrototypeOf(value) + return proto === null || proto === Object.prototype + } + /** + * Deep copy of an object or an array. Function, events and HTML elements will not be cloned, + * you can choose to include them or not, by default they are included. + * You can also exclude certain elements from final object if used with options: { exclude } + */ + clone(obj, options) { + let ret + options = Object.assign({ functions: true, elements: true, events: true, exclude: [] }, options ?? {}) + if (Array.isArray(obj)) { + ret = Array.from(obj) + ret.forEach((value, ind) => { + ret[ind] = this.clone(value, options) + }) + } else if (this.isPlainObject(obj)) { + ret = {} + Object.assign(ret, obj) + if (options.exclude) { + options.exclude.forEach(key => { delete ret[key] }) // delete excluded keys + } + Object.keys(ret).forEach(key => { + ret[key] = this.clone(ret[key], options) + if (ret[key] === undefined) delete ret[key] // do not include undefined elements + }) + } else { + if ((obj instanceof Function && !options.functions) + || (obj instanceof Node && !options.elements) + || (obj instanceof Event && !options.events) + ) { + // do not include these objects, otherwise include them uncloned + } else { + // primitive variable or function, event, dom element, etc, - all these are not cloned + ret = obj + } + } + return ret + } + /** + * Deep extend an object, if an array, it overwrrites it, cloning objects in the process + * target, source1, source2, ... + */ + extend(target, source) { + if (Array.isArray(target)) { + if (Array.isArray(source)) { + target.splice(0, target.length) // empty array but keep the reference + source.forEach(s => { target.push(this.clone(s)) }) + } else { + throw new Error('Arrays can be extended with arrays only') + } + } else if (target instanceof Node || target instanceof Event) { + throw new Error('HTML elmenents and events cannot be extended') + } else if (target && typeof target == 'object' && source != null) { + if (typeof source != 'object') { + throw new Error('Object can be extended with other objects only.') + } + Object.keys(source).forEach(key => { + if (target[key] != null && typeof target[key] == 'object' + && source[key] != null && typeof source[key] == 'object') { + let src = this.clone(source[key]) + // do not extend HTML elements and events, but overwrite them + if (target[key] instanceof Node || target[key] instanceof Event) { + target[key] = src + } else { + // if an array needs to be extended with an object, then convert it to empty object + if (Array.isArray(target[key]) && this.isPlainObject(src)) { + target[key] = {} + } + this.extend(target[key], src) + } + } else { + target[key] = this.clone(source[key]) + } + }) + } else if (source != null) { + throw new Error('Object is not extendable, only {} or [] can be extended.') + } + // other arguments + if (arguments.length > 2) { + for (let i = 2; i < arguments.length; i++) { + this.extend(target, arguments[i]) + } + } + return target + } + /* + * @author Lauri Rooden (https://github.com/litejs/natural-compare-lite) + * @license MIT License + */ + naturalCompare(a, b) { + let i, codeA + , codeB = 1 + , posA = 0 + , posB = 0 + , alphabet = String.alphabet + function getCode(str, pos, code) { + if (code) { + for (i = pos; code = getCode(str, i), code < 76 && code > 65;) ++i + return +str.slice(pos - 1, i) + } + code = alphabet && alphabet.indexOf(str.charAt(pos)) + return code > -1 ? code + 76 : ((code = str.charCodeAt(pos) || 0), code < 45 || code > 127) ? code + : code < 46 ? 65 // - + : code < 48 ? code - 1 + : code < 58 ? code + 18 // 0-9 + : code < 65 ? code - 11 + : code < 91 ? code + 11 // A-Z + : code < 97 ? code - 37 + : code < 123 ? code + 5 // a-z + : code - 63 + } + + if ((a+='') != (b+='')) for (;codeB;) { + codeA = getCode(a, posA++) + codeB = getCode(b, posB++) + if (codeA < 76 && codeB < 76 && codeA > 66 && codeB > 66) { + codeA = getCode(a, posA, posA) + codeB = getCode(b, posB, posA = i) + posB = i + } + if (codeA != codeB) return (codeA < codeB) ? -1 : 1 + } + return 0 + } + normMenu(menu, el) { + if (Array.isArray(menu)) { + menu.forEach((it, m) => { + if (typeof it === 'string' || typeof it === 'number') { + menu[m] = { id: it, text: String(it) } + } else if (it != null) { + if (it.caption != null && it.text == null) it.text = it.caption + if (it.text != null && it.id == null) it.id = it.text + if (it.text == null && it.id != null) it.text = it.id + } else { + menu[m] = { id: null, text: 'null' } + } + }) + return menu + } else if (typeof menu === 'function') { + let newMenu = menu.call(this, menu, el) + return w2utils.normMenu.call(this, newMenu) + } else if (typeof menu === 'object') { + return Object.keys(menu).map(key => { return { id: key, text: menu[key] } }) + } + } + /** + * Takes Url object and fetchOptions and changes it in place applying selected user dataType. Since + * dataType is in w2utils. This method is used in grid, form and tooltip to prepare fetch parameters + */ + prepareParams(url, fetchOptions, defDataType) { + let dataType = defDataType ?? w2utils.settings.dataType + let postParams = fetchOptions.body + switch (dataType) { + case 'HTTPJSON': + postParams = { request: postParams } + if (['PUT', 'DELETE'].includes(fetchOptions.method)) { + fetchOptions.method = 'POST' + } + body2params() + break + case 'HTTP': + if (['PUT', 'DELETE'].includes(fetchOptions.method)) { + fetchOptions.method = 'POST' + } + body2params() + break + case 'RESTFULL': + if (['PUT', 'DELETE'].includes(fetchOptions.method)) { + fetchOptions.headers['Content-Type'] = 'application/json' + } else { + body2params() + } + break + case 'JSON': + if (fetchOptions.method == 'GET') { + postParams = { request: postParams } + body2params() + } else { + fetchOptions.headers['Content-Type'] = 'application/json' + fetchOptions.method = 'POST' + } + break + } + fetchOptions.body = typeof fetchOptions.body == 'string' ? fetchOptions.body : JSON.stringify(fetchOptions.body) + return fetchOptions + function body2params() { + Object.keys(postParams).forEach(key => { + let param = postParams[key] + if (typeof param == 'object') param = JSON.stringify(param) + url.searchParams.append(key, param) + }) + delete fetchOptions.body + } + } + bindEvents(selector, subject) { + // format is + //
    ='["","param1","param2",...]'> -- should be valid JSON (no undefined) + //
    ="|param1|param2"> + // -- can have "event", "this", "stop", "stopPrevent", "alert" - as predefined objects + if (selector.length == 0) return + // for backward compatibility + if (selector?.[0] instanceof Node) { + selector = Array.isArray(selector) ? selector : selector.get() + } + query(selector).each((el) => { + let actions = query(el).data() + Object.keys(actions).forEach(name => { + let events = ['click', 'dblclick', 'mouseenter', 'mouseleave', 'mouseover', 'mouseout', 'mousedown', 'mousemove', 'mouseup', + 'contextmenu', 'focus', 'focusin', 'focusout', 'blur', 'input', 'change', 'keydown', 'keyup', 'keypress'] + if (events.indexOf(String(name).toLowerCase()) == -1) { + return + } + let params = actions[name] + if (typeof params == 'string') { + params = params.split('|').map(key => { + if (key === 'true') key = true + if (key === 'false') key = false + if (key === 'undefined') key = undefined + if (key === 'null') key = null + if (parseFloat(key) == key) key = parseFloat(key) + let quotes = ['\'', '"', '`'] + if (typeof key == 'string' && quotes.includes(key[0]) && quotes.includes(key[key.length-1])) { + key = key.substring(1, key.length-1) + } + return key + }) + } + let method = params[0] + params = params.slice(1) // should be new array + query(el) + .off(name + '.w2utils-bind') + .on(name + '.w2utils-bind', function(event) { + switch (method) { + case 'alert': + alert(params[0]) // for testing purposes + break + case 'stop': + event.stopPropagation() + break + case 'prevent': + event.preventDefault() + break + case 'stopPrevent': + event.stopPropagation() + event.preventDefault() + return false + break + default: + if (subject[method] == null) { + throw new Error(`Cannot dispatch event as the method "${method}" does not exist.`) + } + subject[method].apply(subject, params.map((key, ind) => { + switch (String(key).toLowerCase()) { + case 'event': + return event + case 'this': + return this + default: + return key + } + })) + } + }) + }) + }) + } + debounce(func, wait = 250) { + let timeout + return (...args) => { + clearTimeout(timeout) + timeout = setTimeout(() => { func(...args) }, wait) + } + } +} +var w2utils = new Utils() // eslint-disable-line -- needs to be functional/module scope variable +/** + * Part of w2ui 2.0 library + * - Dependencies: mQuery, w2utils, w2base + * + * == 2.0 changes + * - CSP - fixed inline events + * - removed jQuery dependency + * - popup.open - returns promise like object + * - popup.confirm - refactored + * - popup.message - refactored + * - removed popup.options.mutliple + * - refactores w2alert, w2confirm, w2prompt + * - add w2popup.open().on('') + * - removed w2popup.restoreTemplate + * - deprecated onMsgOpen and onMsgClose + * - deprecated options.bgColor + * - rename focus -> setFocus + * - added center() // will auto center on window resize + * - close(immediate), also refactored if popup is closed when opening + */ + +class Dialog extends w2base { + constructor() { + super() + this.defaults = { + title: '', + text: '', // just a text (will be centered) + body: '', + buttons: '', + width: 450, + height: 250, + focus: null, // brings focus to the element, can be a number or selector + actions: null, // actions object + style: '', // style of the message div + speed: 0.3, + modal: false, + maximized: false, // this is a flag to show the state - to open the popup maximized use openMaximized instead + keyboard: true, // will close popup on esc if not modal + showClose: true, + showMax: false, + transition: null, + openMaximized: false, + moved: false + } + this.name = 'popup' + this.status = 'closed' // string that describes current status + this.onOpen = null + this.onClose = null + this.onMax = null + this.onMin = null + this.onToggle = null + this.onKeydown = null + this.onAction = null + this.onMove = null + this.tmp = {} + // event handler for resize + this.handleResize = (event) => { + // if it was moved by the user, do not auto resize + if (!this.options.moved) { + this.center(undefined, undefined, true) + } + } + } + /** + * Sample calls + * - w2popup.open('ddd').ok(() => { w2popup.close() }) + * - w2popup.open('ddd', { height: 120 }).ok(() => { w2popup.close() }) + * - w2popup.open({ body: 'text', title: 'caption', actions: ["Close"] }).close(() => { w2popup.close() }) + * - w2popup.open({ body: 'text', title: 'caption', actions: { Close() { w2popup.close() }} }) + */ + open(options) { + let self = this + if (this.status == 'closing' || query('#w2ui-popup').hasClass('animating')) { + // if called when previous is closing + this.close(true) + } + // get old options and merge them + let old_options = this.options + if (['string', 'number'].includes(typeof options)) { + options = w2utils.extend({ + title: 'Notification', + body: `
    ${options}
    `, + actions: { Ok() { self.close() }}, + cancelAction: 'ok' + }, arguments[1] ?? {}) + } + if (options.text != null) options.body = `
    ${options.text}
    ` + options = Object.assign({}, this.defaults, old_options, { title: '', body : '' }, options, { maximized: false }) + this.options = options + // if new - reset event handlers + if (query('#w2ui-popup').length === 0) { + this.off('*') + Object.keys(this).forEach(key => { + if (key.startsWith('on') && key != 'on') this[key] = null + }) + } + // reassign events + Object.keys(options).forEach(key => { + if (key.startsWith('on') && key != 'on' && options[key]) { + this[key] = options[key] + } + }) + options.width = parseInt(options.width) + options.height = parseInt(options.height) + let edata, msg, tmp + let { top, left } = this.center() + let prom = { + self: this, + action(callBack) { + self.on('action.prom', callBack) + return prom + }, + close(callBack) { + self.on('close.prom', callBack) + return prom + }, + then(callBack) { + self.on('open:after.prom', callBack) + return prom + } + } + // convert action arrays into buttons + if (options.actions != null && !options.buttons) { + options.buttons = '' + Object.keys(options.actions).forEach((action) => { + let handler = options.actions[action] + let btnAction = action + if (typeof handler == 'function') { + options.buttons += `` + } + if (typeof handler == 'object') { + options.buttons += `` + btnAction = Array.isArray(options.actions) ? handler.text : action + } + if (typeof handler == 'string') { + options.buttons += `` + btnAction = handler + } + if (typeof btnAction == 'string') { + btnAction = btnAction[0].toLowerCase() + btnAction.substr(1).replace(/\s+/g, '') + } + prom[btnAction] = function (callBack) { + self.on('action.buttons', (event) => { + let target = event.detail.action[0].toLowerCase() + event.detail.action.substr(1).replace(/\s+/g, '') + if (target == btnAction) callBack(event) + }) + return prom + } + }) + } + // check if message is already displayed + if (query('#w2ui-popup').length === 0) { + // trigger event + edata = this.trigger('open', { target: 'popup', present: false }) + if (edata.isCancelled === true) return + this.status = 'opening' + // output message + w2utils.lock(document.body, { + opacity: 0.3, + onClick: options.modal ? null : () => { this.close() } + }) + let btn = '' + if (options.showClose) { + btn += `
    + +
    ` + } + if (options.showMax) { + btn += `
    + +
    ` + } + // first insert just body + let styles = ` + left: ${left}px; + top: ${top}px; + width: ${parseInt(options.width)}px; + height: ${parseInt(options.height)}px; + transition: ${options.speed}s + ` + msg = `
    ` + query('body').append(msg) + query('#w2ui-popup')[0]._w2popup = { + self: this, + created: new Promise((resolve) => { this._promCreated = resolve }), + opened: new Promise((resolve) => { this._promOpened = resolve }), + closing: new Promise((resolve) => { this._promClosing = resolve }), + closed: new Promise((resolve) => { this._promClosed = resolve }), + } + // then content + styles = `${!options.title ? 'top: 0px !important;' : ''} ${!options.buttons ? 'bottom: 0px !important;' : ''}` + msg = ` + +
    ${btn}
    +
    +
    +
    +
    +
    +
    + + ` + query('#w2ui-popup').html(msg) + if (options.title) query('#w2ui-popup .w2ui-popup-title').append(w2utils.lang(options.title)) + if (options.buttons) query('#w2ui-popup .w2ui-popup-buttons').append(options.buttons) + if (options.body) query('#w2ui-popup .w2ui-popup-body').append(options.body) + // allow element to render + setTimeout(() => { + query('#w2ui-popup') + .css('transition', options.speed + 's') + .removeClass('w2ui-anim-open') + w2utils.bindEvents('#w2ui-popup .w2ui-eaction', this) + query('#w2ui-popup').find('.w2ui-popup-body').show() + this._promCreated() + }, 1) + // clean transform + clearTimeout(this._timer) + this._timer = setTimeout(() => { + this.status = 'open' + self.setFocus(options.focus) + // event after + edata.finish() + this._promOpened() + query('#w2ui-popup').removeClass('animating') + }, options.speed * 1000) + } else { + // trigger event + edata = this.trigger('open', { target: 'popup', present: true }) + if (edata.isCancelled === true) return + // check if size changed + this.status = 'opening' + if (old_options != null) { + if (!old_options.maximized && (old_options.width != options.width || old_options.height != options.height)) { + this.resize(options.width, options.height) + } + options.prevSize = options.width + 'px:' + options.height + 'px' + options.maximized = old_options.maximized + } + // show new items + let cloned = query('#w2ui-popup .w2ui-box').get(0).cloneNode(true) + query(cloned).removeClass('w2ui-box').addClass('w2ui-box-temp').find('.w2ui-popup-body').empty().append(options.body) + query('#w2ui-popup .w2ui-box').after(cloned) + if (options.buttons) { + query('#w2ui-popup .w2ui-popup-buttons').show().html('').append(options.buttons) + query('#w2ui-popup .w2ui-popup-body').removeClass('w2ui-popup-no-buttons') + query('#w2ui-popup .w2ui-box, #w2ui-popup .w2ui-box-temp').css('bottom', '') + } else { + query('#w2ui-popup .w2ui-popup-buttons').hide().html('') + query('#w2ui-popup .w2ui-popup-body').addClass('w2ui-popup-no-buttons') + query('#w2ui-popup .w2ui-box, #w2ui-popup .w2ui-box-temp').css('bottom', '0px') + } + if (options.title) { + query('#w2ui-popup .w2ui-popup-title') + .show() + .html((options.showClose + ? `
    + +
    ` + : '') + + (options.showMax + ? `
    + +
    ` + : '')) + .append(options.title) + query('#w2ui-popup .w2ui-popup-body').removeClass('w2ui-popup-no-title') + query('#w2ui-popup .w2ui-box, #w2ui-popup .w2ui-box-temp').css('top', '') + } else { + query('#w2ui-popup .w2ui-popup-title').hide().html('') + query('#w2ui-popup .w2ui-popup-body').addClass('w2ui-popup-no-title') + query('#w2ui-popup .w2ui-box, #w2ui-popup .w2ui-box-temp').css('top', '0px') + } + // transition + let div_old = query('#w2ui-popup .w2ui-box')[0] + let div_new = query('#w2ui-popup .w2ui-box-temp')[0] + query('#w2ui-popup').addClass('animating') + w2utils.transition(div_old, div_new, options.transition, () => { + // clean up + query(div_old).remove() + query(div_new).removeClass('w2ui-box-temp').addClass('w2ui-box') + let $body = query(div_new).find('.w2ui-popup-body') + if ($body.length == 1) { + $body[0].style.cssText = options.style + $body.show() + } + // focus on first button + self.setFocus(options.focus) + query('#w2ui-popup').removeClass('animating') + }) + // call event onOpen + this.status = 'open' + edata.finish() + w2utils.bindEvents('#w2ui-popup .w2ui-eaction', this) + query('#w2ui-popup').find('.w2ui-popup-body').show() + } + if (options.openMaximized) { + this.max() + } + // save new options + options._last_focus = document.activeElement + // keyboard events + if (options.keyboard) { + query(document.body).on('keydown', (event) => { + this.keydown(event) + }) + } + query(window).on('resize', this.handleResize) + // initialize move + tmp = { + resizing : false, + mvMove : mvMove, + mvStop : mvStop + } + query('#w2ui-popup .w2ui-popup-title').on('mousedown', function(event) { + if (!self.options.maximized) mvStart(event) + }) + return prom + // handlers + function mvStart(evt) { + if (!evt) evt = window.event + self.status = 'moving' + let rect = query('#w2ui-popup').get(0).getBoundingClientRect() + Object.assign(tmp, { + resizing: true, + isLocked: query('#w2ui-popup > .w2ui-lock').length == 1 ? true : false, + x : evt.screenX, + y : evt.screenY, + pos_x : rect.x, + pos_y : rect.y, + }) + if (!tmp.isLocked) self.lock({ opacity: 0 }) + query(document.body) + .on('mousemove.w2ui-popup', tmp.mvMove) + .on('mouseup.w2ui-popup', tmp.mvStop) + if (evt.stopPropagation) evt.stopPropagation(); else evt.cancelBubble = true + if (evt.preventDefault) evt.preventDefault(); else return false + } + function mvMove(evt) { + if (tmp.resizing != true) return + if (!evt) evt = window.event + tmp.div_x = evt.screenX - tmp.x + tmp.div_y = evt.screenY - tmp.y + // trigger event + let edata = self.trigger('move', { target: 'popup', div_x: tmp.div_x, div_y: tmp.div_y, originalEvent: evt }) + if (edata.isCancelled === true) return + // default behavior + query('#w2ui-popup').css({ + 'transition': 'none', + 'transform' : 'translate3d('+ tmp.div_x +'px, '+ tmp.div_y +'px, 0px)' + }) + self.options.moved = true + // event after + edata.finish() + } + function mvStop(evt) { + if (tmp.resizing != true) return + if (!evt) evt = window.event + self.status = 'open' + tmp.div_x = (evt.screenX - tmp.x) + tmp.div_y = (evt.screenY - tmp.y) + query('#w2ui-popup') + .css({ + 'left': (tmp.pos_x + tmp.div_x) + 'px', + 'top' : (tmp.pos_y + tmp.div_y) + 'px' + }) + .css({ + 'transition': 'none', + 'transform' : 'translate3d(0px, 0px, 0px)' + }) + tmp.resizing = false + query(document.body).off('.w2ui-popup') + if (!tmp.isLocked) self.unlock() + } + } + load(options) { + return new Promise((resolve, reject) => { + if (typeof options == 'string') { + options = { url: options } + } + if (options.url == null) { + console.log('ERROR: The url is not defined.') + reject('The url is not defined') + return + } + this.status = 'loading' + let [url, selector] = String(options.url).split('#') + if (url) { + fetch(url).then(res => res.text()).then(html => { + resolve(this.template(html, selector, options)) + }) + } + }) + } + template(data, id, options = {}) { + let html + try { + html = query(data) + } catch (e) { + html = query.html(data) + } + if (id) html = html.filter('#' + id) + Object.assign(options, { + width: parseInt(query(html).css('width')), + height: parseInt(query(html).css('height')), + title: query(html).find('[rel=title]').html(), + body: query(html).find('[rel=body]').html(), + buttons: query(html).find('[rel=buttons]').html(), + style: query(html).find('[rel=body]').get(0).style.cssText, + }) + return this.open(options) + } + action(action, event) { + let click = this.options.actions[action] + if (click instanceof Object && click.onClick) click = click.onClick + // event before + let edata = this.trigger('action', { action, target: 'popup', self: this, + originalEvent: event, value: this.input ? this.input.value : null }) + if (edata.isCancelled === true) return + // default actions + if (typeof click === 'function') click.call(this, event) + // event after + edata.finish() + } + keydown(event) { + if (this.options && !this.options.keyboard) return + // trigger event + let edata = this.trigger('keydown', { target: 'popup', originalEvent: event }) + if (edata.isCancelled === true) return + // default behavior + switch (event.keyCode) { + case 27: + event.preventDefault() + if (query('#w2ui-popup .w2ui-message').length == 0) { + if (this.options.cancelAction) { + this.action(this.options.cancelAction) + } else { + this.close() + } + } + break + } + // event after + edata.finish() + } + close(immediate) { + // trigger event + let edata = this.trigger('close', { target: 'popup' }) + if (edata.isCancelled === true) return + let cleanUp = () => { + // return template + query('#w2ui-popup').remove() + // restore active + if (this.options._last_focus && this.options._last_focus.length > 0) this.options._last_focus.focus() + this.status = 'closed' + this.options = {} + // event after + edata.finish() + this._promClosed() + } + if (query('#w2ui-popup').length === 0 || this.status == 'closed') { // already closed + return + } + if (this.status == 'opening') { // if it is opening + immediate = true + } + if (this.status == 'closing' && immediate === true) { + cleanUp() + clearTimeout(this.tmp.closingTimer) + w2utils.unlock(document.body, 0) + return + } + // default behavior + this.status = 'closing' + query('#w2ui-popup') + .css('transition', this.options.speed + 's') + .addClass('w2ui-anim-close animating') + w2utils.unlock(document.body, 300) + this._promClosing() + if (immediate) { + cleanUp() + } else { + this.tmp.closingTimer = setTimeout(cleanUp, this.options.speed * 1000) + } + // remove keyboard events + if (this.options.keyboard) { + query(document.body).off('keydown', this.keydown) + } + query(window).off('resize', this.handleResize) + } + toggle() { + let edata = this.trigger('toggle', { target: 'popup' }) + if (edata.isCancelled === true) return + // default action + if (this.options.maximized === true) this.min(); else this.max() + // event after + setTimeout(() => { + edata.finish() + }, (this.options.speed * 1000) + 50) + } + max() { + if (this.options.maximized === true) return + // trigger event + let edata = this.trigger('max', { target: 'popup' }) + if (edata.isCancelled === true) return + // default behavior + this.status = 'resizing' + let rect = query('#w2ui-popup').get(0).getBoundingClientRect() + this.options.prevSize = rect.width + ':' + rect.height + // do resize + this.resize(10000, 10000, () => { + this.status = 'open' + this.options.maximized = true + edata.finish() + }) + } + min() { + if (this.options.maximized !== true) return + let size = this.options.prevSize.split(':') + // trigger event + let edata = this.trigger('min', { target: 'popup' }) + if (edata.isCancelled === true) return + // default behavior + this.status = 'resizing' + // do resize + this.options.maximized = false + this.resize(parseInt(size[0]), parseInt(size[1]), () => { + this.status = 'open' + this.options.prevSize = null + edata.finish() + }) + } + clear() { + query('#w2ui-popup .w2ui-popup-title').html('') + query('#w2ui-popup .w2ui-popup-body').html('') + query('#w2ui-popup .w2ui-popup-buttons').html('') + } + reset() { + this.open(this.defaults) + } + message(options) { + return w2utils.message({ + owner: this, + box : query('#w2ui-popup').get(0), + after: '.w2ui-popup-title' + }, options) + } + confirm(options) { + return w2utils.confirm({ + owner: this, + box : query('#w2ui-popup'), + after: '.w2ui-popup-title' + }, options) + } + setFocus(focus) { + let box = query('#w2ui-popup') + let sel = 'input, button, select, textarea, [contentEditable], .w2ui-input' + if (focus != null) { + let el = isNaN(focus) + ? box.find(sel).filter(focus).get(0) + : box.find(sel).get(focus) + el?.focus() + } else { + let el = box.find('[name=hidden-first]').get(0) + if (el) el.focus() + } + // keep focus/blur inside popup + query(box).find(sel + ',[name=hidden-first],[name=hidden-last]') + .off('.keep-focus') + .on('blur.keep-focus', function (event) { + setTimeout(() => { + let focus = document.activeElement + let inside = query(box).find(sel).filter(focus).length > 0 + let name = query(focus).attr('name') + if (!inside && focus && focus !== document.body) { + query(box).find(sel).get(0)?.focus() + } + if (name == 'hidden-last') { + query(box).find(sel).get(0)?.focus() + } + if (name == 'hidden-first') { + query(box).find(sel).get(-1)?.focus() + } + }, 1) + }) + } + lock(msg, showSpinner) { + let args = Array.from(arguments) + args.unshift(query('#w2ui-popup')) + w2utils.lock(...args) + } + unlock(speed) { + w2utils.unlock(query('#w2ui-popup'), speed) + } + center(width, height, force) { + let maxW, maxH + if (window.innerHeight == undefined) { + maxW = parseInt(document.documentElement.offsetWidth) + maxH = parseInt(document.documentElement.offsetHeight) + } else { + maxW = parseInt(window.innerWidth) + maxH = parseInt(window.innerHeight) + } + width = parseInt(width ?? this.options.width) + height = parseInt(height ?? this.options.height) + if (this.options.maximized === true) { + width = maxW + height = maxH + } + if (maxW - 10 < width) width = maxW - 10 + if (maxH - 10 < height) height = maxH - 10 + let top = (maxH - height) / 2 + let left = (maxW - width) / 2 + if (force) { + query('#w2ui-popup').css({ + 'transition': 'none', + 'top' : top + 'px', + 'left' : left + 'px', + 'width' : width + 'px', + 'height': height + 'px' + }) + this.resizeMessages() // then messages resize nicely + } + return { top, left, width, height } + } + resize(newWidth, newHeight, callBack) { + let self = this + if (this.options.speed == null) this.options.speed = 0 + // calculate new position + let { top, left, width, height } = this.center(newWidth, newHeight) + let speed = this.options.speed + query('#w2ui-popup').css({ + 'transition': `${speed}s width, ${speed}s height, ${speed}s left, ${speed}s top`, + 'top' : top + 'px', + 'left' : left + 'px', + 'width' : width + 'px', + 'height': height + 'px' + }) + let tmp_int = setInterval(() => { self.resizeMessages() }, 10) // then messages resize nicely + setTimeout(() => { + clearInterval(tmp_int) + self.resizeMessages() + if (typeof callBack == 'function') callBack() + }, (this.options.speed * 1000) + 50) // give extra 50 ms + } + // internal function + resizeMessages() { + // see if there are messages and resize them + query('#w2ui-popup .w2ui-message').each(msg => { + let mopt = msg._msg_options + let popup = query('#w2ui-popup') + if (parseInt(mopt.width) < 10) mopt.width = 10 + if (parseInt(mopt.height) < 10) mopt.height = 10 + let rect = popup[0].getBoundingClientRect() + let titleHeight = parseInt(popup.find('.w2ui-popup-title')[0].clientHeight) + let pWidth = parseInt(rect.width) + let pHeight = parseInt(rect.height) + // re-calc width + mopt.width = mopt.originalWidth + if (mopt.width > pWidth - 10) { + mopt.width = pWidth - 10 + } + // re-calc height + mopt.height = mopt.originalHeight + if (mopt.height > pHeight - titleHeight - 5) { + mopt.height = pHeight - titleHeight - 5 + } + if (mopt.originalHeight < 0) mopt.height = pHeight + mopt.originalHeight - titleHeight + if (mopt.originalWidth < 0) mopt.width = pWidth + mopt.originalWidth * 2 // x 2 because there is left and right margin + query(msg).css({ + left : ((pWidth - mopt.width) / 2) + 'px', + width : mopt.width + 'px', + height : mopt.height + 'px' + }) + }) + } +} +function w2alert(msg, title, callBack) { + let prom + let options = { + title: w2utils.lang(title ?? 'Notification'), + body: `
    ${msg}
    `, + showClose: false, + actions: ['Ok'], + cancelAction: 'ok' + } + if (query('#w2ui-popup').length > 0 && w2popup.status != 'closing') { + prom = w2popup.message(options) + } else { + prom = w2popup.open(options) + } + prom.ok((event) => { + if (typeof event.detail.self?.close == 'function') { + event.detail.self.close() + } + if (typeof callBack == 'function') callBack() + }) + return prom +} +function w2confirm(msg, title, callBack) { + let prom + let options = msg + if (['string', 'number'].includes(typeof options)) { + options = { msg: options } + } + if (options.msg) { + options.body = `
    ${options.msg}
    `, + delete options.msg + } + w2utils.extend(options, { + title: w2utils.lang(title ?? 'Confirmation'), + showClose: false, + modal: true, + cancelAction: 'no' + }) + w2utils.normButtons(options, { yes: 'Yes', no: 'No' }) + if (query('#w2ui-popup').length > 0 && w2popup.status != 'closing') { + prom = w2popup.message(options) + } else { + prom = w2popup.open(options) + } + prom.self + .off('.confirm') + .on('action:after.confirm', (event) => { + if (typeof event.detail.self?.close == 'function') { + event.detail.self.close() + } + if (typeof callBack == 'function') callBack(event.detail.action) + }) + return prom +} +function w2prompt(label, title, callBack) { + let prom + let options = label + if (['string', 'number'].includes(typeof options)) { + options = { label: options } + } + if (options.label) { + options.focus = 0 + options.body = (options.textarea + ? `
    +
    ${options.label}
    + +
    ` + : `
    + + +
    ` + ) + } + w2utils.extend(options, { + title: w2utils.lang(title ?? 'Notification'), + showClose: false, + modal: true, + cancelAction: 'cancel' + }) + w2utils.normButtons(options, { ok: 'Ok', cancel: 'Cancel' }) + if (query('#w2ui-popup').length > 0 && w2popup.status != 'closing') { + prom = w2popup.message(options) + } else { + prom = w2popup.open(options) + } + if (prom.self.box) { + prom.self.input = query(prom.self.box).find('#w2prompt').get(0) + } else { + prom.self.input = query('#w2ui-popup .w2ui-popup-body #w2prompt').get(0) + } + if (options.value !== null) { + prom.self.input.select() + } + prom.change = function (callback) { + prom.self.on('change', callback) + return this + } + prom.self + .off('.prompt') + .on('open:after.prompt', (event) => { + let box = event.detail.box ? event.detail.box : query('#w2ui-popup .w2ui-popup-body').get(0) + w2utils.bindEvents(query(box).find('#w2prompt'), { + keydown(evt) { + if (evt.keyCode == 27) evt.stopPropagation() + }, + change(evt) { + let edata = prom.self.trigger('change', { target: 'prompt', originalEvent: evt }) + if (edata.isCancelled === true) return + if (evt.keyCode == 13 && evt.ctrlKey) { + prom.self.action('Ok', evt) + } + if (evt.keyCode == 27) { + prom.self.action('Cancel', evt) + } + edata.finish() + } + }) + query(box).find('.w2ui-eaction').trigger('keyup') + }) + .on('action:after.prompt', (event) => { + if (typeof event.detail.self?.close == 'function') { + event.detail.self.close() + } + if (typeof callBack == 'function') callBack(event.detail.action) + }) + return prom +} +let w2popup = new Dialog() +/** + * Part of w2ui 2.0 library + * - Dependencies: mQuery, w2utils, w2base + * + * 2.0 Changes + * - multiple tooltips to the same anchor + * + */ + +class Tooltip { + // no need to extend w2base, as each individual tooltip extends it + static active = {} // all defined tooltips + constructor() { + this.defaults = { + name : null, // name for the overlay, otherwise input id is used + html : '', // text or html + style : '', // additional style for the overlay + class : '', // add class for w2ui-tooltip-body + position : 'top|bottom', // can be left, right, top, bottom + align : '', // can be: both, both:XX left, right, both, top, bottom + anchor : null, // element it is attached to, if anchor is body, then it is context menu + anchorClass : '', // add class for anchor when tooltip is shown + anchorStyle : '', // add style for anchor when tooltip is shown + autoShow : false, // if autoShow true, then tooltip will show on mouseEnter and hide on mouseLeave + autoShowOn : null, // when options.autoShow = true, mouse event to show on + autoHideOn : null, // when options.autoShow = true, mouse event to hide on + arrowSize : 8, // size of the carret + margin : 0, // extra margin from the anchor + screenMargin : 2, // min margin from screen to tooltip + autoResize : true, // auto resize based on content size and available size + margin : 1, // distance from the anchor + offsetX : 0, // delta for left coordinate + offsetY : 0, // delta for top coordinate + maxWidth : null, // max width + maxHeight : null, // max height + watchScroll : null, // attach to onScroll event // TODO: + watchResize : null, // attach to onResize event // TODO: + hideOn : null, // events when to hide tooltip, ['click', 'change', 'key', 'focus', 'blur'], + onThen : null, // called when displayed + onShow : null, // callBack when shown + onHide : null, // callBack when hidden + onUpdate : null, // callback when tooltip gets updated + onMove : null // callback when tooltip is moved + } + } + static observeRemove = new MutationObserver((mutations) => { + let cnt = 0 + Object.keys(Tooltip.active).forEach(name => { + let overlay = Tooltip.active[name] + if (overlay.displayed) { + if (!overlay.anchor || !overlay.anchor.isConnected) { + overlay.hide() + } else { + cnt++ + } + } + }) + // remove observer, as there is no active tooltips + if (cnt === 0) { + Tooltip.observeRemove.disconnect() + } + }) + trigger(event, data) { + if (arguments.length == 2) { + let type = event + event = data + data.type = type + } + if (event.overlay) { + return event.overlay.trigger(event) + } else { + console.log('ERROR: cannot find overlay where to trigger events') + } + } + get(name) { + if (arguments.length == 0) { + return Object.keys(Tooltip.active) + } else if (name === true) { + return Tooltip.active + } else { + return Tooltip.active[name.replace(/[\s\.#]/g, '_')] + } + } + attach(anchor, text) { + let options, overlay + let self = this + if (arguments.length == 0) { + return + } else if (arguments.length == 1 && anchor.anchor) { + options = anchor + anchor = options.anchor + } else if (arguments.length === 2 && typeof text === 'string') { + options = { anchor, html: text } + text = options.html + } else if (arguments.length === 2 && text != null && typeof text === 'object') { + options = text + text = options.html + } + options = w2utils.extend({}, this.defaults, options || {}) + if (!text && options.text) text = options.text + if (!text && options.html) text = options.html + // anchor is func var + delete options.anchor + // define tooltip + let name = (options.name ? options.name : anchor.id) + if (anchor == document || anchor == document.body) { + anchor = document.body + name = 'context-menu' + } + if (!name) { + name = 'noname-' + Object.keys(Tooltip.active).length + console.log('NOTICE: name property is not defined for tooltip, could lead to too many instances') + } + // clean name as it is used as id and css selector + name = name.replace(/[\s\.#]/g, '_') + if (Tooltip.active[name]) { + overlay = Tooltip.active[name] + overlay.prevOptions = overlay.options + overlay.options = options // do not merge or extend, otherwiser menu items get merged too + // overlay.options = w2utils.extend({}, overlay.options, options) + overlay.anchor = anchor // as HTML elements are not copied + if (overlay.prevOptions.html != overlay.options.html || overlay.prevOptions.class != overlay.options.class + || overlay.prevOptions.style != overlay.options.style) { + overlay.needsUpdate = true + } + options = overlay.options // it was recreated + } else { + overlay = new w2base() + Object.assign(overlay, { + id: 'w2overlay-' + name, name, options, anchor, + displayed: false, + tmp: { + observeResize: new ResizeObserver(() => { + this.resize(overlay.name) + }) + }, + hide() { + self.hide(name) + } + }) + Tooltip.active[name] = overlay + } + // move events on to overlay layer + Object.keys(overlay.options).forEach(key => { + let val = overlay.options[key] + if (key.startsWith('on') && typeof val == 'function') { + overlay[key] = val + delete overlay.options[key] + } + }) + // add event for auto show/hide + if (options.autoShow === true) { + options.autoShowOn = options.autoShowOn ?? 'mouseenter' + options.autoHideOn = options.autoHideOn ?? 'mouseleave' + options.autoShow = false + } + if (options.autoShowOn) { + let scope = 'autoShow-' + overlay.name + query(anchor) + .off(`.${scope}`) + .on(`${options.autoShowOn}.${scope}`, event => { + self.show(overlay.name) + event.stopPropagation() + }) + delete options.autoShowOn + } + if (options.autoHideOn) { + let scope = 'autoHide-' + overlay.name + query(anchor) + .off(`.${scope}`) + .on(`${options.autoHideOn}.${scope}`, event => { + self.hide(overlay.name) + event.stopPropagation() + }) + delete options.autoHideOn + } + overlay.off('.attach') + let ret = { + overlay, + then: (callback) => { + overlay.on('show:after.attach', event => { callback(event) }) + return ret + }, + show: (callback) => { + overlay.on('show.attach', event => { callback(event) }) + return ret + }, + hide: (callback) => { + overlay.on('hide.attach', event => { callback(event) }) + return ret + }, + update: (callback) => { + overlay.on('update.attach', event => { callback(event) }) + return ret + }, + move: (callback) => { + overlay.on('move.attach', event => { callback(event) }) + return ret + } + } + return ret + } + update(name, html) { + let overlay = Tooltip.active[name] + if (overlay) { + overlay.needsUpdate = true + overlay.options.html = html + this.show(name) + } else { + console.log(`Tooltip "${name}" is not displayed. Cannot update it.`) + } + } + show(name) { + if (name instanceof HTMLElement || name instanceof Object) { + let options = name + if (name instanceof HTMLElement) { + options = arguments[1] || {} + options.anchor = name + } + let ret = this.attach(options) + query(ret.overlay.anchor) + .off('.autoShow-' + ret.overlay.name) + .off('.autoHide-' + ret.overlay.name) + // need a timer, so that events would be preperty set + setTimeout(() => { + this.show(ret.overlay.name) + if (this.initControls) { + this.initControls(ret.overlay) + } + }, 1) + return ret + } + let edata + let self = this + let overlay = Tooltip.active[name.replace(/[\s\.#]/g, '_')] + if (!overlay) return + let options = overlay.options + if (!overlay || (overlay.displayed && !overlay.needsUpdate)) { + this.resize(overlay?.name) + return + } + let position = options.position.split('|') + let isVertical = ['top', 'bottom'].includes(position[0]) + // enforce nowrap only when align=both and vertical + let overlayStyles = (options.align == 'both' && isVertical ? '' : 'white-space: nowrap;') + if (options.maxWidth && w2utils.getStrWidth(options.html, '') > options.maxWidth) { + overlayStyles = 'width: '+ options.maxWidth + 'px; white-space: inherit; overflow: auto;' + } + overlayStyles += ' max-height: '+ (options.maxHeight ? options.maxHeight : window.innerHeight - 40) + 'px;' + // if empty content - then hide it + if (options.html === '' || options.html == null) { + self.hide(name) + return + } else if (overlay.box) { + // if already present, update it + edata = this.trigger('update', { target: name, overlay }) + if (edata.isCancelled === true) { + // restore previous options + if (overlay.prevOptions) { + overlay.options = overlay.prevOptions + delete overlay.prevOptions + } + return + } + query(overlay.box) + .find('.w2ui-overlay-body') + .attr('style', (options.style || '') + '; ' + overlayStyles) + .removeClass() // removes all classes + .addClass('w2ui-overlay-body ' + options.class) + .html(options.html) + this.resize(overlay.name) + } else { + // event before + edata = this.trigger('show', { target: name, overlay }) + if (edata.isCancelled === true) return + // normal processing + query('body').append( + // pointer-events will be re-enabled leter + ``) + overlay.box = query('#'+w2utils.escapeId(overlay.id))[0] + overlay.displayed = true + let names = query(overlay.anchor).data('tooltipName') ?? [] + names.push(name) + query(overlay.anchor).data('tooltipName', names) // make available to element overlay attached to + w2utils.bindEvents(overlay.box, {}) + // remember anchor's original styles + overlay.tmp.originalCSS = '' + if (query(overlay.anchor).length > 0) { + overlay.tmp.originalCSS = query(overlay.anchor)[0].style.cssText + } + this.resize(overlay.name) + } + if (options.anchorStyle) { + overlay.anchor.style.cssText += ';' + options.anchorStyle + } + if (options.anchorClass) { + // do not add w2ui-focus to body + if (!(options.anchorClass == 'w2ui-focus' && overlay.anchor == document.body)) { + query(overlay.anchor).addClass(options.anchorClass) + } + } + // add on hide events + if (typeof options.hideOn == 'string') options.hideOn = [options.hideOn] + if (!Array.isArray(options.hideOn)) options.hideOn = [] + // initial scroll + Object.assign(overlay.tmp, { + scrollLeft: document.body.scrollLeft, + scrollTop: document.body.scrollTop + }) + addHideEvents() + addWatchEvents(document.body) + // first show empty tooltip, so it will popup up in the right position + query(overlay.box).show() + overlay.tmp.observeResize.observe(overlay.box) + // observer element removal from DOM + Tooltip.observeRemove.observe(document.body, { subtree: true, childList: true }) + // then insert html and it will adjust + query(overlay.box) + .css('opacity', 1) + .find('.w2ui-overlay-body') + .html(options.html) + /** + * pointer-events: none is needed to avoid cases when popup is shown right under the cursor + * or it will trigger onmouseout, onmouseleave and other events. + */ + setTimeout(() => { query(overlay.box).css({ 'pointer-events': 'auto' }).data('ready', 'yes') }, 100) + delete overlay.needsUpdate + // expose overlay to DOM element + overlay.box.overlay = overlay + // event after + if (edata) edata.finish() + return { overlay } + function addWatchEvents(el) { + let scope = 'tooltip-' + overlay.name + let queryEl = el + if (el.tagName == 'BODY') { + queryEl = el.ownerDocument + } + query(queryEl) + .off(`.${scope}`) + .on(`scroll.${scope}`, event => { + Object.assign(overlay.tmp, { + scrollLeft: el.scrollLeft, + scrollTop: el.scrollTop + }) + self.resize(overlay.name) + }) + } + function addHideEvents() { + let hide = (event) => { self.hide(overlay.name) } + let $anchor = query(overlay.anchor) + let scope = 'tooltip-' + overlay.name + // document click + query('body').off(`.${scope}`) + if (options.hideOn.includes('doc-click')) { + if (['INPUT', 'TEXTAREA'].includes(overlay.anchor.tagName)) { + // otherwise hides on click to focus + $anchor + .off(`.${scope}-doc`) + .on(`click.${scope}-doc`, (event) => { event.stopPropagation() }) + } + query('body').on(`click.${scope}`, hide) + } + if (options.hideOn.includes('focus-change')) { + query('body') + .on(`focusin.${scope}`, (e) => { + if (document.activeElement != overlay.anchor) { + self.hide(overlay.name) + } + }) + } + if (['INPUT', 'TEXTAREA'].includes(overlay.anchor.tagName)) { + $anchor.off(`.${scope}`) + options.hideOn.forEach(event => { + if (['doc-click', 'focus-change'].indexOf(event) == -1) { + $anchor.on(`${event}.${scope}`, { once: true }, hide) + } + }) + } + } + } + hide(name) { + let overlay + if (arguments.length == 0) { + // hide all tooltips + Object.keys(Tooltip.active).forEach(name => { this.hide(name) }) + return + } + if (name instanceof HTMLElement) { + let names = query(name).data('tooltipName') ?? [] + names.forEach(name => { this.hide(name) }) + return + } + if (typeof name == 'string') { + name = name.replace(/[\s\.#]/g, '_') + overlay = Tooltip.active[name] + } + if (!overlay || !overlay.box) return + delete Tooltip.active[name] + // event before + let edata = this.trigger('hide', { target: name, overlay }) + if (edata.isCancelled === true) return + let scope = 'tooltip-' + overlay.name + // normal processing + overlay.tmp.observeResize?.disconnect() + if (overlay.options.watchScroll) { + query(overlay.options.watchScroll) + .off('.w2scroll-' + overlay.name) + } + // if no active tooltip then disable observeRemove + let cnt = 0 + Object.keys(Tooltip.active).forEach(key => { + let overlay = Tooltip.active[key] + if (overlay.displayed) { + cnt++ + } + }) + if (cnt == 0) { + Tooltip.observeRemove.disconnect() + } + query('body').off(`.${scope}`) // hide to click event here + query(document).off(`.${scope}`) // scroll event here + // remove element + overlay.box.remove() + overlay.box = null + overlay.displayed = false + // remove name from anchor properties + let names = query(overlay.anchor).data('tooltipName') ?? [] + let ind = names.indexOf(overlay.name) + if (ind != -1) names.splice(names.indexOf(overlay.name), 1) + if (names.length == 0) { + query(overlay.anchor).removeData('tooltipName') + } else { + query(overlay.anchor).data('tooltipName', names) + } + // restore original CSS + overlay.anchor.style.cssText = overlay.tmp.originalCSS + query(overlay.anchor) + .off(`.${scope}`) + .removeClass(overlay.options.anchorClass) + // event after + edata.finish() + } + resize(name) { + if (arguments.length == 0) { + Object.keys(Tooltip.active).forEach(key => { + let overlay = Tooltip.active[key] + if (overlay.displayed) this.resize(overlay.name) + }) + return + } + let overlay = Tooltip.active[name.replace(/[\s\.#]/g, '_')] + let pos = this.getPosition(overlay.name) + let newPos = pos.left + 'x' + pos.top + let edata + if (overlay.tmp.lastPos != newPos) { + edata = this.trigger('move', { target: name, overlay, pos }) + } + query(overlay.box) + .css({ + left: pos.left + 'px', + top : pos.top + 'px' + }) + .then(query => { + if (pos.width != null) { + query.css('width', pos.width + 'px') + .find('.w2ui-overlay-body') + .css('width', '100%') + } + if (pos.height != null) { + query.css('height', pos.height + 'px') + .find('.w2ui-overlay-body') + .css('height', '100%') + } + }) + .find('.w2ui-overlay-body') + .removeClass('w2ui-arrow-right w2ui-arrow-left w2ui-arrow-top w2ui-arrow-bottom') + .addClass(pos.arrow.class) + .closest('.w2ui-overlay') + .find('style') + .text(pos.arrow.style) + if (overlay.tmp.lastPos != newPos && edata) { + overlay.tmp.lastPos = newPos + edata.finish() + } + } + getPosition(name) { + let overlay = Tooltip.active[name.replace(/[\s\.#]/g, '_')] + if (!overlay || !overlay.box) { + return + } + let options = overlay.options + if (overlay.tmp.resizedY || overlay.tmp.resizedX) { + query(overlay.box).css({ width: '', height: '', scroll: 'auto' }) + } + let scrollSize = w2utils.scrollBarSize() + let hasScrollBarX = !(document.body.scrollWidth == document.body.clientWidth) + let hasScrollBarY = !(document.body.scrollHeight == document.body.clientHeight) + let max = { + width: window.innerWidth - (hasScrollBarY ? scrollSize : 0), + height: window.innerHeight - (hasScrollBarX ? scrollSize : 0) + } + let position = options.position == 'auto' ? 'top|bottom|right|left'.split('|') : options.position.split('|') + let isVertical = ['top', 'bottom'].includes(position[0]) + let content = overlay.box.getBoundingClientRect() + let anchor = overlay.anchor.getBoundingClientRect() + if (overlay.anchor == document.body) { + // context menu + let { x, y, width, height } = options.originalEvent + anchor = { left: x - 2, top: y - 4, width, height, arrow: 'none' } + } + let arrowSize = options.arrowSize + if (anchor.arrow == 'none') arrowSize = 0 + // space available + let available = { // tipsize adjustment should be here, not in max.width/max.height + top: anchor.top, + bottom: max.height - (anchor.top + anchor.height) - + (hasScrollBarX ? scrollSize : 0), + left: anchor.left, + right: max.width - (anchor.left + anchor.width) + (hasScrollBarY ? scrollSize : 0), + } + // size of empty tooltip + if (content.width < 22) content.width = 22 + if (content.height < 14) content.height = 14 + let left, top, width, height // tooltip position + let found = '' + let arrow = { + offset: 0, + class: '', + style: `#${overlay.id} { --tip-size: ${arrowSize}px; }` + } + let adjust = { left: 0, top: 0 } + let bestFit = { posX: '', x: 0, posY: '', y: 0 } + // find best position + position.forEach(pos => { + if (['top', 'bottom'].includes(pos)) { + if (!found && (content.height + arrowSize/1.893) < available[pos]) { // 1.893 = 1 + sin(90) + found = pos + } + if (available[pos] > bestFit.y) { + Object.assign(bestFit, { posY: pos, y: available[pos] }) + } + } + if (['left', 'right'].includes(pos)) { + if (!found && (content.width + arrowSize/1.893) < available[pos]) { // 1.893 = 1 + sin(90) + found = pos + } + if (available[pos] > bestFit.x) { + Object.assign(bestFit, { posX: pos, x: available[pos] }) + } + } + }) + // if not found, use best (greatest available space) position + if (!found) { + if (isVertical) { + found = bestFit.posY + } else { + found = bestFit.posX + } + } + if (options.autoResize) { + if (['top', 'bottom'].includes(found)) { + if (content.height > available[found]) { + height = available[found] + overlay.tmp.resizedY = true + } else { + overlay.tmp.resizedY = false + } + } + if (['left', 'right'].includes(found)) { + if (content.width > available[found]) { + width = available[found] + overlay.tmp.resizedX = true + } else { + overlay.tmp.resizedX = false + } + } + } + usePosition(found) + if (isVertical) anchorAlignment() + screenAdjust() + let extraTop = (found == 'top' ? -options.margin : (found == 'bottom' ? options.margin : 0)) + let extraLeft = (found == 'left' ? -options.margin : (found == 'right' ? options.margin : 0)) + // adjust for scrollbar + top = Math.floor((top + parseFloat(options.offsetY) + parseFloat(extraTop)) * 100) / 100 + left = Math.floor((left + parseFloat(options.offsetX) + parseFloat(extraLeft)) * 100) / 100 + return { left, top, arrow, adjust, width, height, pos: found } + function usePosition(pos) { + arrow.class = anchor.arrow ? anchor.arrow : `w2ui-arrow-${pos}` + switch (pos) { + case 'top': { + left = anchor.left + (anchor.width - (width ?? content.width)) / 2 + top = anchor.top - (height ?? content.height) - arrowSize / 1.5 + 1 + break + } + case 'bottom': { + left = anchor.left + (anchor.width - (width ?? content.width)) / 2 + top = anchor.top + anchor.height + arrowSize / 1.25 + 1 + break + } + case 'left': { + left = anchor.left - (width ?? content.width) - arrowSize / 1.2 - 1 + top = anchor.top + (anchor.height - (height ?? content.height)) / 2 + break + } + case 'right': { + left = anchor.left + anchor.width + arrowSize / 1.2 + 1 + top = anchor.top + (anchor.height - (height ?? content.height)) / 2 + break + } + } + } + function anchorAlignment() { + // top/bottom alignments + if (options.align == 'left') { + adjust.left = anchor.left - left + left = anchor.left + } + if (options.align == 'right') { + adjust.left = (anchor.left + anchor.width - (width ?? content.width)) - left + left = anchor.left + anchor.width - (width ?? content.width) + } + if (['top', 'bottom'].includes(found) && options.align.startsWith('both')) { + let minWidth = options.align.split(':')[1] ?? 50 + if (anchor.width >= minWidth) { + left = anchor.left + width = anchor.width + } + } + // left/right alignments + if (options.align == 'top') { + adjust.top = anchor.top - top + top = anchor.top + } + if (options.align == 'bottom') { + adjust.top = (anchor.top + anchor.height - (height ?? content.height)) - top + top = anchor.top + anchor.height - (height ?? content.height) + } + if (['left', 'right'].includes(found) && options.align.startsWith('both')) { + let minHeight = options.align.split(':')[1] ?? 50 + if (anchor.height >= minHeight) { + top = anchor.top + height = anchor.height + } + } + } + function screenAdjust() { + let adjustArrow + // adjust tip if needed after alignment + if ((['left', 'right'].includes(options.align) && anchor.width < (width ?? content.width)) + || (['top', 'bottom'].includes(options.align) && anchor.height < (height ?? content.height)) + ) { + adjustArrow = true + } + // if off screen then adjust + let minLeft = (found == 'right' ? arrowSize : options.screenMargin) + let minTop = (found == 'bottom' ? arrowSize : options.screenMargin) + let maxLeft = max.width - (width ?? content.width) - (found == 'left' ? arrowSize : options.screenMargin) + let maxTop = max.height - (height ?? content.height) - (found == 'top' ? arrowSize : options.screenMargin) + 3 + // adjust X + if (['top', 'bottom'].includes(found) || options.autoResize) { + if (left < minLeft) { + adjustArrow = true + adjust.left -= left + left = minLeft + } + if (left > maxLeft) { + adjustArrow = true + adjust.left -= left - maxLeft + left += maxLeft - left + } + } + // adjust Y + if (['left', 'right'].includes(found) || options.autoResize) { + if (top < minTop) { + adjustArrow = true + adjust.top -= top + top = minTop + } + if (top > maxTop) { + adjustArrow = true + adjust.top -= top - maxTop + top += maxTop - top + } + } + // moves carret to adjust it with element width + if (adjustArrow) { + let aType = isVertical ? 'left' : 'top' + let sType = isVertical ? 'width' : 'height' + arrow.offset = -adjust[aType] + let maxOffset = content[sType] / 2 - arrowSize + if (Math.abs(arrow.offset) > maxOffset + arrowSize) { + arrow.class = '' // no arrow + } + if (Math.abs(arrow.offset) > maxOffset) { + arrow.offset = arrow.offset < 0 ? -maxOffset : maxOffset + } + arrow.style = w2utils.stripSpaces(`#${overlay.id} .w2ui-overlay-body:after, + #${overlay.id} .w2ui-overlay-body:before { + --tip-size: ${arrowSize}px; + margin-${aType}: ${arrow.offset}px; + }`) + } + } + } +} +class ColorTooltip extends Tooltip { + constructor() { + super() + this.palette = [ + ['000000', '333333', '555555', '777777', '888888', '999999', 'AAAAAA', 'CCCCCC', 'DDDDDD', 'EEEEEE', 'F7F7F7', 'FFFFFF'], + ['FF011B', 'FF9838', 'FFC300', 'FFFD59', '86FF14', '14FF7A', '2EFFFC', '2693FF', '006CE7', '9B24F4', 'FF21F5', 'FF0099'], + ['FFEAEA', 'FCEFE1', 'FCF4DC', 'FFFECF', 'EBFFD9', 'D9FFE9', 'E0FFFF', 'E8F4FF', 'ECF4FC', 'EAE6F4', 'FFF5FE', 'FCF0F7'], + ['F4CCCC', 'FCE5CD', 'FFF1C2', 'FFFDA1', 'D5FCB1', 'B5F7D0', 'BFFFFF', 'D6ECFF', 'CFE2F3', 'D9D1E9', 'FFE3FD', 'FFD9F0'], + ['EA9899', 'F9CB9C', 'FFE48C', 'F7F56F', 'B9F77E', '84F0B1', '83F7F7', 'B5DAFF', '9FC5E8', 'B4A7D6', 'FAB9F6', 'FFADDE'], + ['E06666', 'F6B26B', 'DEB737', 'E0DE51', '8FDB48', '52D189', '4EDEDB', '76ACE3', '6FA8DC', '8E7CC3', 'E07EDA', 'F26DBD'], + ['CC0814', 'E69138', 'AB8816', 'B5B20E', '6BAB30', '27A85F', '1BA8A6', '3C81C7', '3D85C6', '674EA7', 'A14F9D', 'BF4990'], + ['99050C', 'B45F17', '80650E', '737103', '395E14', '10783D', '13615E', '094785', '0A5394', '351C75', '780172', '782C5A'] + ] + this.defaults = w2utils.extend({}, this.defaults, { + advanced : false, + transparent : true, + position : 'top|bottom', + class : 'w2ui-white', + color : '', + liveUpdate : true, + arrowSize : 12, + autoResize : false, + anchorClass : 'w2ui-focus', + autoShowOn : 'focus', + hideOn : ['doc-click', 'focus-change'], + onSelect : null, + onLiveUpdate: null + }) + } + attach(anchor, text) { + let options + if (arguments.length == 1 && anchor.anchor) { + options = anchor + anchor = options.anchor + } else if (arguments.length === 2 && text != null && typeof text === 'object') { + options = text + options.anchor = anchor + } + let prevHideOn = options.hideOn + options = w2utils.extend({}, this.defaults, options || {}) + if (prevHideOn) { + options.hideOn = prevHideOn + } + options.style += '; padding: 0;' + // add remove transparent color + if (options.transparent && this.palette[0][1] == '333333') { + this.palette[0].splice(1, 1) + this.palette[0].push('') + } + if (!options.transparent && this.palette[0][1] != '333333') { + this.palette[0].splice(1, 0, '333333') + this.palette[0].pop() + } + if (options.color) options.color = String(options.color).toUpperCase() + if (typeof options.color === 'string' && options.color.substr(0,1) === '#') options.color = options.color.substr(1) + // needed for keyboard navigation + this.index = [-1, -1] + let ret = super.attach(options) + let overlay = ret.overlay + overlay.options.html = this.getColorHTML(overlay.name, options) + overlay.on('show.attach', event => { + let overlay = event.detail.overlay + let anchor = overlay.anchor + let options = overlay.options + if (['INPUT', 'TEXTAREA'].includes(anchor.tagName) && !options.color && anchor.value) { + overlay.tmp.initColor = anchor.value + } + delete overlay.newColor + }) + overlay.on('show:after.attach', event => { + if (ret.overlay?.box) { + let actions = query(ret.overlay.box).find('.w2ui-eaction') + w2utils.bindEvents(actions, this) + this.initControls(ret.overlay) + } + }) + overlay.on('update:after.attach', event => { + if (ret.overlay?.box) { + let actions = query(ret.overlay.box).find('.w2ui-eaction') + w2utils.bindEvents(actions, this) + this.initControls(ret.overlay) + } + }) + overlay.on('hide.attach', event => { + let overlay = event.detail.overlay + let anchor = overlay.anchor + let color = overlay.newColor ?? overlay.options.color ?? '' + if (['INPUT', 'TEXTAREA'].includes(anchor.tagName) && anchor.value != color) { + anchor.value = color + } + let edata = this.trigger('select', { color, target: overlay.name, overlay }) + if (edata.isCancelled === true) return + // event after + edata.finish() + }) + ret.liveUpdate = (callback) => { + overlay.on('liveUpdate.attach', (event) => { callback(event) }) + return ret + } + ret.select = (callback) => { + overlay.on('select.attach', (event) => { callback(event) }) + return ret + } + return ret + } + // regular panel handler, adds selection class + select(color, name) { + let target + this.index = [-1, -1] + if (typeof name != 'string') { + target = name.target + this.index = query(target).attr('index').split(':') + name = query(target).closest('.w2ui-overlay').attr('name') + } + let overlay = this.get(name) + // event before + let edata = this.trigger('liveUpdate', { color, target: name, overlay, param: arguments[1] }) + if (edata.isCancelled === true) return + // if anchor is input - live update + if (['INPUT', 'TEXTAREA'].includes(overlay.anchor.tagName) && overlay.options.liveUpdate) { + query(overlay.anchor).val(color) + } + overlay.newColor = color + query(overlay.box).find('.w2ui-selected').removeClass('w2ui-selected') + if (target) { + query(target).addClass('w2ui-selected') + } + // event after + edata.finish() + } + // used for keyboard navigation, if any + nextColor(direction) { // TODO: check it + let pal = this.palette + switch (direction) { + case 'up': + this.index[0]-- + break + case 'down': + this.index[0]++ + break + case 'right': + this.index[1]++ + break + case 'left': + this.index[1]-- + break + } + if (this.index[0] < 0) this.index[0] = 0 + if (this.index[0] > pal.length - 2) this.index[0] = pal.length - 2 + if (this.index[1] < 0) this.index[1] = 0 + if (this.index[1] > pal[0].length - 1) this.index[1] = pal[0].length - 1 + return pal[this.index[0]][this.index[1]] + } + tabClick(index, name) { + if (typeof name != 'string') { + name = query(name.target).closest('.w2ui-overlay').attr('name') + } + let overlay = this.get(name) + let tab = query(overlay.box).find(`.w2ui-color-tab:nth-child(${index})`) + query(overlay.box).find('.w2ui-color-tab').removeClass('w2ui-selected') + query(tab).addClass('w2ui-selected') + query(overlay.box) + .find('.w2ui-tab-content') + .hide() + .closest('.w2ui-colors') + .find('.tab-'+ index) + .show() + } + // generate HTML with color pallent and controls + getColorHTML(name, options) { + let html = ` +
    +
    ` + for (let i = 0; i < this.palette.length; i++) { + html += '
    ' + for (let j = 0; j < this.palette[i].length; j++) { + let color = this.palette[i][j] + let border = '' + if (color === 'FFFFFF') border = '; border: 1px solid #efefef' + html += ` +
      +
    ` + } + html += '
    ' + if (i < 2) html += '
    ' + } + html += '
    ' + // advanced tab + html += ` + ` + // color tabs on the bottom + html += ` +
    +
    +
    +
    + ${(typeof options.html == 'string' ? options.html : '')} +
    +
    ` + return html + } + // bind advanced tab controls + initControls(overlay) { + let initial // used for mouse events + let self = this + let options = overlay.options + let rgb = w2utils.parseColor(options.color || overlay.tmp.initColor) + if (rgb == null) { + rgb = { r: 140, g: 150, b: 160, a: 1 } + } + let hsv = w2utils.rgb2hsv(rgb) + if (options.advanced === true) { + this.tabClick(2, overlay.name) + } + setColor(hsv, true, true) + // even for rgb, hsv inputs + query(overlay.box).find('input') + .off('.w2color') + .on('change.w2color', (event) => { + let el = query(event.target) + let val = parseFloat(el.val()) + let max = parseFloat(el.attr('max')) + if (isNaN(val)) { + val = 0 + el.val(0) + } + if (max > 1) val = parseInt(val) // trancate fractions + if (max > 0 && val > max) { + el.val(max) + val = max + } + if (val < 0) { + el.val(0) + val = 0 + } + let name = el.attr('name') + let color = {} + if (['r', 'g', 'b', 'a'].indexOf(name) !== -1) { + rgb[name] = val + hsv = w2utils.rgb2hsv(rgb) + } else if (['h', 's', 'v'].indexOf(name) !== -1) { + color[name] = val + } + setColor(color, true) + }) + // click on original color resets it + query(overlay.box).find('.color-original') + .off('.w2color') + .on('click.w2color', (event) => { + let tmp = w2utils.parseColor(query(event.target).css('background-color')) + if (tmp != null) { + rgb = tmp + hsv = w2utils.rgb2hsv(rgb) + setColor(hsv, true) + } + }) + // color sliders events + let mDown = `${!w2utils.isIOS ? 'mousedown' : 'touchstart'}.w2color` + let mUp = `${!w2utils.isIOS ? 'mouseup' : 'touchend'}.w2color` + let mMove = `${!w2utils.isIOS ? 'mousemove' : 'touchmove'}.w2color` + query(overlay.box).find('.palette, .rainbow, .alpha') + .off('.w2color') + .on(`${mDown}.w2color`, mouseDown) + return + function setColor(color, fullUpdate, initial) { + if (color.h != null) hsv.h = color.h + if (color.s != null) hsv.s = color.s + if (color.v != null) hsv.v = color.v + if (color.a != null) { rgb.a = color.a; hsv.a = color.a } + rgb = w2utils.hsv2rgb(hsv) + let newColor = 'rgba('+ rgb.r +','+ rgb.g +','+ rgb.b +','+ rgb.a +')' + let cl = [ + Number(rgb.r).toString(16).toUpperCase(), + Number(rgb.g).toString(16).toUpperCase(), + Number(rgb.b).toString(16).toUpperCase(), + (Math.round(Number(rgb.a)*255)).toString(16).toUpperCase() + ] + cl.forEach((item, ind) => { if (item.length === 1) cl[ind] = '0' + item }) + newColor = cl[0] + cl[1] + cl[2] + cl[3] + if (rgb.a === 1) { + newColor = cl[0] + cl[1] + cl[2] + } + query(overlay.box).find('.color-preview').css('background-color', '#' + newColor) + query(overlay.box).find('input').each(el => { + if (el.name) { + if (rgb[el.name] != null) el.value = rgb[el.name] + if (hsv[el.name] != null) el.value = hsv[el.name] + if (el.name === 'a') el.value = rgb.a + } + }) + // if it is in pallette + if (initial) { + let color = overlay.tmp?.initColor || newColor + query(overlay.box).find('.color-original') + .css('background-color', '#'+color) + query(overlay.box).find('.w2ui-colors .w2ui-selected') + .removeClass('w2ui-selected') + query(overlay.box).find(`.w2ui-colors [name="${color}"]`) + .addClass('w2ui-selected') + // if has transparent color, open advanced tab + if (newColor.length == 8) { + self.tabClick(2, overlay.name) + } + } else { + self.select(newColor, overlay.name) + } + if (fullUpdate) { + updateSliders() + refreshPalette() + } + } + function updateSliders() { + let el1 = query(overlay.box).find('.palette .value1') + let el2 = query(overlay.box).find('.rainbow .value2') + let el3 = query(overlay.box).find('.alpha .value2') + let offset1 = parseInt(el1[0].clientWidth) / 2 + let offset2 = parseInt(el2[0].clientWidth) / 2 + el1.css({ + 'left': (hsv.s * 150 / 100 - offset1) + 'px', + 'top': ((100 - hsv.v) * 125 / 100 - offset1) + 'px' + }) + el2.css('left', (hsv.h/(360/150) - offset2) + 'px') + el3.css('left', (rgb.a*150 - offset2) + 'px') + } + function refreshPalette() { + let cl = w2utils.hsv2rgb(hsv.h, 100, 100) + let rgb = `${cl.r},${cl.g},${cl.b}` + query(overlay.box).find('.palette') + .css('background-image', `linear-gradient(90deg, rgba(${rgb},0) 0%, rgba(${rgb},1) 100%)`) + } + function mouseDown(event) { + let el = query(this).find('.value1, .value2') + let offset = parseInt(el.prop('clientWidth')) / 2 + if (el.hasClass('move-x')) el.css({ left: (event.offsetX - offset) + 'px' }) + if (el.hasClass('move-y')) el.css({ top: (event.offsetY - offset) + 'px' }) + initial = { + el : el, + x : event.pageX, + y : event.pageY, + width : el.prop('parentNode').clientWidth, + height : el.prop('parentNode').clientHeight, + left : parseInt(el.css('left')), + top : parseInt(el.css('top')) + } + mouseMove(event) + query('body') + .off('.w2color') + .on(mMove, mouseMove) + .on(mUp, mouseUp) + } + function mouseUp(event) { + query('body').off('.w2color') + } + function mouseMove(event) { + let el = initial.el + let divX = event.pageX - initial.x + let divY = event.pageY - initial.y + let newX = initial.left + divX + let newY = initial.top + divY + let offset = parseInt(el.prop('clientWidth')) / 2 + if (newX < -offset) newX = -offset + if (newY < -offset) newY = -offset + if (newX > initial.width - offset) newX = initial.width - offset + if (newY > initial.height - offset) newY = initial.height - offset + if (el.hasClass('move-x')) el.css({ left : newX + 'px' }) + if (el.hasClass('move-y')) el.css({ top : newY + 'px' }) + // move + let name = query(el.get(0).parentNode).attr('name') + let x = parseInt(el.css('left')) + offset + let y = parseInt(el.css('top')) + offset + if (name === 'palette') { + setColor({ + s: Math.round(x / initial.width * 100), + v: Math.round(100 - (y / initial.height * 100)) + }) + } + if (name === 'rainbow') { + let h = Math.round(360 / 150 * x) + setColor({ h: h }) + refreshPalette() + } + if (name === 'alpha') { + setColor({ a: parseFloat(Number(x / 150).toFixed(2)) }) + } + } + } +} +class MenuTooltip extends Tooltip { + constructor() { + super() + // ITEM STRUCTURE + // item : { + // id : null, + // text : '', + // style : '', + // icon : '', + // count : '', + // tooltip : '', + // hotkey : '', + // remove : false, + // items : [] + // indent : 0, + // type : null, // check/radio + // group : false, // groupping for checks + // expanded : false, + // hidden : false, + // checked : null, + // disabled : false + // ... + // } + this.defaults = w2utils.extend({}, this.defaults, { + type : 'normal', // can be normal, radio, check + items : [], + index : null, // current selected + render : null, + spinner : false, + msgNoItems : w2utils.lang('No items found'), + topHTML : '', + menuStyle : '', + filter : false, + markSearch : false, + match : 'contains', // is, begins, ends, contains + search : false, // top search TODO: Check + altRows : false, + arrowSize : 10, + align : 'left', + position : 'bottom|top', + class : 'w2ui-white', + anchorClass : 'w2ui-focus', + autoShowOn : 'focus', + hideOn : ['doc-click', 'focus-change', 'select'], // also can 'item-remove' + onSelect : null, + onSubMenu : null, + onRemove : null + }) + } + attach(anchor, text) { + let options + if (arguments.length == 1 && anchor.anchor) { + options = anchor + anchor = options.anchor + } else if (arguments.length === 2 && text != null && typeof text === 'object') { + options = text + options.anchor = anchor + } + let prevHideOn = options.hideOn + options = w2utils.extend({}, this.defaults, options || {}) + if (prevHideOn) { + options.hideOn = prevHideOn + } + options.style += '; padding: 0;' + if (options.items == null) { + options.items = [] + } + options.html = this.getMenuHTML(options) + let ret = super.attach(options) + let overlay = ret.overlay + overlay.on('show:after.attach, update:after.attach', event => { + if (ret.overlay?.box) { + let search = '' + // reset selected and active chain + overlay.selected = null + overlay.options.items = w2utils.normMenu(overlay.options.items) + if (['INPUT', 'TEXTAREA'].includes(overlay.anchor.tagName)) { + search = overlay.anchor.value + overlay.selected = overlay.anchor.dataset.selectedIndex + } + let actions = query(ret.overlay.box).find('.w2ui-eaction') + w2utils.bindEvents(actions, this) + this.applyFilter(overlay.name, null, search) + .then(data => { + overlay.tmp.searchCount = data.count + overlay.tmp.search = data.search + this.refreshSearch(overlay.name) + this.initControls(ret.overlay) + this.refreshIndex(overlay.name) + }) + } + }) + overlay.on('hide:after.attach', event => { + w2tooltip.hide(overlay.name + '-tooltip') + }) + ret.select = (callback) => { + overlay.on('select.attach', (event) => { callback(event) }) + return ret + } + ret.remove = (callback) => { + overlay.on('remove.attach', (event) => { callback(event) }) + return ret + } + ret.subMenu = (callback) => { + overlay.on('subMenu.attach', (event) => { callback(event) }) + return ret + } + return ret + } + update(name, items) { + let overlay = Tooltip.active[name] + if (overlay) { + let options = overlay.options + if (options.items != items) { + options.items = items + } + let menuHTML = this.getMenuHTML(options) + if (options.html != menuHTML) { + options.html = menuHTML + overlay.needsUpdate = true + this.show(name) + } + } else { + console.log(`Tooltip "${name}" is not displayed. Cannot update it.`) + } + } + initControls(overlay) { + query(overlay.box).find('.w2ui-menu:not(.w2ui-sub-menu)') + .off('.w2menu') + .on('mouseDown.w2menu', { delegate: '.w2ui-menu-item' }, event => { + let dt = event.delegate.dataset + this.menuDown(overlay, event, dt.index, dt.parents) + }) + .on((w2utils.isIOS ? 'touchStart' : 'click') + '.w2menu', { delegate: '.w2ui-menu-item' }, event => { + let dt = event.delegate.dataset + this.menuClick(overlay, event, parseInt(dt.index), dt.parents) + }) + .find('.w2ui-menu-item') + .off('.w2menu') + .on('mouseEnter.w2menu', event => { + let dt = event.target.dataset + let tooltip = overlay.options.items[dt.index]?.tooltip + if (tooltip) { + w2tooltip.show({ + name: overlay.name + '-tooltip', + anchor: event.target, + html: tooltip, + position: 'right|left', + hideOn: ['doc-click'] + }) + } + }) + .on('mouseLeave.w2menu', event => { + w2tooltip.hide(overlay.name + '-tooltip') + }) + if (['INPUT', 'TEXTAREA'].includes(overlay.anchor.tagName)) { + query(overlay.anchor) + .off('.w2menu') + .on('input.w2menu', event => { + // if user types, clear selection + // let dt = event.target.dataset + // delete dt.selected + // delete dt.selectedIndex + }) + .on('keyup.w2menu', event => { + event._searchType = 'filter' + this.keyUp(overlay, event) + }) + } + if (overlay.options.search) { + query(overlay.box).find('#menu-search') + .off('.w2menu') + .on('keyup.w2menu', event => { + event._searchType = 'search' + this.keyUp(overlay, event) + }) + } + } + getCurrent(name, id) { + let overlay = Tooltip.active[name.replace(/[\s\.#]/g, '_')] + let options = overlay.options + let selected = (id ? id : overlay.selected ?? '').split('-') + let last = selected.length-1 + let index = selected[last] + let parents = selected.slice(0, selected.length-1).join('-') + index = w2utils.isInt(index) ? parseInt(index) : 0 + // items + let items = options.items + selected.forEach((id, ind) => { + // do not go to the last one + if (ind < selected.length - 1) { + items = items[id].items + } + }) + return { last, index, items, item: items[index], parents } + } + getMenuHTML(options, items, subMenu, parentIndex) { + if (options.spinner) { + return ` +
    +
    +
    + ${w2utils.lang('Loading...')} +
    +
    ` + } + if (!parentIndex) parentIndex = [] + if (items == null) { + items = options.items + } + if (!Array.isArray(items)) items = [] + let count = 0 + let icon = null + let topHTML = '' + if (!subMenu && options.search) { + topHTML += ` + ` + items.forEach(item => item.hidden = false) + } + if (!subMenu && options.topHTML) { + topHTML += `
    ${options.topHTML}
    ` + } + let menu_html = ` + ${topHTML} +
    + ` + items.forEach((mitem, f) => { + icon = mitem.icon + let index = (parentIndex.length > 0 ? parentIndex.join('-') + '-' : '') + f + if (icon == null) icon = null // icon might be undefined + if (['radio', 'check'].indexOf(options.type) != -1 && !Array.isArray(mitem.items) && mitem.group !== false) { + if (mitem.checked === true) icon = 'w2ui-icon-check'; else icon = 'w2ui-icon-empty' + } + if (mitem.hidden !== true) { + let txt = mitem.text + let icon_dsp = '' + let subMenu_dsp = '' + if (typeof options.render === 'function') txt = options.render(mitem, options) + if (typeof txt == 'function') txt = txt(mitem, options) + if (icon) { + if (String(icon).slice(0, 1) !== '<') { + icon = `` + } + icon_dsp = `` + } + // render only if non-empty + if (mitem.type !== 'break' && txt != null && txt !== '' && String(txt).substr(0, 2) != '--') { + let classes = ['w2ui-menu-item'] + if (options.altRows == true) { + classes.push(count % 2 === 0 ? 'w2ui-even' : 'w2ui-odd') + } + let colspan = 1 + if (icon_dsp === '') colspan++ + if (mitem.count == null && mitem.hotkey == null && mitem.remove !== true && mitem.items == null) colspan++ + if (mitem.tooltip == null && mitem.hint != null) mitem.tooltip = mitem.hint // for backward compatibility + let count_dsp = '' + if (mitem.remove === true) { + count_dsp = 'x' + } else if (mitem.items != null) { + let _items = [] + if (typeof mitem.items == 'function') { + _items = mitem.items(mitem) + } else if (Array.isArray(mitem.items)) { + _items = mitem.items + } + count_dsp = '' + subMenu_dsp = ` +
    + ${this.getMenuHTML(options, _items, true, parentIndex.concat(f))} +
    ` + } else { + if (mitem.count != null) count_dsp += '' + mitem.count + '' + if (mitem.hotkey != null) count_dsp += '' + mitem.hotkey + '' + } + if (mitem.disabled === true) classes.push('w2ui-disabled') + if (mitem._noSearchInside === true) classes.push('w2ui-no-search-inside') + if (subMenu_dsp !== '') { + classes.push('has-sub-menu') + if (mitem.expanded) { + classes.push('expanded') + } else { + classes.push('collapsed') + } + } + menu_html += ` +
    +
    + ${icon_dsp} + + +
    + ${subMenu_dsp}` + count++ + } else { + // horizontal line + let divText = (txt ?? '').replace(/^-+/g, '') + menu_html += ` +
    +
    + ${divText ? `
    ${divText}
    ` : ''} +
    ` + } + } + items[f] = mitem + }) + if (count === 0 && options.msgNoItems) { + menu_html += ` +
    + ${w2utils.lang(options.msgNoItems)} +
    ` + } + menu_html += '
    ' + return menu_html + } + // Refreshed only selected item highligh, used in keyboard navigation + refreshIndex(name) { + let overlay = Tooltip.active[name.replace(/[\s\.#]/g, '_')] + if (!overlay) return + if (!overlay.displayed) { + this.show(overlay.name) + } + let view = query(overlay.box).find('.w2ui-overlay-body').get(0) + let search = query(overlay.box).find('.w2ui-menu-search, .w2ui-menu-top').get(0) + query(overlay.box).find('.w2ui-menu-item.w2ui-selected') + .removeClass('w2ui-selected') + let el = query(overlay.box).find(`.w2ui-menu-item[index="${overlay.selected}"]`) + .addClass('w2ui-selected') + .get(0) + if (el) { + if (el.offsetTop + el.clientHeight > view.clientHeight + view.scrollTop) { + el.scrollIntoView({ behavior: 'smooth', block: 'start', inline: 'start' }) + } + if (el.offsetTop < view.scrollTop + (search ? search.clientHeight : 0)) { + el.scrollIntoView({ behavior: 'smooth', block: 'end', inline: 'end' }) + } + } + } + // show/hide searched items + refreshSearch(name) { + let overlay = Tooltip.active[name.replace(/[\s\.#]/g, '_')] + if (!overlay) return + if (!overlay.displayed) { + this.show(overlay.name) + } + query(overlay.box).find('.w2ui-no-items').hide() + query(overlay.box).find('.w2ui-menu-item, .w2ui-menu-divider').each(el => { + let cur = this.getCurrent(name, el.getAttribute('index')) + if (cur.item?.hidden) { + query(el).hide() + } else { + let search = overlay.tmp?.search + if (search && overlay.options.markSearch) { + w2utils.marker(el, search, { onlyFirst: overlay.options.match == 'begins' }) + } + query(el).show() + } + }) + // hide empty menus + query(overlay.box).find('.w2ui-sub-menu').each(sub => { + let hasItems = query(sub).find('.w2ui-menu-item').get().some(el => { + return el.style.display != 'none' ? true : false + }) + let parent = this.getCurrent(name, sub.dataset.parent) + // only if parent is expaneded + if (parent.item.expanded) { + if (!hasItems) { + query(sub).parent().hide() + } else { + query(sub).parent().show() + } + } + }) + // show empty message + if (overlay.tmp.searchCount == 0 || overlay.options?.items?.length == 0) { + if (query(overlay.box).find('.w2ui-no-items').length == 0) { + query(overlay.box).find('.w2ui-menu:not(.w2ui-sub-menu)').append(` +
    + ${w2utils.lang(overlay.options.msgNoItems)} +
    `) + } + query(overlay.box).find('.w2ui-no-items').show() + } + } + /** + * Loops through the items and markes item.hidden = true for those that need to be hidden, and item.hidden = false + * for those that are visible. Return a promise (since items can be on the server) with the number of visible items. + */ + applyFilter(name, items, search, debounce) { + let count = 0 + let overlay = Tooltip.active[name.replace(/[\s\.#]/g, '_')] + let options = overlay.options + let resolve, reject + let prom = new Promise((res, rej) => { + resolve = res + reject = rej + }) + if (search == null) { + if (['INPUT', 'TEXTAREA'].includes(overlay.anchor.tagName)) { + search = overlay.anchor.value + } else { + search = '' + } + } + let selectedIds = [] + if (options.selected) { + if (Array.isArray(options.selected)) { + selectedIds = options.selected.map(item => { + return item?.id ?? item + }) + } else if (options.selected?.id) { + selectedIds = [options.selected.id] + } + } + overlay.tmp.activeChain = null + // if url is defined, get items from it + let remote = overlay.tmp.remote ?? { hasMore: true, emtpySet: false, search: null, total: -1 } + if (items == null && options.url && remote.hasMore && remote.search !== search) { + let proceed = true + // only when items == null because it is case of nested items + let msg = w2utils.lang('Loading...') + if (search.length < options.minLength && remote.emptySet !== true) { + msg = w2utils.lang('${count} letters or more...', { count: options.minLength }) + proceed = false + if (search === '') { + msg = w2utils.lang(options.msgSearch) + } + } + query(overlay.box).find('.w2ui-no-items').html(msg) + remote.search = search + options.items = [] + overlay.tmp.remote = remote + if (proceed) { + this.request(overlay, search, debounce) + .then(remoteItems => { + this.update(name, remoteItems) + this.applyFilter(name, null, search).then(data => { + resolve(data) + }) + }) + .catch(error => { + console.log('Server Request error', error) + }) + } + return prom + } + let edata + // only trigger search event when data is present and for the top level + if (items == null) { + edata = this.trigger('search', { search, overlay, prom, resolve, reject }) + if (edata.isCancelled === true) { + return prom + } + } + if (items == null) { + items = overlay.options.items + } + if (options.filter === false) { + resolve({ count: -1, search }) + return prom + } + items.forEach(item => { + let prefix = '' + let suffix = '' + if (['is', 'begins', 'begins with'].indexOf(options.match) !== -1) prefix = '^' + if (['is', 'ends', 'ends with'].indexOf(options.match) !== -1) suffix = '$' + try { + let re = new RegExp(prefix + search + suffix, 'i') + if (re.test(item.text) || item.text === '...') { + item.hidden = false + } else { + item.hidden = true + } + } catch (e) {} + // do not show selected items + if (options.hideSelected && selectedIds.includes(item.id)) { + item.hidden = true + } + // search nested items + if (Array.isArray(item.items) && item.items.length > 0) { + delete item._noSearchInside + this.applyFilter(name, item.items, search).then(data => { + let subCount = data.count + if (subCount > 0) { + count += subCount + if (item.hidden) item._noSearchInside = true + // only expand items if search is not empty + if (search) item.expanded = true + item.hidden = false + } + }) + } + if (item.hidden !== true) count++ + }) + resolve({ count, search }) + edata?.finish() + return prom + } + request(overlay, search, debounce) { + let options = overlay.options + let remote = overlay.tmp.remote + let resolve, reject // promise functions + if ((options.items.length === 0 && remote.total !== 0) + || (remote.total == options.cacheMax && search.length > remote.search.length) + || (search.length >= remote.search.length && search.substr(0, remote.search.length) !== remote.search) + || (search.length < remote.search.length)) + { + // Aabort previous request if any + if (remote.controller) { + remote.controller.abort() + } + remote.loading = true + clearTimeout(remote.timeout) + remote.timeout = setTimeout(() => { + let url = options.url + let postData = { search, max: options.cacheMax } + Object.assign(postData, options.postData) + // trigger event + let edata = this.trigger('request', { + search, overlay, url, postData, + httpMethod: options.method ?? 'GET', + httpHeaders: {} + }) + if (edata.isCancelled === true) return + // if event updated url and postData, use it + url = new URL(edata.detail.url, location) + let fetchOptions = w2utils.prepareParams(url, { + method: edata.detail.httpMethod, + headers: edata.detail.httpHeaders, + body: edata.detail.postData + }) + // Create new abort controller + remote.controller = new AbortController() + fetchOptions.signal = remote.controller.signal + // send request + fetch(url, fetchOptions) + .then(resp => resp.json()) + .then(data => { + remote.controller = null + // trigger event + let edata = overlay.trigger('load', { search: postData.search, overlay, data }) + if (edata.isCancelled === true) return + // default behavior + data = edata.detail.data + if (typeof data === 'string') data = JSON.parse(data) + // if server just returns array + if (Array.isArray(data)) { + data = { records: data } + } + // needed for backward compatibility + if (data.records == null && data.items != null) { + data.records = data.items + delete data.items + } + // handles Golang marshal of empty arrays to null + if (!data.error && data.records == null) { + data.records = [] + } + if (!Array.isArray(data.records)) { + console.error('ERROR: server did not return proper data structure', '\n', + ' - it should return', { records: [{ id: 1, text: 'item' }] }, '\n', + ' - or just an array ', [{ id: 1, text: 'item' }], '\n', + ' - or if errorr ', { error: true, message: 'error message' }) + return + } + // remove all extra items if more then needed for cache + if (data.records.length >= options.cacheMax) { + data.records.splice(options.cacheMax, data.records.length) + remote.hasMore = true + } else { + remote.hasMore = false + } + // map id and text + if (options.recId == null && options.recid != null) options.recId = options.recid // since lower-case recid is used in grid + if (options.recId || options.recText) { + data.records.forEach((item) => { + if (typeof options.recId === 'string') item.id = item[options.recId] + if (typeof options.recId === 'function') item.id = options.recId(item) + if (typeof options.recText === 'string') item.text = item[options.recText] + if (typeof options.recText === 'function') item.text = options.recText(item) + }) + } + // remember stats + remote.loading = false + remote.search = search + remote.total = data.records.length + remote.lastError = '' + remote.emptySet = (search === '' && data.records.length === 0 ? true : false) + // event after + edata.finish() + resolve(w2utils.normMenu(data.records)) + }) + .catch(error => { + let edata = this.trigger('error', { overlay, search, error }) + if (edata.isCancelled === true) return + // default behavior + if (error?.name !== 'AbortError') { + console.error('ERROR: Server communication failed.', '\n', + ' - it should return', { records: [{ id: 1, text: 'item' }] }, '\n', + ' - or just an array ', [{ id: 1, text: 'item' }], '\n', + ' - or if errorr ', { error: true, message: 'error message' }) + } + // reset stats + remote.loading = false + remote.search = '' + remote.total = -1 + remote.emptySet = true + remote.lastError = (edata.detail.error || 'Server communication failed') + options.items = [] + // event after + edata.finish() + reject() + }) + // event after + edata.finish() + }, debounce ? (options.debounce ?? 350) : 0) + } + return new Promise((res, rej) => { + resolve = res + reject = rej + }) + } + /** + * Builds an array of item ids that sequencial in navigation with up/down keys. + * Skips hidden and disabled items and goes into nested structures. + */ + getActiveChain(name, items, parents = [], res = [], noSave) { + let overlay = Tooltip.active[name.replace(/[\s\.#]/g, '_')] + if (overlay.tmp.activeChain != null) { + return overlay.tmp.activeChain + } + if (items == null) items = overlay.options.items + items.forEach((item, ind) => { + if (!item.hidden && !item.disabled && !item?.text?.startsWith('--')) { + res.push(parents.concat([ind]).join('-')) + if (Array.isArray(item.items) && item.items.length > 0 && item.expanded) { + parents.push(ind) + this.getActiveChain(name, item.items, parents, res, true) + parents.pop() + } + } + }) + if (noSave == null) { + overlay.tmp.activeChain = res + } + return res + } + menuDown(overlay, event, index, parentIndex) { + let options = overlay.options + let items = options.items + let icon = query(event.delegate).find('.w2ui-icon') + let menu = query(event.target).closest('.w2ui-menu:not(.w2ui-sub-menu)') + if (typeof parentIndex == 'string' && parentIndex !== '') { + let ids = parentIndex.split('-') + ids.forEach(id => { + items = items[id].items + }) + } + let item = items[index] + if (item.disabled) { + return + } + let uncheck = (items, parent) => { + items.forEach((other, ind) => { + if (other.id == item.id) return + if (other.group === item.group && other.checked) { + menu + .find(`.w2ui-menu-item[index="${(parent ? parent + '-' : '') + ind}"] .w2ui-icon`) + .removeClass('w2ui-icon-check') + .addClass('w2ui-icon-empty') + items[ind].checked = false + } + if (Array.isArray(other.items)) { + uncheck(other.items, ind) + } + }) + } + if ((options.type === 'check' || options.type === 'radio') && item.group !== false + && !query(event.target).hasClass('remove') + && !query(event.target).closest('.w2ui-menu-item').hasClass('has-sub-menu')) { + item.checked = options.type == 'radio' ? true : !item.checked + if (item.checked) { + if (options.type === 'radio') { + query(event.target).closest('.w2ui-menu').find('.w2ui-icon') + .removeClass('w2ui-icon-check') + .addClass('w2ui-icon-empty') + } + if (options.type === 'check' && item.group != null) { + uncheck(options.items) + } + icon.removeClass('w2ui-icon-empty').addClass('w2ui-icon-check') + } else if (options.type === 'check') { + icon.removeClass('w2ui-icon-check').addClass('w2ui-icon-empty') + } + } + // highlight record + if (!query(event.target).hasClass('remove')) { + menu.find('.w2ui-menu-item').removeClass('w2ui-selected') + query(event.delegate).addClass('w2ui-selected') + } + } + menuClick(overlay, event, index, parentIndex) { + let options = overlay.options + let items = options.items + let $item = query(event.delegate).closest('.w2ui-menu-item') + let keepOpen = options.hideOn.includes('select') ? false : true + if (event.shiftKey || event.metaKey || event.ctrlKey) { + keepOpen = true + } + if (typeof parentIndex == 'string' && parentIndex !== '') { + let ids = parentIndex.split('-') + ids.forEach(id => { + items = items[id].items + }) + } else { + parentIndex = null + } + if (typeof items == 'function') { + items = items({ overlay, index, parentIndex, event }) + } + let item = items[index] + if (item.disabled && !query(event.target).hasClass('remove')) { + return + } + let edata + if (query(event.target).hasClass('remove')) { + edata = this.trigger('remove', { originalEvent: event, target: overlay.name, + overlay, item, index, parentIndex, el: $item[0] }) + if (edata.isCancelled === true) { + return + } + keepOpen = !options.hideOn.includes('item-remove') + $item.remove() + } else if ($item.hasClass('has-sub-menu')) { + edata = this.trigger('subMenu', { originalEvent: event, target: overlay.name, + overlay, item, index, parentIndex, el: $item[0] }) + if (edata.isCancelled === true) { + return + } + keepOpen = true + if ($item.hasClass('expanded')) { + item.expanded = false + $item.removeClass('expanded').addClass('collapsed') + query($item.get(0).nextElementSibling).hide() + overlay.selected = parseInt($item.attr('index')) + } else { + item.expanded = true + $item.addClass('expanded').removeClass('collapsed') + query($item.get(0).nextElementSibling).show() + overlay.selected = parseInt($item.attr('index')) + } + } else { + // find items that are selected + let selected = this.findChecked(options.items) + overlay.selected = parseInt($item.attr('index')) + edata = this.trigger('select', { originalEvent: event, target: overlay.name, + overlay, item, index, parentIndex, selected, keepOpen, el: $item[0] }) + if (edata.isCancelled === true) { + return + } + if (item.keepOpen != null) { + keepOpen = item.keepOpen + } + if (['INPUT', 'TEXTAREA'].includes(overlay.anchor.tagName)) { + overlay.anchor.dataset.selected = item.id + overlay.anchor.dataset.selectedIndex = overlay.selected + } + } + if (!keepOpen) { + this.hide(overlay.name) + } + // if (['INPUT', 'TEXTAREA'].includes(overlay.anchor.tagName)) { + // overlay.anchor.focus() + // } + // event after + edata.finish() + } + findChecked(items) { + let found = [] + items.forEach(item => { + if (item.checked) found.push(item) + if (Array.isArray(item.items)) { + found = found.concat(this.findChecked(item.items)) + } + }) + return found + } + keyUp(overlay, event) { + let options = overlay.options + let search = event.target.value + let filter = true + let refreshIndex = false + switch (event.keyCode) { + case 46: // delete + case 8: { // backspace + // if search empty and delete is clicked, do not filter nor show overlay + if (search === '' && !overlay.displayed) filter = false + break + } + case 13: { // enter + if (!overlay.displayed || !overlay.selected) return + let { index, parents } = this.getCurrent(overlay.name) + event.delegate = query(overlay.box).find('.w2ui-selected').get(0) + // reset active chain for folders + this.menuClick(overlay, event, parseInt(index), parents) + filter = false + break + } + case 27: { // escape + filter = false + if (overlay.displayed) { + this.hide(overlay.name) + } else { + // clear selected + let el = overlay.anchor + if (['INPUT', 'TEXTAREA'].includes(el.tagName)) { + el.value = '' + delete el.dataset.selected + delete el.dataset.selectedIndex + } + } + break + } + case 37: { // left + if (!overlay.displayed) return + let { item, index, parents } = this.getCurrent(overlay.name) + // collapse parent if any + if (parents) { + item = options.items[parents] + index = parseInt(parents) + parents = '' + refreshIndex = true + } + if (Array.isArray(item?.items) && item.items.length > 0 && item.expanded) { + event.delegate = query(overlay.box).find(`.w2ui-menu-item[index="${index}"]`).get(0) + overlay.selected = index + this.menuClick(overlay, event, parseInt(index), parents) + } + filter = false + break + } + case 39: { // right + if (!overlay.displayed) return + let { item, index, parents } = this.getCurrent(overlay.name) + if (Array.isArray(item?.items) && item.items.length > 0 && !item.expanded) { + event.delegate = query(overlay.box).find('.w2ui-selected').get(0) + this.menuClick(overlay, event, parseInt(index), parents) + } + filter = false + break + } + case 38: { // up + if (!overlay.displayed) { + break + } + let chain = this.getActiveChain(overlay.name) + if (overlay.selected == null || overlay.selected?.length == 0) { + overlay.selected = chain[chain.length-1] + } else { + let ind = chain.indexOf(overlay.selected) + // selected not in chain of items + if (ind == -1) { + overlay.selected = chain[chain.length-1] + } + // not first item + if (ind > 0) { + overlay.selected = chain[ind - 1] + } + } + filter = false + refreshIndex = true + event.preventDefault() + break + } + case 40: { // down + if (!overlay.displayed) { + break + } + let chain = this.getActiveChain(overlay.name) + if (overlay.selected == null || overlay.selected?.length == 0) { + overlay.selected = chain[0] + } else { + let ind = chain.indexOf(overlay.selected) + // selected not in chain of items + if (ind == -1) { + overlay.selected = chain[0] + } + // not the last item + if (ind < chain.length - 1) { + overlay.selected = chain[ind + 1] + } + } + filter = false + refreshIndex = true + event.preventDefault() + break + } + } + // filter + if (filter && overlay.displayed + && ((options.filter && event._searchType == 'filter') || (options.search && event._searchType == 'search'))) { + this.applyFilter(overlay.name, null, search, true) + .then(data => { + overlay.tmp.searchCount = data.count + overlay.tmp.search = data.search + // if selected is not in searched items + if (data.count === 0 || !this.getActiveChain(overlay.name).includes(overlay.selected)) { + overlay.selected = null + } + this.refreshSearch(overlay.name) + }) + } + if (refreshIndex) { + this.refreshIndex(overlay.name) + } + } +} +class DateTooltip extends Tooltip { + constructor() { + super() + let td = new Date() + this.daysCount = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] + this.today = td.getFullYear() + '/' + (Number(td.getMonth()) + 1) + '/' + td.getDate() + this.defaults = w2utils.extend({}, this.defaults, { + position : 'top|bottom', + class : 'w2ui-calendar', + type : 'date', // can be date/time/datetime + format : '', + value : '', // initial date (in w2utils.settings format) + start : null, + end : null, + blockDates : [], // array of blocked dates + blockWeekdays : [], // blocked weekdays 0 - sunday, 1 - monday, etc + colored : {}, // ex: { '3/13/2022': 'bg-color|text-color' } + arrowSize : 12, + autoResize : false, + anchorClass : 'w2ui-focus', + autoShowOn : 'focus', + hideOn : ['doc-click', 'focus-change'], + onSelect : null + }) + } + attach(anchor, text) { + let options + if (arguments.length == 1 && anchor.anchor) { + options = anchor + anchor = options.anchor + } else if (arguments.length === 2 && text != null && typeof text === 'object') { + options = text + options.anchor = anchor + } + let prevHideOn = options.hideOn + options = w2utils.extend({}, this.defaults, options || {}) + if (prevHideOn) { + options.hideOn = prevHideOn + } + if (!options.format) { + let df = w2utils.settings.dateFormat + let tf = w2utils.settings.timeFormat + if (options.type == 'date') { + options.format = df + } else if (options.type == 'time') { + options.format = tf + } else { + options.format = df + '|' + tf + } + } + let cal = options.type == 'time' ? this.getHourHTML(options) : this.getMonthHTML(options) + options.style += '; padding: 0;' + options.html = cal.html + let ret = super.attach(options) + let overlay = ret.overlay + Object.assign(overlay.tmp, cal) + overlay.on('show.attach', event => { + let overlay = event.detail.overlay + let anchor = overlay.anchor + let options = overlay.options + if (['INPUT', 'TEXTAREA'].includes(anchor.tagName) && !options.value && anchor.value) { + overlay.tmp.initValue = anchor.value + } + delete overlay.newValue + delete overlay.newDate + }) + overlay.on('show:after.attach', event => { + if (ret.overlay?.box) { + this.initControls(ret.overlay) + } + }) + overlay.on('update:after.attach', event => { + if (ret.overlay?.box) { + this.initControls(ret.overlay) + } + }) + overlay.on('hide.attach', event => { + let overlay = event.detail.overlay + let anchor = overlay.anchor + if (overlay.newValue != null) { + if (overlay.newDate) { + overlay.newValue = overlay.newDate + ' ' + overlay.newValue + } + if (['INPUT', 'TEXTAREA'].includes(anchor.tagName) && anchor.value != overlay.newValue) { + anchor.value = overlay.newValue + } + let edata = this.trigger('select', { date: overlay.newValue, target: overlay.name, overlay }) + if (edata.isCancelled === true) return + // event after + edata.finish() + } + }) + ret.select = (callback) => { + overlay.on('select.attach', (event) => { callback(event) }) + return ret + } + return ret + } + initControls(overlay) { + let options = overlay.options + let moveMonth = (inc) => { + let { month, year } = overlay.tmp + month += inc + if (month > 12) { + month = 1 + year++ + } + if (month < 1 ) { + month = 12 + year-- + } + let cal = this.getMonthHTML(options, month, year) + Object.assign(overlay.tmp, cal) + query(overlay.box).find('.w2ui-overlay-body').html(cal.html) + this.initControls(overlay) + } + let checkJump = (event, dblclick) => { + query(event.target).parent().find('.w2ui-jump-month, .w2ui-jump-year') + .removeClass('w2ui-selected') + query(event.target).addClass('w2ui-selected') + let dt = new Date() + let { jumpMonth, jumpYear } = overlay.tmp + if (dblclick) { + if (jumpYear == null) jumpYear = dt.getFullYear() + if (jumpMonth == null) jumpMonth = dt.getMonth() + 1 + } + if (jumpMonth && jumpYear) { + let cal = this.getMonthHTML(options, jumpMonth, jumpYear) + Object.assign(overlay.tmp, cal) + query(overlay.box).find('.w2ui-overlay-body').html(cal.html) + overlay.tmp.jump = false + this.initControls(overlay) + } + } + // events for next/prev buttons and title + query(overlay.box).find('.w2ui-cal-title') + .off('.calendar') + // click on title + .on('click.calendar', event => { + Object.assign(overlay.tmp, { jumpYear: null, jumpMonth: null }) + if (overlay.tmp.jump) { + let { month, year } = overlay.tmp + let cal = this.getMonthHTML(options, month, year) + query(overlay.box).find('.w2ui-overlay-body').html(cal.html) + overlay.tmp.jump = false + } else { + query(overlay.box).find('.w2ui-overlay-body .w2ui-cal-days') + .replace(this.getYearHTML()) + let el = query(overlay.box).find(`[name="${overlay.tmp.year}"]`).get(0) + if (el) el.scrollIntoView(true) + overlay.tmp.jump = true + } + this.initControls(overlay) + event.stopPropagation() + }) + // prev button + .find('.w2ui-cal-previous') + .off('.calendar') + .on('click.calendar', event => { + moveMonth(-1) + event.stopPropagation() + }) + .parent() + // next button + .find('.w2ui-cal-next') + .off('.calendar') + .on('click.calendar', event => { + moveMonth(1) + event.stopPropagation() + }) + // now button + query(overlay.box).find('.w2ui-cal-now') + .off('.calendar') + .on('click.calendar', event => { + if (options.type == 'datetime') { + if (overlay.newDate) { + overlay.newValue = w2utils.formatTime(new Date(), options.format.split('|')[1]) + } else { + overlay.newValue = w2utils.formatDateTime(new Date(), options.format) + } + } else if (options.type == 'date') { + overlay.newValue = w2utils.formatDate(new Date(), options.format) + } else if (options.type == 'time') { + overlay.newValue = w2utils.formatTime(new Date(), options.format) + } + this.hide(overlay.name) + }) + // events for dates + query(overlay.box) + .off('.calendar') + .on('click.calendar', { delegate: '.w2ui-day.w2ui-date' }, event => { + if (options.type == 'datetime') { + overlay.newDate = query(event.target).attr('date') + query(overlay.box).find('.w2ui-overlay-body').html(this.getHourHTML(overlay.options).html) + this.initControls(overlay) + } else { + overlay.newValue = query(event.target).attr('date') + this.hide(overlay.name) + } + }) + // click on month + .on('click.calendar', { delegate: '.w2ui-jump-month' }, event => { + overlay.tmp.jumpMonth = parseInt(query(event.target).attr('name')) + checkJump(event) + }) + // double click on month + .on('dblclick.calendar', { delegate: '.w2ui-jump-month' }, event => { + overlay.tmp.jumpMonth = parseInt(query(event.target).attr('name')) + checkJump(event, true) + }) + // click on year + .on('click.calendar', { delegate: '.w2ui-jump-year' }, event => { + overlay.tmp.jumpYear = parseInt(query(event.target).attr('name')) + checkJump(event) + }) + // dbl click on year + .on('dblclick.calendar', { delegate: '.w2ui-jump-year' }, event => { + overlay.tmp.jumpYear = parseInt(query(event.target).attr('name')) + checkJump(event, true) + }) + // click on hour + .on('click.calendar', { delegate: '.w2ui-time.hour' }, event => { + let hour = query(event.target).attr('hour') + let min = this.str2min(options.value) % 60 + if (overlay.tmp.initValue && !options.value) { + min = this.str2min(overlay.tmp.initValue) % 60 + } + if (options.noMinutes) { + overlay.newValue = this.min2str(hour * 60, options.format) + this.hide(overlay.name) + } else { + overlay.newValue = hour + ':' + min + let html = this.getMinHTML(hour, options).html + query(overlay.box).find('.w2ui-overlay-body').html(html) + this.initControls(overlay) + } + }) + // click on minute + .on('click.calendar', { delegate: '.w2ui-time.min' }, event => { + let hour = Math.floor(this.str2min(overlay.newValue) / 60) + let time = (hour * 60) + parseInt(query(event.target).attr('min')) + overlay.newValue = this.min2str(time, options.format) + this.hide(overlay.name) + }) + } + getMonthHTML(options, month, year) { + let days = w2utils.settings.fulldays.slice() // creates copy of the array + let sdays = w2utils.settings.shortdays.slice() // creates copy of the array + if (w2utils.settings.weekStarts !== 'M') { + days.unshift(days.pop()) + sdays.unshift(sdays.pop()) + } + let td = new Date() + let dayLengthMil = 1000 * 60 * 60 * 24 + let selected = options.type === 'datetime' + ? w2utils.isDateTime(options.value, options.format, true) + : w2utils.isDate(options.value, options.format, true) + let selected_dsp = w2utils.formatDate(selected) + // normalize date + if (month == null || year == null) { + year = selected ? selected.getFullYear() : td.getFullYear() + month = selected ? selected.getMonth() + 1 : td.getMonth() + 1 + } + if (month > 12) { month -= 12; year++ } + if (month < 1 || month === 0) { month += 12; year-- } + if (year/4 == Math.floor(year/4)) { this.daysCount[1] = 29 } else { this.daysCount[1] = 28 } + options.current = month + '/' + year + // start with the required date + td = new Date(year, month-1, 1) + let weekDay = td.getDay() + let weekDays = '' + let st = w2utils.settings.weekStarts + for (let i = 0; i < sdays.length; i++) { + let isSat = (st == 'M' && i == 5) || (st != 'M' && i == 6) ? true : false + let isSun = (st == 'M' && i == 6) || (st != 'M' && i == 0) ? true : false + weekDays += `
    ${sdays[i]}
    ` + } + let html = ` +
    +
    +
    +
    +
    +
    +
    + ${w2utils.settings.fullmonths[month-1]}, ${year} + +
    +
    + ${weekDays} + ` + let DT = new Date(`${year}/${month}/1`) // first of month + /** + * Move to noon, instead of midnight. If not, then the date when time saving happens + * will be duplicated in the calendar + */ + DT = new Date(DT.getTime() + dayLengthMil * 0.5) + let weekday = DT.getDay() + if (w2utils.settings.weekStarts == 'M') weekDay-- + if (weekday > 0) { + DT = new Date(DT.getTime() - (weekDay * dayLengthMil)) + } + for (let ci = 0; ci < 42; ci++) { + let className = [] + let dt = `${DT.getFullYear()}/${DT.getMonth()+1}/${DT.getDate()}` + if (DT.getDay() === 6) className.push('w2ui-saturday') + if (DT.getDay() === 0) className.push('w2ui-sunday') + if (DT.getMonth() + 1 !== month) className.push('outside') + if (dt == this.today) className.push('w2ui-today') + let dspDay = DT.getDate() + let col = '' + let bgcol = '' + let tmp_dt, tmp_dt_fmt + if (options.type === 'datetime') { + tmp_dt = w2utils.formatDateTime(dt, options.format) + tmp_dt_fmt = w2utils.formatDate(dt, w2utils.settings.dateFormat) + } else { + tmp_dt = w2utils.formatDate(dt, options.format) + tmp_dt_fmt = tmp_dt + } + if (options.colored && options.colored[tmp_dt_fmt] !== undefined) { // if there is predefined colors for dates + let tmp = options.colored[tmp_dt_fmt].split('|') + bgcol = 'background-color: ' + tmp[0] + ';' + col = 'color: ' + tmp[1] + ';' + } + html += `
    + ${dspDay} +
    ` + DT = new Date(DT.getTime() + dayLengthMil) + } + html += '
    ' + if (options.btnNow) { + let label = w2utils.lang('Today' + (options.type == 'datetime' ? ' & Now' : '')) + html += `
    ${label}
    ` + } + return { html, month, year } + } + getYearHTML() { + let mhtml = '' + let yhtml = '' + for (let m = 0; m < w2utils.settings.fullmonths.length; m++) { + mhtml += `
    ${w2utils.settings.shortmonths[m]}
    ` + } + for (let y = w2utils.settings.dateStartYear; y <= w2utils.settings.dateEndYear; y++) { + yhtml += `
    ${y}
    ` + } + return `
    +
    ${mhtml}
    +
    ${yhtml}
    +
    ` + } + getHourHTML(options) { + options = options ?? {} + if (!options.format) options.format = w2utils.settings.timeFormat + let h24 = (options.format.indexOf('h24') > -1) + let value = options.value ? options.value : (options.anchor ? options.anchor.value : '') + let tmp = [] + for (let a = 0; a < 24; a++) { + let time = (a >= 12 && !h24 ? a - 12 : a) + ':00' + (!h24 ? (a < 12 ? ' am' : ' pm') : '') + if (a == 12 && !h24) time = '12:00 pm' + if (!tmp[Math.floor(a/8)]) tmp[Math.floor(a/8)] = '' + let tm1 = this.min2str(this.str2min(time)) + let tm2 = this.min2str(this.str2min(time) + 59) + if (options.type === 'datetime') { + let dt = w2utils.isDateTime(value, options.format, true) + let fm = options.format.split('|')[0].trim() + tm1 = w2utils.formatDate(dt, fm) + ' ' + tm1 + tm2 = w2utils.formatDate(dt, fm) + ' ' + tm2 + } + let valid = this.inRange(tm1, options) || this.inRange(tm2, options) + tmp[Math.floor(a/8)] += `${time}` + } + let html = `
    +
    ${w2utils.lang('Select Hour')}
    +
    +
    ${tmp[0]}
    +
    ${tmp[1]}
    +
    ${tmp[2]}
    +
    + ${options.btnNow ? `
    ${w2utils.lang('Now')}
    ` : '' } +
    ` + return { html } + } + getMinHTML(hour, options) { + if (hour == null) hour = 0 + options = options ?? {} + if (!options.format) options.format = w2utils.settings.timeFormat + let h24 = (options.format.indexOf('h24') > -1) + let value = options.value ? options.value : (options.anchor ? options.anchor.value : '') + let tmp = [] + for (let a = 0; a < 60; a += 5) { + let time = (hour > 12 && !h24 ? hour - 12 : hour) + ':' + (a < 10 ? 0 : '') + a + ' ' + (!h24 ? (hour < 12 ? 'am' : 'pm') : '') + let tm = time + let ind = a < 20 ? 0 : (a < 40 ? 1 : 2) + if (!tmp[ind]) tmp[ind] = '' + if (options.type === 'datetime') { + let dt = w2utils.isDateTime(value, options.format, true) + let fm = options.format.split('|')[0].trim() + tm = w2utils.formatDate(dt, fm) + ' ' + tm + } + tmp[ind] += `${time}` + } + let html = `
    +
    ${w2utils.lang('Select Minute')}
    +
    +
    ${tmp[0]}
    +
    ${tmp[1]}
    +
    ${tmp[2]}
    +
    + ${options.btnNow ? `
    ${w2utils.lang('Now')}
    ` : '' } +
    ` + return { html } + } + // checks if date is in range (loost at start, end, blockDates, blockWeekdays) + inRange(str, options, dateOnly) { + let inRange = false + if (options.type === 'date') { + let dt = w2utils.isDate(str, options.format, true) + if (dt) { + // enable range + if (options.start || options.end) { + let st = (typeof options.start === 'string' ? options.start : query(options.start).val()) + let en = (typeof options.end === 'string' ? options.end : query(options.end).val()) + let start = w2utils.isDate(st, options.format, true) + let end = w2utils.isDate(en, options.format, true) + let current = new Date(dt) + if (!start) start = current + if (!end) end = current + if (current >= start && current <= end) inRange = true + } else { + inRange = true + } + // block predefined dates + if (Array.isArray(options.blockDates) && options.blockDates.includes(str)) inRange = false + // block weekdays + if (Array.isArray(options.blockWeekdays) && options.blockWeekdays.includes(dt.getDay())) inRange = false + } + } else if (options.type === 'time') { + if (options.start || options.end) { + let tm = this.str2min(str) + let tm1 = this.str2min(options.start) + let tm2 = this.str2min(options.end) + if (!tm1) tm1 = tm + if (!tm2) tm2 = tm + if (tm >= tm1 && tm <= tm2) inRange = true + } else { + inRange = true + } + } else if (options.type === 'datetime') { + let dt = w2utils.isDateTime(str, options.format, true) + if (dt) { + let format = options.format.split('|').map(format => format.trim()) + if (dateOnly) { + let date = w2utils.formatDate(dt, format[0]) + let opts = w2utils.extend({}, options, { type: 'date', format: format[0] }) + if (this.inRange(date, opts)) inRange = true + } else { + let time = w2utils.formatTime(dt, format[1]) + let opts = { type: 'time', format: format[1], start: options.startTime, end: options.endTime } + if (this.inRange(time, opts)) inRange = true + } + } + } + return inRange + } + // converts time into number of minutes since midnight -- '11:50am' => 710 + str2min(str) { + if (typeof str !== 'string') return null + let tmp = str.split(':') + if (tmp.length === 2) { + tmp[0] = parseInt(tmp[0]) + tmp[1] = parseInt(tmp[1]) + if (str.indexOf('pm') !== -1 && tmp[0] !== 12) tmp[0] += 12 + if (str.includes('am') && tmp[0] == 12) tmp[0] = 0 // 12:00am - is midnight + } else { + return null + } + return tmp[0] * 60 + tmp[1] + } + // converts minutes since midnight into time str -- 710 => '11:50am' + min2str(time, format) { + let ret = '' + if (time >= 24 * 60) time = time % (24 * 60) + if (time < 0) time = 24 * 60 + time + let hour = Math.floor(time/60) + let min = ((time % 60) < 10 ? '0' : '') + (time % 60) + if (!format) { format = w2utils.settings.timeFormat} + if (format.indexOf('h24') !== -1) { + ret = hour + ':' + min + } else { + ret = (hour <= 12 ? hour : hour - 12) + ':' + min + ' ' + (hour >= 12 ? 'pm' : 'am') + } + return ret + } +} +let w2tooltip = new Tooltip() +let w2menu = new MenuTooltip() +let w2color = new ColorTooltip() +let w2date = new DateTooltip() +/** + * Part of w2ui 2.0 library + * - Dependencies: mQuery, w2utils, w2base, w2tooltip, w2color, w2menu + * + * == TODO == + * - tab navigation (index state) + * - vertical toolbar + * - w2menu on second click of tb button should hide + * - button display groups for each show/hide, possibly add state: { single: t/f, multiple: t/f, type: 'font' } + * - item.count - should just support html, so a custom block can be created, such as a colored line + * + * == 2.0 changes + * - CSP - fixed inline events + * - removed jQuery dependency + * - item.icon - can be class or or + * - new w2tooltips and w2menu + * - scroll returns promise + * - added onMouseEntter, onMouseLeave, onMouseDown, onMouseUp events + * - add(..., skipRefresh), insert(..., skipRefresh) + */ + +class w2toolbar extends w2base { + constructor(options) { + super(options.name) + this.box = null // DOM Element that holds the element + this.name = null // unique name for w2ui + this.routeData = {} // data for dynamic routes + this.items = [] + this.right = '' // HTML text on the right of toolbar + this.tooltip = 'top|left'// can be top, bottom, left, right + this.onClick = null + this.onMouseDown = null + this.onMouseUp = null + this.onMouseEnter = null // mouse enter the button event + this.onMouseLeave = null + this.onRender = null + this.onRefresh = null + this.onResize = null + this.onDestroy = null + this.item_template = { + id: null, // command to be sent to all event handlers + type: 'button', // button, check, radio, drop, menu, menu-radio, menu-check, break, html, spacer + text: null, + html: '', + tooltip: null, // w2toolbar.tooltip should be + count: null, + hidden: false, + disabled: false, + checked: false, // used for radio buttons + icon: null, + route: null, // if not null, it is route to go + arrow: null, // arrow down for drop/menu types + style: null, // extra css style for caption + group: null, // used for radio buttons + items: null, // for type menu* it is an array of items in the menu + selected: null, // used for menu-check, menu-radio + color: null, // color value - used in color pickers + overlay: { // additional options for overlay + anchorClass: '' + }, + onClick: null, + onRefresh: null + } + this.last = { + badge: {} + } + // mix in options, w/o items + let items = options.items + delete options.items + Object.assign(this, options) + // add item via method to makes sure item_template is applied + if (Array.isArray(items)) this.add(items, true) + // need to reassign back to keep it in config + options.items = items + // render if box specified + if (typeof this.box == 'string') this.box = query(this.box).get(0) + if (this.box) this.render(this.box) + } + add(items, skipRefresh) { + this.insert(null, items, skipRefresh) + } + insert(id, items, skipRefresh) { + if (!Array.isArray(items)) items = [items] + items.forEach((item, idx, arr) => { + if (typeof item === 'string') { + item = arr[idx] = { id: item, text: item } + } + // checks + let valid = ['button', 'check', 'radio', 'drop', 'menu', 'menu-radio', 'menu-check', 'color', 'text-color', 'html', + 'break', 'spacer', 'new-line'] + if (!valid.includes(String(item.type))) { + console.log('ERROR: The parameter "type" should be one of the following:', valid, `, but ${item.type} is supplied.`, item) + return + } + if (item.id == null && !['break', 'spacer', 'new-line'].includes(item.type)) { + console.log('ERROR: The parameter "id" is required but not supplied.', item) + return + } + if (item.type == null) { + console.log('ERROR: The parameter "type" is required but not supplied.', item) + return + } + if (!w2utils.checkUniqueId(item.id, this.items, 'toolbar', this.name)) return + // add item + let newItem = w2utils.extend({}, this.item_template, item) + if (newItem.type == 'menu-check') { + if (!Array.isArray(newItem.selected)) newItem.selected = [] + if (Array.isArray(newItem.items)) { + newItem.items.forEach(it => { + if (typeof it === 'string') { + it = arr[idx] = { id: it, text: it } + } + if (it.checked && !newItem.selected.includes(it.id)) newItem.selected.push(it.id) + if (!it.checked && newItem.selected.includes(it.id)) it.checked = true + if (it.checked == null) it.checked = false + }) + } + } else if (newItem.type == 'menu-radio') { + if (Array.isArray(newItem.items)) { + newItem.items.forEach((it, idx, arr) => { + if (typeof it === 'string') { + it = arr[idx] = { id: it, text: it } + } + if (it.checked && newItem.selected == null) newItem.selected = it.id; else it.checked = false + if (!it.checked && newItem.selected == it.id) it.checked = true + if (it.checked == null) it.checked = false + }) + } + } + if (id == null) { + this.items.push(newItem) + } else { + let middle = this.get(id, true) + this.items = this.items.slice(0, middle).concat([newItem], this.items.slice(middle)) + } + newItem.line = newItem.line ?? 1 + if (skipRefresh !== true) this.refresh(newItem.id) + }) + if (skipRefresh !== true) this.resize() + } + remove() { + let effected = 0 + Array.from(arguments).forEach(item => { + let it = this.get(item) + if (!it || String(item).indexOf(':') != -1) return + effected++ + // remove from screen + query(this.box).find('#tb_'+ this.name +'_item_'+ w2utils.escapeId(it.id)).remove() + // remove from array + let ind = this.get(it.id, true) + if (ind != null) this.items.splice(ind, 1) + }) + this.resize() + return effected + } + set(id, newOptions) { + let item = this.get(id) + if (item == null) return false + Object.assign(item, newOptions) + this.refresh(String(id).split(':')[0]) + return true + } + get(id, returnIndex) { + if (arguments.length === 0) { + let all = [] + for (let i1 = 0; i1 < this.items.length; i1++) if (this.items[i1].id != null) all.push(this.items[i1].id) + return all + } + let tmp = String(id).split(':') + for (let i2 = 0; i2 < this.items.length; i2++) { + let it = this.items[i2] + // find a menu item + if (['menu', 'menu-radio', 'menu-check'].includes(it.type) && tmp.length == 2 && it.id == tmp[0]) { + let subItems = it.items + if (typeof subItems == 'function') subItems = subItems(this) + for (let i = 0; i < subItems.length; i++) { + let item = subItems[i] + if (item.id == tmp[1] || (item.id == null && item.text == tmp[1])) { + if (returnIndex == true) return i; else return item + } + if (Array.isArray(item.items)) { + for (let j = 0; j < item.items.length; j++) { + if (item.items[j].id == tmp[1] || (item.items[j].id == null && item.items[j].text == tmp[1])) { + if (returnIndex == true) return i; else return item.items[j] + } + } + } + } + } else if (it.id == tmp[0]) { + if (returnIndex == true) return i2; else return it + } + } + return null + } + setCount(id, count, className, style) { + let btn = query(this.box).find(`#tb_${this.name}_item_${w2utils.escapeId(id)} .w2ui-tb-count > span`) + if (btn.length > 0) { + btn.removeClass() + .addClass(className ?? '') + .text(count) + .get(0).style.cssText = style ?? '' + this.last.badge[id] = { + className: className ?? '', + style: style ?? '' + } + let item = this.get(id) + item.count = count + } else { + this.set(id, { count: count }) + this.setCount(...arguments) // to update styles + } + } + show() { + let effected = [] + Array.from(arguments).forEach(item => { + let it = this.get(item) + if (!it) return + it.hidden = false + effected.push(String(item).split(':')[0]) + }) + setTimeout(() => { effected.forEach(it => { this.refresh(it); this.resize() }) }, 15) // needs timeout + return effected + } + hide() { + let effected = [] + Array.from(arguments).forEach(item => { + let it = this.get(item) + if (!it) return + it.hidden = true + effected.push(String(item).split(':')[0]) + }) + setTimeout(() => { effected.forEach(it => { this.refresh(it); this.tooltipHide(it); this.resize() }) }, 15) // needs timeout + return effected + } + enable() { + let effected = [] + Array.from(arguments).forEach(item => { + let it = this.get(item) + if (!it) return + it.disabled = false + effected.push(String(item).split(':')[0]) + }) + setTimeout(() => { effected.forEach(it => { this.refresh(it) }) }, 15) // needs timeout + return effected + } + disable() { + let effected = [] + Array.from(arguments).forEach(item => { + let it = this.get(item) + if (!it) return + it.disabled = true + effected.push(String(item).split(':')[0]) + }) + setTimeout(() => { effected.forEach(it => { this.refresh(it); this.tooltipHide(it) }) }, 15) // needs timeout + return effected + } + check() { + let effected = [] + Array.from(arguments).forEach(item => { + let it = this.get(item) + if (!it || String(item).indexOf(':') != -1) return + it.checked = true + effected.push(String(item).split(':')[0]) + }) + setTimeout(() => { effected.forEach(it => { this.refresh(it) }) }, 15) // needs timeout + return effected + } + uncheck() { + let effected = [] + Array.from(arguments).forEach(item => { + let it = this.get(item) + if (!it || String(item).indexOf(':') != -1) return + // remove overlay + if (['menu', 'menu-radio', 'menu-check', 'drop', 'color', 'text-color'].includes(it.type) && it.checked) { + w2tooltip.hide(this.name + '-drop') + } + it.checked = false + effected.push(String(item).split(':')[0]) + }) + setTimeout(() => { effected.forEach(it => { this.refresh(it) }) }, 15) // needs timeout + return effected + } + click(id, event) { + // click on menu items + let tmp = String(id).split(':') + let it = this.get(tmp[0]) + let items = (it && it.items ? w2utils.normMenu.call(this, it.items, it) : []) + if (tmp.length > 1) { + let subItem = this.get(id) + if (subItem && !subItem.disabled) { + this.menuClick({ name: this.name, item: it, subItem: subItem, originalEvent: event }) + } + return + } + if (it && !it.disabled) { + // event before + let edata = this.trigger('click', { + target: (id != null ? id : this.name), + item: it, object: it, originalEvent: event + }) + if (edata.isCancelled === true) return + // read items again, they might have been changed in the click event handler + items = (it && it.items ? w2utils.normMenu.call(this, it.items, it) : []) + let btn = '#tb_'+ this.name +'_item_'+ w2utils.escapeId(it.id) + query(this.box).find(btn).removeClass('down') // need to re-query at the moment -- as well as elsewhere in this function + if (it.type == 'radio') { + for (let i = 0; i < this.items.length; i++) { + let itt = this.items[i] + if (itt == null || itt.id == it.id || itt.type !== 'radio') continue + if (itt.group == it.group && itt.checked) { + itt.checked = false + this.refresh(itt.id) + } + } + it.checked = true + query(this.box).find(btn).addClass('checked') + } + if (['menu', 'menu-radio', 'menu-check', 'drop', 'color', 'text-color'].includes(it.type)) { + this.tooltipHide(id) + if (it.checked) { + w2tooltip.hide(this.name + '-drop') + return + } else { + // timeout is needed to make sure previous overlay hides + setTimeout(() => { + let hideDrop = (id, btn) => { + // need a closure to capture id variable + let self = this + return function () { + self.set(id, { checked: false }) + } + } + let el = query(this.box).find('#tb_'+ this.name +'_item_'+ w2utils.escapeId(it.id)) + if (!w2utils.isPlainObject(it.overlay)) it.overlay = {} + if (it.type == 'drop') { + w2tooltip.show(w2utils.extend({ + html: it.html, + class: 'w2ui-white', + hideOn: ['doc-click'] + }, it.overlay, { + anchor: el[0], + name: this.name + '-drop', + data: { item: it, btn } + })) + .hide(hideDrop(it.id, btn)) + } + if (['menu', 'menu-radio', 'menu-check'].includes(it.type)) { + let menuType = 'normal' + if (it.type == 'menu-radio') { + menuType = 'radio' + items.forEach((item) => { + if (it.selected == item.id) item.checked = true; else item.checked = false + }) + } + if (it.type == 'menu-check') { + menuType = 'check' + items.forEach((item) => { + if (Array.isArray(it.selected) && it.selected.includes(item.id)) item.checked = true; else item.checked = false + }) + } + w2menu.show(w2utils.extend({ + items, + }, it.overlay, { + type: menuType, + name : this.name + '-drop', + anchor: el[0], + data: { item: it, btn } + })) + .hide(hideDrop(it.id, btn)) + .remove(event => { + this.menuClick({ name: this.name, remove: true, item: it, subItem: event.detail.item, + originalEvent: event }) + }) + .select(event => { + this.menuClick({ name: this.name, item: it, subItem: event.detail.item, + originalEvent: event }) + }) + } + if (['color', 'text-color'].includes(it.type)) { + w2color.show(w2utils.extend({ + color: it.color + }, it.overlay, { + anchor: el[0], + name: this.name + '-drop', + data: { item: it, btn } + })) + .hide(hideDrop(it.id, btn)) + .select(event => { + if (event.detail.color != null) { + this.colorClick({ name: this.name, item: it, color: event.detail.color }) + } + }) + } + }, 0) + } + } + if (['check', 'menu', 'menu-radio', 'menu-check', 'drop', 'color', 'text-color'].includes(it.type)) { + it.checked = !it.checked + if (it.checked) { + query(this.box).find(btn).addClass('checked') + } else { + query(this.box).find(btn).removeClass('checked') + } + } + // route processing + if (it.route) { + let route = String('/'+ it.route).replace(/\/{2,}/g, '/') + let info = w2utils.parseRoute(route) + if (info.keys.length > 0) { + for (let k = 0; k < info.keys.length; k++) { + route = route.replace((new RegExp(':'+ info.keys[k].name, 'g')), this.routeData[info.keys[k].name]) + } + } + setTimeout(() => { window.location.hash = route }, 1) + } + // need to refresh toolbar as it might be dynamic + this.tooltipShow(id) + // event after + edata.finish() + } + } + scroll(direction, line, instant) { + return new Promise((resolve, reject) => { + let scrollBox = query(this.box).find(`.w2ui-tb-line:nth-child(${line}) .w2ui-scroll-wrapper`) + let scrollLeft = scrollBox.get(0).scrollLeft + let right = scrollBox.find('.w2ui-tb-right').get(0) + let width1 = scrollBox.parent().get(0).getBoundingClientRect().width + let width2 = scrollLeft + parseInt(right.offsetLeft) + parseInt(right.clientWidth ) + switch (direction) { + case 'left': { + scroll = scrollLeft - width1 + 50 // 35 is width of both button + if (scroll <= 0) scroll = 0 + scrollBox.get(0).scrollTo({ top: 0, left: scroll, behavior: instant ? 'atuo' : 'smooth' }) + break + } + case 'right': { + scroll = scrollLeft + width1 - 50 // 35 is width of both button + if (scroll >= width2 - width1) scroll = width2 - width1 + scrollBox.get(0).scrollTo({ top: 0, left: scroll, behavior: instant ? 'atuo' : 'smooth' }) + break + } + } + setTimeout(() => { this.resize(); resolve() }, instant ? 0 : 500) + }) + } + render(box) { + let time = Date.now() + if (typeof box == 'string') box = query(box).get(0) + // event before + let edata = this.trigger('render', { target: this.name, box: box ?? this.box }) + if (edata.isCancelled === true) return + // defaul action + if (box != null) { + // clean previous box + if (query(this.box).find('.w2ui-scroll-wrapper .w2ui-tb-right').length > 0) { + query(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-toolbar') + .html('') + } + this.box = box + } + if (!this.box) return + if (!Array.isArray(this.right)) { + this.right = [this.right] + } + // render all buttons + let html = '' + let line = 0 + for (let i = 0; i < this.items.length; i++) { + let it = this.items[i] + if (it == null) continue + if (it.id == null) it.id = 'item_' + i + if (it.caption != null) { + console.log('NOTICE: toolbar item.caption property is deprecated, please use item.text. Item -> ', it) + } + if (it.hint != null) { + console.log('NOTICE: toolbar item.hint property is deprecated, please use item.tooltip. Item -> ', it) + } + if (i === 0 || it.type == 'new-line') { + line++ + html += ` +
    +
    +
    ${this.right[line-1] ?? ''}
    +
    +
    +
    +
    + ` + } + it.line = line + } + query(this.box) + .attr('name', this.name) + .addClass('w2ui-reset w2ui-toolbar') + .html(html) + if (query(this.box).length > 0) { + query(this.box)[0].style.cssText += this.style + } + w2utils.bindEvents(query(this.box).find('.w2ui-tb-line .w2ui-eaction'), this) + // observe div resize + this.last.observeResize = new ResizeObserver(() => { this.resize() }) + this.last.observeResize.observe(this.box) + // refresh all + this.refresh() + this.resize() + // event after + edata.finish() + return Date.now() - time + } + refresh(id) { + let time = Date.now() + // event before + let edata = this.trigger('refresh', { target: (id != null ? id : this.name), item: this.get(id) }) + if (edata.isCancelled === true) return + let edata2 + // refresh all + if (id == null) { + for (let i = 0; i < this.items.length; i++) { + let it1 = this.items[i] + if (it1.id == null) it1.id = 'item_' + i + this.refresh(it1.id) + } + return + } + // create or refresh only one item + let it = this.get(id) + if (it == null) return false + if (typeof it.onRefresh == 'function') { + edata2 = this.trigger('refresh', { target: id, item: it, object: it }) + if (edata2.isCancelled === true) return + } + let selector = `#tb_${this.name}_item_${w2utils.escapeId(it.id)}` + let btn = query(this.box).find(selector) + let html = this.getItemHTML(it) + // hide tooltip + this.tooltipHide(id) + // if there is a spacer, then right HTML is not 100% + if (it.type == 'spacer') { + query(this.box).find(`.w2ui-tb-line:nth-child(${it.line}`).find('.w2ui-tb-right').css('width', 'auto') + } + if (btn.length === 0) { + let next = parseInt(this.get(id, true)) + 1 + let $next = query(this.box).find(`#tb_${this.name}_item_${w2utils.escapeId(this.items[next] ? this.items[next].id : '')}`) + if ($next.length == 0) { + $next = query(this.box).find(`.w2ui-tb-line:nth-child(${it.line}`).find('.w2ui-tb-right').before(html) + } else { + $next.after(html) + } + w2utils.bindEvents(query(this.box).find(selector), this) + } else { + // refresh + query(this.box).find(selector).replace(query.html(html)) + let newBtn = query(this.box).find(selector).get(0) + w2utils.bindEvents(newBtn, this) + // update overlay's anchor if changed + let overlays = w2tooltip.get(true) + Object.keys(overlays).forEach(key => { + if (overlays[key].anchor == btn.get(0)) { + overlays[key].anchor = newBtn + } + }) + } + if (['menu', 'menu-radio', 'menu-check'].includes(it.type) && it.checked) { + // check selected items + let selected = Array.isArray(it.selected) ? it.selected : [it.selected] + it.items.forEach((item) => { + if (selected.includes(item.id)) item.checked = true; else item.checked = false + }) + w2menu.update(this.name + '-drop', it.items) + } + // event after + if (typeof it.onRefresh == 'function') { + edata2.finish() + } + edata.finish() + return Date.now() - time + } + resize() { + let time = Date.now() + // event before + let edata = this.trigger('resize', { target: this.name }) + if (edata.isCancelled === true) return + query(this.box).find('.w2ui-tb-line').each(el => { + // show hide overflow buttons + let box = query(el) + box.find('.w2ui-scroll-left, .w2ui-scroll-right').hide() + let scrollBox = box.find('.w2ui-scroll-wrapper').get(0) + let $right = box.find('.w2ui-tb-right') + let boxWidth = box.get(0).getBoundingClientRect().width + let itemsWidth = ($right.length > 0 ? $right[0].offsetLeft + $right[0].clientWidth : 0) + if (boxWidth < itemsWidth) { + // we have overflown content + if (scrollBox.scrollLeft > 0) { + box.find('.w2ui-scroll-left').show() + } + if (boxWidth < itemsWidth - scrollBox.scrollLeft) { + box.find('.w2ui-scroll-right').show() + } + } + }) + // event after + edata.finish() + return Date.now() - time + } + destroy() { + // event before + let edata = this.trigger('destroy', { target: this.name }) + if (edata.isCancelled === true) return + // clean up + if (query(this.box).find('.w2ui-scroll-wrapper .w2ui-tb-right').length > 0) { + query(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-toolbar') + .html('') + } + query(this.box).html('') + this.last.observeResize?.disconnect() + delete w2ui[this.name] + // event after + edata.finish() + } + // ======================================== + // --- Internal Functions + getItemHTML(item) { + let html = '' + if (item.caption != null && item.text == null) item.text = item.caption // for backward compatibility + if (item.text == null) item.text = '' + if (item.tooltip == null && item.hint != null) item.tooltip = item.hint // for backward compatibility + if (item.tooltip == null) item.tooltip = '' + if (typeof item.get !== 'function' && (Array.isArray(item.items) || typeof item.items == 'function')) { + item.get = function get(id) { // need scope, cannot be arrow func + let tmp = item.items + if (typeof tmp == 'function') tmp = item.items(item) + return tmp.find(it => it.id == id ? true : false) + } + } + let icon = '' + let text = (typeof item.text == 'function' ? item.text.call(this, item) : item.text) + if (item.icon) { + icon = item.icon + if (typeof item.icon == 'function') { + icon = item.icon.call(this, item) + } + if (String(icon).slice(0, 1) !== '<') { + icon = `` + } + icon = `
    ${icon}
    ` + } + let classes = ['w2ui-tb-button'] + if (item.checked) classes.push('checked') + if (item.disabled) classes.push('disabled') + if (item.hidden) classes.push('hidden') + if (!icon) classes.push('no-icon') + switch (item.type) { + case 'color': + case 'text-color': + if (typeof item.color == 'string') { + if (item.color.slice(0, 1) == '#') item.color = item.color.slice(1) + if ([3, 6, 8].includes(item.color.length)) item.color = '#' + item.color + } + if (item.type == 'color') { + text = ` + ${(item.text ? `
    ${w2utils.lang(item.text)}
    ` : '')}` + } + if (item.type == 'text-color') { + text = ''+ + (item.text ? w2utils.lang(item.text) : 'Aa') + + '' + } + case 'menu': + case 'menu-check': + case 'menu-radio': + case 'button': + case 'check': + case 'radio': + case 'drop': { + let arrow = (item.arrow === true + || (item.arrow !== false && ['menu', 'menu-radio', 'menu-check', 'drop', 'color', 'text-color'].includes(item.type))) + html = ` +
    + ${ icon } + ${ text != '' + ? `
    + ${ w2utils.lang(text) } + ${ item.count != null + ? w2utils.stripSpaces(` + ${item.count} + `) + : '' + } + ${ arrow + ? '' + : '' + } +
    ` + : ''} +
    + ` + break + } + case 'break': + html = `
    +   +
    ` + break + case 'spacer': + html = `
    +
    ` + break + case 'html': + html = `
    + ${(typeof item.html == 'function' ? item.html.call(this, item) : item.html)} +
    ` + break + } + return html + } + tooltipShow(id) { + if (this.tooltip == null) return + let el = query(this.box).find('#tb_'+ this.name + '_item_'+ w2utils.escapeId(id)).get(0) + let item = this.get(id) + let pos = this.tooltip + let txt = item.tooltip + if (typeof txt == 'function') txt = txt.call(this, item) + // not for opened drop downs + if (['menu', 'menu-radio', 'menu-check', 'drop', 'color', 'text-color'].includes(item.type) + && item.checked == true) { + return + } + w2tooltip.show({ + anchor: el, + name: this.name + '-tooltip', + html: txt, + position: pos + }) + return + } + tooltipHide(id) { + if (this.tooltip == null) return + w2tooltip.hide(this.name + '-tooltip') + } + menuClick(event) { + if (event.item && !event.item.disabled) { + // event before + let edata = this.trigger((event.remove !== true ? 'click' : 'remove'), { + target: event.item.id + ':' + event.subItem.id, item: event.item, + subItem: event.subItem, originalEvent: event.originalEvent + }) + if (edata.isCancelled === true) return + // route processing + let it = event.subItem + let item = this.get(event.item.id) + let items = item.items + if (typeof items == 'function') items = item.items() + if (item.type == 'menu') { + item.selected = it.id + } + if (item.type == 'menu-radio') { + item.selected = it.id + if (Array.isArray(items)) { + items.forEach((item) => { + if (item.checked === true) delete item.checked + if (Array.isArray(item.items)) { + item.items.forEach((item) => { + if (item.checked === true) delete item.checked + }) + } + }) + } + it.checked = true + } + if (item.type == 'menu-check') { + if (!Array.isArray(item.selected)) item.selected = [] + if (it.group == null) { + let ind = item.selected.indexOf(it.id) + if (ind == -1) { + item.selected.push(it.id) + it.checked = true + } else { + item.selected.splice(ind, 1) + it.checked = false + } + } else if (it.group === false) { + // if group is false, then it is not part of checkboxes + } else { + let unchecked = [] + let ind = item.selected.indexOf(it.id) + let checkNested = (items) => { + items.forEach((sub) => { + if (sub.group === it.group) { + let ind = item.selected.indexOf(sub.id) + if (ind != -1) { + if (sub.id != it.id) unchecked.push(sub.id) + item.selected.splice(ind, 1) + } + } + if (Array.isArray(sub.items)) checkNested(sub.items) + }) + } + checkNested(items) + if (ind == -1) { + item.selected.push(it.id) + it.checked = true + } + } + } + if (typeof it.route == 'string') { + let route = it.route !== '' ? String('/'+ it.route).replace(/\/{2,}/g, '/') : '' + let info = w2utils.parseRoute(route) + if (info.keys.length > 0) { + for (let k = 0; k < info.keys.length; k++) { + if (this.routeData[info.keys[k].name] == null) continue + route = route.replace((new RegExp(':'+ info.keys[k].name, 'g')), this.routeData[info.keys[k].name]) + } + } + setTimeout(() => { window.location.hash = route }, 1) + } + this.refresh(event.item.id) + // event after + edata.finish() + } + } + colorClick(event) { + let obj = this + if (event.item && !event.item.disabled) { + // event before + let edata = this.trigger('click', { + target: event.item.id, item: event.item, + color: event.color, final: event.final, originalEvent: event.originalEvent + }) + if (edata.isCancelled === true) return + // default behavior + event.item.color = event.color + obj.refresh(event.item.id) + // event after + edata.finish() + } + } + mouseAction(event, target, action, id) { + let btn = this.get(id) + let edata = this.trigger('mouse' + action, { target: id, item: btn, object: btn, originalEvent: event }) + if (edata.isCancelled === true || btn.disabled || btn.hidden) return + switch (action) { + case 'Enter': + query(target).addClass('over') + this.tooltipShow(id) + break + case 'Leave': + query(target).removeClass('over down') + this.tooltipHide(id) + break + case 'Down': + query(target).addClass('down') + break + case 'Up': + query(target).removeClass('down') + break + } + edata.finish() + } +} +/** + * Part of w2ui 2.0 library + * - Dependencies: mQuery, w2utils, w2base, w2tooltip, w2menu + * + * == TODO == + * - dbl click should be like it is in grid (with timer not HTML dbl click event) + * - node.style is misleading - should be there to apply color for example + * - node.plus - is not working + * + * == 2.0 changes + * - remove jQuery dependency + * - deprecarted obj.img, node.img + * - CSP - fixed inline events + * - observeResize for the box + * - handleTooltip and handle.tooltip - text/function + * - added onMouseEntter, onMouseLeave events + */ + +class w2sidebar extends w2base { + constructor(options) { + super(options.name) + this.name = null + this.box = null + this.sidebar = null + this.parent = null + this.nodes = [] // Sidebar child nodes + this.menu = [] + this.routeData = {} // data for dynamic routes + this.selected = null // current selected node (readonly) + this.icon = null + this.style = '' + this.topHTML = '' + this.bottomHTML = '' + this.flatButton = false + this.keyboard = true + this.flat = false + this.hasFocus = false + this.levelPadding = 12 + this.skipRefresh = false + this.tabIndex = null // will only be set if > 0 and not null + this.handle = { size: 0, style: '', html: '', tooltip: '' }, + this.onClick = null // Fire when user click on Node Text + this.onDblClick = null // Fire when user dbl clicks + this.onMouseEnter = null // mouse enter/leave over an item + this.onMouseLeave = null + this.onContextMenu = null + this.onMenuClick = null // when context menu item selected + this.onExpand = null // Fire when node expands + this.onCollapse = null // Fire when node collapses + this.onKeydown = null + this.onRender = null + this.onRefresh = null + this.onResize = null + this.onDestroy = null + this.onFocus = null + this.onBlur = null + this.onFlat = null + this.node_template = { + id: null, + text: '', + order: null, + count: null, + icon: null, + nodes: [], + style: '', // additional style for subitems + route: null, + selected: false, + expanded: false, + hidden: false, + disabled: false, + group: false, // if true, it will build as a group + groupShowHide: true, + collapsible: false, + plus: false, // if true, plus will be shown even if there is no sub nodes + // events + onClick: null, + onDblClick: null, + onContextMenu: null, + onExpand: null, + onCollapse: null, + // internal + parent: null, // node object + sidebar: null + } + this.last = { + badge: {} + } + let nodes = options.nodes + delete options.nodes + // mix in options + Object.assign(this, options) + // add item via method to makes sure item_template is applied + if (Array.isArray(nodes)) this.add(nodes) + // need to reassign back to keep it in config + options.nodes = nodes + // render if box specified + if (typeof this.box == 'string') this.box = query(this.box).get(0) + if (this.box) this.render(this.box) + } + add(parent, nodes) { + if (arguments.length == 1) { + // need to be in reverse order + nodes = arguments[0] + parent = this + } + if (typeof parent == 'string') parent = this.get(parent) + if (parent == null || parent == '') parent = this + return this.insert(parent, null, nodes) + } + insert(parent, before, nodes) { + let txt, ind, tmp, node, nd + if (arguments.length == 2 && typeof parent == 'string') { + // need to be in reverse order + nodes = arguments[1] + before = arguments[0] + if (before != null) { + ind = this.get(before) + if (ind == null) { + if (!Array.isArray(nodes)) nodes = [nodes] + if (nodes[0].caption != null && nodes[0].text == null) { + console.log('NOTICE: sidebar node.caption property is deprecated, please use node.text. Node -> ', nodes[0]) + nodes[0].text = nodes[0].caption + } + txt = nodes[0].text + console.log('ERROR: Cannot insert node "'+ txt +'" because cannot find node "'+ before +'" to insert before.') + return null + } + parent = this.get(before).parent + } else { + parent = this + } + } + if (typeof parent == 'string') parent = this.get(parent) + if (parent == null || parent == '') parent = this + if (!Array.isArray(nodes)) nodes = [nodes] + for (let o = 0; o < nodes.length; o++) { + node = nodes[o] + if (node.caption != null && node.text == null) { + console.log('NOTICE: sidebar node.caption property is deprecated, please use node.text') + node.text = node.caption + } + if (typeof node.id == null) { + txt = node.text + console.log('ERROR: Cannot insert node "'+ txt +'" because it has no id.') + continue + } + if (this.get(this, node.id) != null) { + console.log('ERROR: Cannot insert node with id='+ node.id +' (text: '+ node.text + ') because another node with the same id already exists.') + continue + } + tmp = Object.assign({}, this.node_template, node) + tmp.sidebar = this + tmp.parent = parent + nd = tmp.nodes || [] + tmp.nodes = [] // very important to re-init empty nodes array + if (before == null) { // append to the end + parent.nodes.push(tmp) + } else { + ind = this.get(parent, before, true) + if (ind == null) { + console.log('ERROR: Cannot insert node "'+ node.text +'" because cannot find node "'+ before +'" to insert before.') + return null + } + parent.nodes.splice(ind, 0, tmp) + } + if (nd.length > 0) { + this.insert(tmp, null, nd) + } + } + if (!this.skipRefresh) this.refresh(parent.id) + return tmp + } + remove() { // multiple arguments + let effected = 0 + let node + Array.from(arguments).forEach(arg => { + node = this.get(arg) + if (node == null) return + if (this.selected != null && this.selected === node.id) { + this.selected = null + } + let ind = this.get(node.parent, arg, true) + if (ind == null) return + if (node.parent.nodes[ind].selected) node.sidebar.unselect(node.id) + node.parent.nodes.splice(ind, 1) + node.parent.collapsible = node.parent.nodes.length > 0 + effected++ + }) + if (!this.skipRefresh) { + if (effected > 0 && arguments.length == 1) this.refresh(node.parent.id); else this.refresh() + } + return effected + } + set(parent, id, node) { + if (arguments.length == 2) { + // need to be in reverse order + node = id + id = parent + parent = this + } + // searches all nested nodes + if (typeof parent == 'string') parent = this.get(parent) + if (parent.nodes == null) return null + for (let i = 0; i < parent.nodes.length; i++) { + if (parent.nodes[i].id === id) { + // see if quick update is possible + let res = this.update(id, node) + if (Object.keys(res).length != 0) { + // make sure nodes inserted correctly + let nodes = node.nodes + w2utils.extend(parent.nodes[i], node, { nodes: [] }) + if (nodes != null) { + this.add(parent.nodes[i], nodes) + } + if (!this.skipRefresh) this.refresh(id) + } + return true + } else { + let rv = this.set(parent.nodes[i], id, node) + if (rv) return true + } + } + return false + } + get(parent, id, returnIndex) { // can be just called get(id) or get(id, true) + if (arguments.length === 0) { + let all = [] + let tmp = this.find({}) + for (let t = 0; t < tmp.length; t++) { + if (tmp[t].id != null) all.push(tmp[t].id) + } + return all + } else { + if (arguments.length == 1 || (arguments.length == 2 && id === true) ) { + // need to be in reverse order + returnIndex = id + id = parent + parent = this + } + // searches all nested nodes + if (typeof parent == 'string') parent = this.get(parent) + if (parent.nodes == null) return null + for (let i = 0; i < parent.nodes.length; i++) { + if (parent.nodes[i].id == id) { + if (returnIndex === true) return i; else return parent.nodes[i] + } else { + let rv = this.get(parent.nodes[i], id, returnIndex) + if (rv || rv === 0) return rv + } + } + return null + } + } + setCount(id, count, className, style) { + let btn = query(this.box).find(`#node_${w2utils.escapeId(id)} .w2ui-node-count`) + if (btn.length > 0) { + btn.removeClass() + .addClass(`w2ui-node-count ${className || ''}`) + .text(count) + .get(0).style.cssText = style || '' + this.last.badge[id] = { + className: className || '', + style: style || '' + } + let item = this.get(id) + item.count = count + } else { + this.set(id, { count: count }) + this.setCount(...arguments) // to update styles + } + } + find(parent, params, results) { // can be just called find({ selected: true }) + // TODO: rewrite with this.each() + if (arguments.length == 1) { + // need to be in reverse order + params = parent + parent = this + } + if (!results) results = [] + // searches all nested nodes + if (typeof parent == 'string') parent = this.get(parent) + if (parent.nodes == null) return results + for (let i = 0; i < parent.nodes.length; i++) { + let match = true + for (let prop in params) { // params is an object + if (parent.nodes[i][prop] != params[prop]) match = false + } + if (match) results.push(parent.nodes[i]) + if (parent.nodes[i].nodes.length > 0) results = this.find(parent.nodes[i], params, results) + } + return results + } + sort(options, nodes) { + // default options + if (!options || typeof options != 'object') options = {} + if (options.foldersFirst == null) options.foldersFirst = true + if (options.caseSensitive == null) options.caseSensitive = false + if (options.reverse == null) options.reverse = false + if (nodes == null) { + nodes = this.nodes + } + nodes.sort((a, b) => { + // folders first + let isAfolder = (a.nodes && a.nodes.length > 0) + let isBfolder = (b.nodes && b.nodes.length > 0) + // both folder or both not folders + if (options.foldersFirst === false || (!isAfolder && !isBfolder) || (isAfolder && isBfolder)) { + let aText = a.text + let bText = b.text + if (!options.caseSensitive) { + aText = aText.toLowerCase() + bText = bText.toLowerCase() + } + if (a.order != null) aText = a.order + if (b.order != null) bText = b.order + let cmp = w2utils.naturalCompare(aText, bText) + return (cmp === 1 || cmp === -1) & options.reverse ? -cmp : cmp + } + if (isAfolder && !isBfolder) { + return !options.reverse ? -1 : 1 + } + if (!isAfolder && isBfolder) { + return !options.reverse ? 1 : -1 + } + }) + nodes.forEach(node => { + if (node.nodes && node.nodes.length > 0) { + this.sort(options, node.nodes) + } + }) + } + each(fn, nodes) { + if (nodes == null) nodes = this.nodes + nodes.forEach((node) => { + fn.call(this, node) + if (node.nodes && node.nodes.length > 0) { + this.each(fn, node.nodes) + } + }) + } + search(str) { + let count = 0 + let str2 = str.toLowerCase() + this.each((node) => { + if (node.text.toLowerCase().indexOf(str2) === -1) { + node.hidden = true + } else { + count++ + showParents(node) + node.hidden = false + } + }) + this.refresh() + return count + function showParents(node) { + if (node.parent) { + node.parent.hidden = false + showParents(node.parent) + } + } + } + show() { // multiple arguments + let effected = [] + Array.from(arguments).forEach(it => { + let node = this.get(it) + if (node == null || node.hidden === false) return + node.hidden = false + effected.push(node.id) + }) + if (effected.length > 0) { + if (arguments.length == 1) this.refresh(arguments[0]); else this.refresh() + } + return effected + } + hide() { // multiple arguments + let effected = [] + Array.from(arguments).forEach(it => { + let node = this.get(it) + if (node == null || node.hidden === true) return + node.hidden = true + effected.push(node.id) + }) + if (effected.length > 0) { + if (arguments.length == 1) this.refresh(arguments[0]); else this.refresh() + } + return effected + } + enable() { // multiple arguments + let effected = [] + Array.from(arguments).forEach(it => { + let node = this.get(it) + if (node == null || node.disabled === false) return + node.disabled = false + effected.push(node.id) + }) + if (effected.length > 0) { + if (arguments.length == 1) this.refresh(arguments[0]); else this.refresh() + } + return effected + } + disable() { // multiple arguments + let effected = [] + Array.from(arguments).forEach(it => { + let node = this.get(it) + if (node == null || node.disabled === true) return + node.disabled = true + if (node.selected) this.unselect(node.id) + effected.push(node.id) + }) + if (effected.length > 0) { + if (arguments.length == 1) this.refresh(arguments[0]); else this.refresh() + } + return effected + } + select(id) { + let new_node = this.get(id) + if (!new_node) return false + if (this.selected == id && new_node.selected) return false + this.unselect(this.selected) + let $el = query(this.box).find('#node_'+ w2utils.escapeId(id)) + $el.addClass('w2ui-selected') + .find('.w2ui-icon') + .addClass('w2ui-icon-selected') + if ($el.length > 0) { + if (!this.inView(id)) this.scrollIntoView(id) + } + new_node.selected = true + this.selected = id + return true + } + unselect(id) { + // if no arguments provided, unselect selected node + if (arguments.length === 0) { + id = this.selected + } + let current = this.get(id) + if (!current) return false + current.selected = false + query(this.box).find('#node_'+ w2utils.escapeId(id)) + .removeClass('w2ui-selected') + .find('.w2ui-icon').removeClass('w2ui-icon-selected') + if (this.selected == id) this.selected = null + return true + } + toggle(id) { + let nd = this.get(id) + if (nd == null) return false + if (nd.plus) { + this.set(id, { plus: false }) + this.expand(id) + this.refresh(id) + return + } + if (nd.nodes.length === 0) return false + if (!nd.collapsible) return false + if (this.get(id).expanded) return this.collapse(id); else return this.expand(id) + } + collapse(id) { + let self = this + let nd = this.get(id) + if (nd == null) return false + // event before + let edata = this.trigger('collapse', { target: id, object: nd }) + if (edata.isCancelled === true) return + // default action + query(this.box).find('#node_'+ w2utils.escapeId(id) +'_sub').hide() + query(this.box).find('#node_'+ w2utils.escapeId(id) +' .w2ui-expanded') + .removeClass('w2ui-expanded') + .addClass('w2ui-collapsed') + nd.expanded = false + // event after + edata.finish() + setTimeout(() => { self.refresh(id) }, 0) + return true + } + expand(id) { + let self = this + let nd = this.get(id) + // event before + let edata = this.trigger('expand', { target: id, object: nd }) + if (edata.isCancelled === true) return + // default action + query(this.box).find('#node_'+ w2utils.escapeId(id) +'_sub') + .show() + query(this.box).find('#node_'+ w2utils.escapeId(id) +' .w2ui-collapsed') + .removeClass('w2ui-collapsed') + .addClass('w2ui-expanded') + nd.expanded = true + // event after + edata.finish() + self.refresh(id) + return true + } + collapseAll(parent) { + if (parent == null) parent = this + if (typeof parent == 'string') parent = this.get(parent) + if (parent.nodes == null) return false + for (let i = 0; i < parent.nodes.length; i++) { + if (parent.nodes[i].expanded === true) parent.nodes[i].expanded = false + if (parent.nodes[i].nodes && parent.nodes[i].nodes.length > 0) this.collapseAll(parent.nodes[i]) + } + this.refresh(parent.id) + return true + } + expandAll(parent) { + if (parent == null) parent = this + if (typeof parent == 'string') parent = this.get(parent) + if (parent.nodes == null) return false + for (let i = 0; i < parent.nodes.length; i++) { + if (parent.nodes[i].expanded === false) parent.nodes[i].expanded = true + if (parent.nodes[i].nodes && parent.nodes[i].nodes.length > 0) this.expandAll(parent.nodes[i]) + } + this.refresh(parent.id) + } + expandParents(id) { + let node = this.get(id) + if (node == null) return false + if (node.parent) { + if (!node.parent.expanded) { + node.parent.expanded = true + this.refresh(node.parent.id) + } + this.expandParents(node.parent.id) + } + return true + } + click(id, event) { + let obj = this + let nd = this.get(id) + if (nd == null) return + if (nd.disabled || nd.group) return // should click event if already selected + // unselect all previously + query(obj.box).find('.w2ui-node.w2ui-selected').each(el => { + let oldID = query(el).attr('id').replace('node_', '') + let oldNode = obj.get(oldID) + if (oldNode != null) oldNode.selected = false + query(el).removeClass('w2ui-selected').find('.w2ui-icon').removeClass('w2ui-icon-selected') + }) + // select new one + let newNode = query(obj.box).find('#node_'+ w2utils.escapeId(id)) + let oldNode = query(obj.box).find('#node_'+ w2utils.escapeId(obj.selected)) + newNode.addClass('w2ui-selected').find('.w2ui-icon').addClass('w2ui-icon-selected') + // need timeout to allow rendering + setTimeout(() => { + // event before + let edata = obj.trigger('click', { target: id, originalEvent: event, node: nd, object: nd }) + if (edata.isCancelled === true) { + // restore selection + newNode.removeClass('w2ui-selected').find('.w2ui-icon').removeClass('w2ui-icon-selected') + oldNode.addClass('w2ui-selected').find('.w2ui-icon').addClass('w2ui-icon-selected') + return + } + // default action + if (oldNode != null) oldNode.selected = false + obj.get(id).selected = true + obj.selected = id + // route processing + if (typeof nd.route == 'string') { + let route = nd.route !== '' ? String('/'+ nd.route).replace(/\/{2,}/g, '/') : '' + let info = w2utils.parseRoute(route) + if (info.keys.length > 0) { + for (let k = 0; k < info.keys.length; k++) { + if (obj.routeData[info.keys[k].name] == null) continue + route = route.replace((new RegExp(':'+ info.keys[k].name, 'g')), obj.routeData[info.keys[k].name]) + } + } + setTimeout(() => { window.location.hash = route }, 1) + } + // event after + edata.finish() + }, 1) + } + focus(event) { + let self = this + // event before + let edata = this.trigger('focus', { target: this.name, originalEvent: event }) + if (edata.isCancelled === true) return false + // default behaviour + this.hasFocus = true + query(this.box).find('.w2ui-sidebar-body').addClass('w2ui-focus') + setTimeout(() => { + let input = query(self.box).find('#sidebar_'+ self.name + '_focus').get(0) + if (document.activeElement != input) input.focus() + }, 10) + // event after + edata.finish() + } + blur(event) { + // event before + let edata = this.trigger('blur', { target: this.name, originalEvent: event }) + if (edata.isCancelled === true) return false + // default behaviour + this.hasFocus = false + query(this.box).find('.w2ui-sidebar-body').removeClass('w2ui-focus') + // event after + edata.finish() + } + keydown(event) { + let obj = this + let nd = obj.get(obj.selected) + if (obj.keyboard !== true) return + if (!nd) nd = obj.nodes[0] + // trigger event + let edata = obj.trigger('keydown', { target: obj.name, originalEvent: event }) + if (edata.isCancelled === true) return + // default behaviour + if (event.keyCode == 13 || event.keyCode == 32) { // enter or space + if (nd.nodes.length > 0) obj.toggle(obj.selected) + } + if (event.keyCode == 37) { // left + if (nd.nodes.length > 0 && nd.expanded) { + obj.collapse(obj.selected) + } else { + selectNode(nd.parent) + if (!nd.parent.group) obj.collapse(nd.parent.id) + } + } + if (event.keyCode == 39) { // right + if ((nd.nodes.length > 0 || nd.plus) && !nd.expanded) obj.expand(obj.selected) + } + if (event.keyCode == 38) { // up + if (obj.get(obj.selected) == null) { + selectNode(this.nodes[0] || null) + } else { + selectNode(neighbor(nd, prev)) + } + } + if (event.keyCode == 40) { // down + if (obj.get(obj.selected) == null) { + selectNode(this.nodes[0] || null) + } else { + selectNode(neighbor(nd, next)) + } + } + // cancel event if needed + if ([13, 32, 37, 38, 39, 40].includes(event.keyCode)) { + if (event.preventDefault) event.preventDefault() + if (event.stopPropagation) event.stopPropagation() + } + // event after + edata.finish() + function selectNode(node, event) { + if (node != null && !node.hidden && !node.disabled && !node.group) { + obj.click(node.id, event) + if (!obj.inView(node.id)) obj.scrollIntoView(node.id) + } + } + function neighbor(node, neighborFunc) { + node = neighborFunc(node) + while (node != null && (node.hidden || node.disabled)) { + if (node.group) break; else node = neighborFunc(node) + } + return node + } + function next(node, noSubs) { + if (node == null) return null + let parent = node.parent + let ind = obj.get(node.id, true) + let nextNode = null + // jump inside + if (node.expanded && node.nodes.length > 0 && noSubs !== true) { + let t = node.nodes[0] + if (t.hidden || t.disabled || t.group) nextNode = next(t); else nextNode = t + } else { + if (parent && ind + 1 < parent.nodes.length) { + nextNode = parent.nodes[ind + 1] + } else { + nextNode = next(parent, true) // jump to the parent + } + } + if (nextNode != null && (nextNode.hidden || nextNode.disabled || nextNode.group)) nextNode = next(nextNode) + return nextNode + } + function prev(node) { + if (node == null) return null + let parent = node.parent + let ind = obj.get(node.id, true) + let prevNode = (ind > 0) ? lastChild(parent.nodes[ind - 1]) : parent + if (prevNode != null && (prevNode.hidden || prevNode.disabled || prevNode.group)) prevNode = prev(prevNode) + return prevNode + } + function lastChild(node) { + if (node.expanded && node.nodes.length > 0) { + let t = node.nodes[node.nodes.length - 1] + if (t.hidden || t.disabled || t.group) return prev(t); else return lastChild(t) + } + return node + } + } + inView(id) { + let item = query(this.box).find('#node_'+ w2utils.escapeId(id)).get(0) + if (!item) { + return false + } + let div = query(this.box).find('.w2ui-sidebar-body').get(0) + if (item.offsetTop < div.scrollTop || (item.offsetTop + item.clientHeight > div.clientHeight + div.scrollTop)) { + return false + } + return true + } + scrollIntoView(id, instant) { + return new Promise((resolve, reject) => { + if (id == null) id = this.selected + let nd = this.get(id) + if (nd == null) return + let item = query(this.box).find('#node_'+ w2utils.escapeId(id)).get(0) + item.scrollIntoView({ block: 'center', inline: 'center', behavior: instant ? 'atuo' : 'smooth' }) + setTimeout(() => { this.resize(); resolve() }, instant ? 0 : 500) + }) + } + dblClick(id, event) { + let nd = this.get(id) + // event before + let edata = this.trigger('dblClick', { target: id, originalEvent: event, object: nd }) + if (edata.isCancelled === true) return + // default action + this.toggle(id) + // event after + edata.finish() + } + contextMenu(id, event) { + let nd = this.get(id) + if (id != this.selected) this.click(id) + // event before + let edata = this.trigger('contextMenu', { target: id, originalEvent: event, object: nd, allowOnDisabled: false }) + if (edata.isCancelled === true) return + // default action + if (nd.disabled && !edata.allowOnDisabled) return + if (this.menu.length > 0) { + w2menu.show({ + name: this.name + '_menu', + anchor: document.body, + items: this.menu, + originalEvent: event + }) + .select(evt => { + this.menuClick(id, parseInt(evt.detail.index), event) + }) + } + // prevent default context menu + if (event.preventDefault) event.preventDefault() + // event after + edata.finish() + } + menuClick(itemId, index, event) { + // event before + let edata = this.trigger('menuClick', { target: itemId, originalEvent: event, menuIndex: index, menuItem: this.menu[index] }) + if (edata.isCancelled === true) return + // default action + // -- empty + // event after + edata.finish() + } + goFlat() { + // event before + let edata = this.trigger('flat', { goFlat: !this.flat }) + if (edata.isCancelled === true) return + // default action + this.flat = !this.flat + this.refresh() + // event after + edata.finish() + } + render(box) { + let time = Date.now() + let obj = this + if (typeof box == 'string') box = query(box).get(0) + // event before + let edata = this.trigger('render', { target: this.name, box: box ?? this.box }) + if (edata.isCancelled === true) return + // default action + if (box != null) { + // clean previous box + if (query(this.box).find('.w2ui-sidebar-body').length > 0) { + query(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-sidebar') + .html('') + } + this.box = box + } + if (!this.box) return + query(this.box) + .attr('name', this.name) + .addClass('w2ui-reset w2ui-sidebar') + .html(`
    +
    + +
    +
    +
    `) + let rect = query(this.box).get(0).getBoundingClientRect() + query(this.box).find(':scope > div').css({ + width : rect.width + 'px', + height : rect.height + 'px' + }) + query(this.box).get(0).style.cssText += this.style + // focus + let kbd_timer + query(this.box).find('#sidebar_'+ this.name + '_focus') + .on('focus', function(event) { + clearTimeout(kbd_timer) + if (!obj.hasFocus) obj.focus(event) + }) + .on('blur', function(event) { + kbd_timer = setTimeout(() => { + if (obj.hasFocus) { obj.blur(event) } + }, 100) + }) + .on('keydown', function(event) { + if (event.keyCode != 9) { // not tab + w2ui[obj.name].keydown.call(w2ui[obj.name], event) + } + }) + query(this.box).off('mousedown') + .on('mousedown', function(event) { + // set focus to grid + setTimeout(() => { + // if input then do not focus + if (['INPUT', 'TEXTAREA', 'SELECT'].indexOf(event.target.tagName.toUpperCase()) == -1) { + let $input = query(obj.box).find('#sidebar_'+ obj.name + '_focus') + if (document.activeElement != $input.get(0)) { + $input.get(0).focus() + } + } + }, 1) + }) + // observe div resize + this.last.observeResize = new ResizeObserver(() => { this.resize() }) + this.last.observeResize.observe(this.box) + // event after + edata.finish() + // --- + this.refresh() + return Date.now() - time + } + update(id, options) { + // quick function to refresh just this item (not sub nodes) + // - icon, class, style, text, count + let nd = this.get(id) + let level + if (nd) { + let $el = query(this.box).find('#node_'+ w2utils.escapeId(nd.id)) + if (nd.group) { + if (options.text) { + nd.text = options.text + $el.find('.w2ui-group-text').replace(typeof nd.text == 'function' + ? nd.text.call(this, nd) + : ''+ nd.text +'') + delete options.text + } + if (options.class) { + nd.class = options.class + level = $el.data('level') + $el.get(0).className = 'w2ui-node-group w2ui-level-'+ level +(nd.class ? ' ' + nd.class : '') + delete options.class + } + if (options.style) { + nd.style = options.style + $el.get(0).nextElementSibling.style = nd.style +';'+ (!nd.hidden && nd.expanded ? '' : 'display: none;') + delete options.style + } + } else { + if (options.icon) { + let $icon = $el.find('.w2ui-node-image > span') + if ($icon.length > 0) { + nd.icon = options.icon + $icon[0].className = (typeof nd.icon == 'function' ? nd.icon.call(this, nd) : nd.icon) + delete options.icon + } + } + if (options.count) { + nd.count = options.count + $el.find('.w2ui-node-count').html(nd.count) + if ($el.find('.w2ui-node-count').length > 0) delete options.count + } + if (options.class && $el.length > 0) { + nd.class = options.class + level = $el.data('level') + $el[0].className = 'w2ui-node w2ui-level-'+ level + (nd.selected ? ' w2ui-selected' : '') + (nd.disabled ? ' w2ui-disabled' : '') + (nd.class ? ' ' + nd.class : '') + delete options.class + } + if (options.text) { + nd.text = options.text + $el.find('.w2ui-node-text').html(typeof nd.text == 'function' ? nd.text.call(this, nd) : nd.text) + delete options.text + } + if (options.style && $el.length > 0) { + let $txt = $el.find('.w2ui-node-text') + nd.style = options.style + $txt[0].style = nd.style + delete options.style + } + } + } + // return what was not set + return options + } + refresh(id, noBinding) { + if (this.box == null) return + let time = Date.now() + // event before + let edata = this.trigger('refresh', { + target: (id != null ? id : this.name), + nodeId: (id != null ? id : null), + fullRefresh: (id != null ? false : true) + }) + if (edata.isCancelled === true) return + // adjust top and bottom + let flatHTML = '' + if (this.flatButton == true) { + flatHTML = `
    ` + } + if (id == null && (this.topHTML !== '' || flatHTML !== '')) { + query(this.box).find('.w2ui-sidebar-top').html(this.topHTML + flatHTML) + query(this.box).find('.w2ui-sidebar-body') + .css('top', query(this.box).find('.w2ui-sidebar-top').get(0)?.clientHeight + 'px') + query(this.box).find('.w2ui-flat') + .off('click') + .on('click', event => { this.goFlat() }) + } + if (id != null && this.bottomHTML !== '') { + query(this.box).find('.w2ui-sidebar-bottom').html(this.bottomHTML) + query(this.box).find('.w2ui-sidebar-body') + .css('bottom', query(this.box).find('.w2ui-sidebar-bottom').get(0)?.clientHeight + 'px') + } + // default action + query(this.box).find(':scope > div').removeClass('w2ui-sidebar-flat').addClass(this.flat ? 'w2ui-sidebar-flat' : '').css({ + width : query(this.box).get(0)?.clientWidth + 'px', + height: query(this.box).get(0)?.clientHeight + 'px' + }) + // if no parent - reset nodes + if (this.nodes.length > 0 && this.nodes[0].parent == null) { + let tmp = this.nodes + this.nodes = [] + this.add(this, tmp) + } + let obj = this + let node + let nodeSubId + if (id == null) { + node = this + nodeSubId = '.w2ui-sidebar-body' + } else { + node = this.get(id) + if (node == null) return + nodeSubId = '#node_'+ w2utils.escapeId(node.id) + '_sub' + } + let nodeId = '#node_'+ w2utils.escapeId(node.id) + let nodeHTML + if (node !== this) { + nodeHTML = getNodeHTML(node) + query(this.box).find(nodeId).before('') + query(this.box).find(nodeId).remove() + query(this.box).find(nodeSubId).remove() + query(this.box).find('#sidebar_'+ this.name + '_tmp').before(nodeHTML) + query(this.box).find('#sidebar_'+ this.name + '_tmp').remove() + } + // remember scroll position + let div = query(this.box).find(':scope > div').get(0) + let scroll = { + top: div?.scrollTop, + left: div?.scrollLeft + } + // refresh sub nodes + query(this.box).find(nodeSubId).html('') + for (let i = 0; i < node.nodes.length; i++) { + let subNode = node.nodes[i] + nodeHTML = getNodeHTML(subNode) + query(this.box).find(nodeSubId).append(nodeHTML) + if (subNode.nodes.length !== 0) { + this.refresh(subNode.id, true) + } else { + // trigger event + let edata2 = this.trigger('refresh', { target: subNode.id }) + if (edata2.isCancelled === true) return + // event after + edata2.finish() + } + } + // reset scroll + if (div) { + div.scrollTop = scroll.top + div.scrollLeft = scroll.left + } + // bind events + if (!noBinding) { + let els = query(this.box).find(`${nodeId}.w2ui-eaction, ${nodeSubId} .w2ui-eaction`) + w2utils.bindEvents(els, this) + } + // event after + edata.finish() + return Date.now() - time + function getNodeHTML(nd) { + let html = '' + let icon = nd.icon + if (icon == null) icon = obj.icon + // -- find out level + let tmp = nd.parent + let level = 0 + while (tmp && tmp.parent != null) { + // if (tmp.group) level--; + tmp = tmp.parent + level++ + } + if (nd.caption != null && nd.text == null) nd.text = nd.caption + if (nd.caption != null) { + console.log('NOTICE: sidebar node.caption property is deprecated, please use node.text. Node -> ', nd) + nd.text = nd.caption + } + if (Array.isArray(nd.nodes) && nd.nodes.length > 0) nd.collapsible = true + if (nd.group) { + let text = w2utils.lang(typeof nd.text == 'function' ? nd.text.call(obj, nd) : nd.text) + if (String(text).substr(0, 5) != '${text}` + } + html = ` +
    + ${nd.groupShowHide && nd.collapsible + ? `${!nd.hidden && nd.expanded ? w2utils.lang('Hide') : w2utils.lang('Show')}` + : '' + } ${text} +
    +
    +
    ` + if (obj.flat) { + html = ` +
     
    +
    ` + } + } else { + if (nd.selected && !nd.disabled) obj.selected = nd.id + tmp = '' + if (icon) { + tmp = ` +
    + +
    ` + } + let expand = '' + let counts = (nd.count != null + ? `
    + ${nd.count} +
    ` + : '') + if (nd.collapsible === true) { + expand = `
    ` + } + let text = w2utils.lang(typeof nd.text == 'function' ? nd.text.call(obj, nd) : nd.text) + // array with classes + let classes = ['w2ui-node', `w2ui-level-${level}`, 'w2ui-eaction'] + if (nd.selected) classes.push('w2ui-selected') + if (nd.disabled) classes.push('w2ui-disabled') + if (nd.class) classes.push(nd.class) + html = ` +
    + ${obj.handle.html + ? `
    + ${typeof obj.handle.html == 'function' ? obj.handle.html.call(obj, nd) : obj.handle.html} +
    ` + : '' + } +
    + ${expand} ${tmp} ${counts} +
    ${text}
    +
    +
    +
    ` + if (obj.flat) { + html = ` +
    +
    ${tmp}
    +
    +
    ` + } + } + return html + } + } + mouseAction(action, el, id, event, type) { + let node = this.get(id) + let text = w2utils.lang(typeof node.text == 'function' ? node.text.call(this, node) : node.text) + let tooltip = text + (node.count || node.count === 0 ? ' - '+ node.count +'' : '') + let edata = this.trigger('mouse' + action, { target: id, node, tooltip, originalEvent: event }) + if (type == 'tooltip') { + this.tooltip(el, tooltip, id) + } + if (type == 'handle') { + this.handleTooltip(el, id) + } + edata.finish() + } + tooltip(el, text, id) { + let $el = query(el).find('.w2ui-node-data') + if (text !== '') { + w2tooltip.show({ + anchor: $el.get(0), + name: this.name + '_tooltip', + html: text, + position: 'right|left' + }) + } else { + w2tooltip.hide(this.name + '_tooltip') + } + } + handleTooltip(anchor, id) { + let text = this.handle.tooltip + if (typeof text == 'function') { + text = text(id) + } + if (text !== '' && id != null) { + w2tooltip.show({ + anchor: anchor, + name: this.name + '_tooltip', + html: text, + position: 'top|bottom' + }) + } else { + w2tooltip.hide(this.name + '_tooltip') + } + } + showPlus(el, color) { + query(el).find('span:nth-child(1)').css('color', color) + } + resize() { + let time = Date.now() + // event before + let edata = this.trigger('resize', { target: this.name }) + if (edata.isCancelled === true) return + // default action + let rect = query(this.box).get(0).getBoundingClientRect() + query(this.box).css('overflow', 'hidden') // container should have no overflow + query(this.box).find(':scope > div').css({ + width : rect.width + 'px', + height : rect.height + 'px' + }) + // event after + edata.finish() + return Date.now() - time + } + destroy() { + // event before + let edata = this.trigger('destroy', { target: this.name }) + if (edata.isCancelled === true) return + // clean up + if (query(this.box).find('.w2ui-sidebar-body').length > 0) { + query(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-sidebar') + .html('') + } + this.last.observeResize?.disconnect() + delete w2ui[this.name] + // event after + edata.finish() + } + lock(msg, showSpinner) { + let args = Array.from(arguments) + args.unshift(this.box) + w2utils.lock(...args) + } + unlock(speed) { + w2utils.unlock(this.box, speed) + } +} +/** + * Part of w2ui 2.0 library + * - Dependencies: mQuery, w2utils, w2base, w2tooltip + * + * == 2.0 changes + * - CSP - fixed inline events + * - removed jQuery dependency + * - observeResize for the box + * - refactored w2events + * - scrollIntoView - removed callback + * - scroll, scrollIntoView return promise + * - animateInsert, animateClose - returns a promise + * - add, insert return a promise + * - onMouseEnter, onMouseLeave, onMouseDown, onMouseUp + */ + +class w2tabs extends w2base { + constructor(options) { + super(options.name) + this.box = null // DOM Element that holds the element + this.name = null // unique name for w2ui + this.active = null + this.reorder = false + this.flow = 'down' // can be down or up + this.tooltip = 'top|left' // can be top, bottom, left, right + this.tabs = [] + this.routeData = {} // data for dynamic routes + this.last = {} // placeholder for internal variables + this.right = '' + this.style = '' + this.onClick = null + this.onMouseEnter = null // mouse enter and lease + this.onMouseLeave = null + this.onMouseDown = null + this.onMouseUp = null + this.onClose = null + this.onRender = null + this.onRefresh = null + this.onResize = null + this.onDestroy = null + this.tab_template = { + id: null, + text: null, + route: null, + hidden: false, + disabled: false, + closable: false, + tooltip: null, + style: '', + onClick: null, + onRefresh: null, + onClose: null + } + let tabs = options.tabs + delete options.tabs + // mix in options + Object.assign(this, options) + // add item via method to makes sure item_template is applied + if (Array.isArray(tabs)) this.add(tabs) + // need to reassign back to keep it in config + options.tabs = tabs + // render if box specified + if (typeof this.box == 'string') this.box = query(this.box).get(0) + if (this.box) this.render(this.box) + } + add(tab) { + return this.insert(null, tab) + } + insert(id, tabs) { + if (!Array.isArray(tabs)) tabs = [tabs] + // assume it is array + let proms = [] + tabs.forEach(tab => { + // checks + if (tab.id == null) { + console.log(`ERROR: The parameter "id" is required but not supplied. (obj: ${this.name})`) + return + } + if (!w2utils.checkUniqueId(tab.id, this.tabs, 'tabs', this.name)) return + // add tab + let it = Object.assign({}, this.tab_template, tab) + if (id == null) { + this.tabs.push(it) + proms.push(this.animateInsert(null, it)) + } else { + let middle = this.get(id, true) + let before = this.tabs[middle].id + this.tabs.splice(middle, 0, it) + proms.push(this.animateInsert(before, it)) + } + }) + return Promise.all(proms) + } + remove() { + let effected = 0 + Array.from(arguments).forEach(it => { + let tab = this.get(it) + if (!tab) return + effected++ + // remove from array + this.tabs.splice(this.get(tab.id, true), 1) + // remove from screen + query(this.box).find(`#tabs_${this.name}_tab_${w2utils.escapeId(tab.id)}`).remove() + }) + this.resize() + return effected + } + select(id) { + if (this.active == id || this.get(id) == null) return false + this.active = id + this.refresh() + return true + } + set(id, tab) { + let index = this.get(id, true) + if (index == null) return false + w2utils.extend(this.tabs[index], tab) + this.refresh(id) + return true + } + get(id, returnIndex) { + if (arguments.length === 0) { + let all = [] + for (let i1 = 0; i1 < this.tabs.length; i1++) { + if (this.tabs[i1].id != null) { + all.push(this.tabs[i1].id) + } + } + return all + } else { + for (let i2 = 0; i2 < this.tabs.length; i2++) { + if (this.tabs[i2].id == id) { // need to be == since id can be numeric + return (returnIndex === true ? i2 : this.tabs[i2]) + } + } + } + return null + } + show() { + let effected = [] + Array.from(arguments).forEach(it => { + let tab = this.get(it) + if (!tab || tab.hidden === false) return + tab.hidden = false + effected.push(tab.id) + }) + setTimeout(() => { effected.forEach(it => { this.refresh(it); this.resize() }) }, 15) // needs timeout + return effected + } + hide() { + let effected = [] + Array.from(arguments).forEach(it => { + let tab = this.get(it) + if (!tab || tab.hidden === true) return + tab.hidden = true + effected.push(tab.id) + }) + setTimeout(() => { effected.forEach(it => { this.refresh(it); this.resize() }) }, 15) // needs timeout + return effected + } + enable() { + let effected = [] + Array.from(arguments).forEach(it => { + let tab = this.get(it) + if (!tab || tab.disabled === false) return + tab.disabled = false + effected.push(tab.id) + }) + setTimeout(() => { effected.forEach(it => { this.refresh(it) }) }, 15) // needs timeout + return effected + } + disable() { + let effected = [] + Array.from(arguments).forEach(it => { + let tab = this.get(it) + if (!tab || tab.disabled === true) return + tab.disabled = true + effected.push(tab.id) + }) + setTimeout(() => { effected.forEach(it => { this.refresh(it) }) }, 15) // needs timeout + return effected + } + dragMove(event) { + if (!this.last.reordering) return + let self = this + let info = this.last.moving + let tab = this.tabs[info.index] + let next = _find(info.index, 1) + let prev = _find(info.index, -1) + let $el = query(this.box).find('#tabs_'+ this.name + '_tab_'+ w2utils.escapeId(tab.id)) + if (info.divX > 0 && next) { + let $nextEl = query(this.box).find('#tabs_'+ this.name + '_tab_'+ w2utils.escapeId(next.id)) + let width1 = parseInt($el.get(0).clientWidth) + let width2 = parseInt($nextEl.get(0).clientWidth) + if (width1 < width2) { + width1 = Math.floor(width1 / 3) + width2 = width2 - width1 + } else { + width1 = Math.floor(width2 / 3) + width2 = width2 - width1 + } + if (info.divX > width2) { + let index = this.tabs.indexOf(next) + this.tabs.splice(info.index, 0, this.tabs.splice(index, 1)[0]) // reorder in the array + info.$tab.before($nextEl.get(0)) + info.$tab.css('opacity', 0) + Object.assign(this.last.moving, { + index: index, + divX: -width1, + x: event.pageX + width1, + left: info.left + info.divX + width1 + }) + return + } + } + if (info.divX < 0 && prev) { + let $prevEl = query(this.box).find('#tabs_'+ this.name + '_tab_'+ w2utils.escapeId(prev.id)) + let width1 = parseInt($el.get(0).clientWidth) + let width2 = parseInt($prevEl.get(0).clientWidth) + if (width1 < width2) { + width1 = Math.floor(width1 / 3) + width2 = width2 - width1 + } else { + width1 = Math.floor(width2 / 3) + width2 = width2 - width1 + } + if (Math.abs(info.divX) > width2) { + let index = this.tabs.indexOf(prev) + this.tabs.splice(info.index, 0, this.tabs.splice(index, 1)[0]) // reorder in the array + $prevEl.before(info.$tab) + info.$tab.css('opacity', 0) + Object.assign(info, { + index: index, + divX: width1, + x: event.pageX - width1, + left: info.left + info.divX - width1 + }) + return + } + } + function _find(ind, inc) { + ind += inc + let tab = self.tabs[ind] + if (tab && tab.hidden) { + tab = _find(ind, inc) + } + return tab + } + } + mouseAction(action, id, event) { + let tab = this.get(id) + let edata = this.trigger('mouse' + action, { target: id, tab, object: tab, originalEvent: event }) + if (edata.isCancelled === true || tab.disabled || tab.hidden) return + switch (action) { + case 'Enter': + this.tooltipShow(id) + break + case 'Leave': + this.tooltipHide(id) + break + case 'Down': + this.initReorder(id, event) + break + case 'Up': + break + } + edata.finish() + } + tooltipShow(id) { + let item = this.get(id) + let el = query(this.box).find('#tabs_'+ this.name + '_tab_'+ w2utils.escapeId(id)).get(0) + if (this.tooltip == null || item.disabled || this.last.reordering) { + return + } + let pos = this.tooltip + let txt = item.tooltip + if (typeof txt == 'function') txt = txt.call(this, item) + w2tooltip.show({ + anchor: el, + name: this.name + '_tooltip', + html: txt, + position: pos + }) + } + tooltipHide(id) { + if (this.tooltip == null) return + w2tooltip.hide(this.name + '_tooltip') + } + getTabHTML(id) { + let index = this.get(id, true) + let tab = this.tabs[index] + if (tab == null) return false + if (tab.text == null && tab.caption != null) tab.text = tab.caption + if (tab.tooltip == null && tab.hint != null) tab.tooltip = tab.hint // for backward compatibility + if (tab.caption != null) { + console.log('NOTICE: tabs tab.caption property is deprecated, please use tab.text. Tab -> ', tab) + } + if (tab.hint != null) { + console.log('NOTICE: tabs tab.hint property is deprecated, please use tab.tooltip. Tab -> ', tab) + } + let text = tab.text + if (typeof text == 'function') text = text.call(this, tab) + if (text == null) text = '' + let closable = '' + let addStyle = '' + if (tab.hidden) { addStyle += 'display: none;' } + if (tab.disabled) { addStyle += 'opacity: 0.2;' } + if (tab.closable && !tab.disabled) { + closable = `
    +
    ` + } + return ` +
    + ${w2utils.lang(text) + closable} +
    ` + } + refresh(id) { + let time = Date.now() + if (this.flow == 'up') { + query(this.box).addClass('w2ui-tabs-up') + } else { + query(this.box).removeClass('w2ui-tabs-up') + } + // event before + let edata = this.trigger('refresh', { target: (id != null ? id : this.name), object: this.get(id) }) + if (edata.isCancelled === true) return + if (id == null) { + // refresh all + for (let i = 0; i < this.tabs.length; i++) { + this.refresh(this.tabs[i].id) + } + } else { + // create or refresh only one item + let selector = '#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(id) + let $tab = query(this.box).find(selector) + let tabHTML = this.getTabHTML(id) + if ($tab.length === 0) { + query(this.box).find('#tabs_'+ this.name +'_right').before(tabHTML) + } else { + if (query(this.box).find('.tab-animate-insert').length == 0) { + $tab.replace(tabHTML) + } + } + w2utils.bindEvents(query(this.box).find(`${selector}, ${selector} .w2ui-eaction`), this) + } + // right html + query(this.box).find('#tabs_'+ this.name +'_right').html(this.right) + // event after + edata.finish() + // this.resize(); + return Date.now() - time + } + render(box) { + let time = Date.now() + if (typeof box == 'string') box = query(box).get(0) + // event before + let edata = this.trigger('render', { target: this.name, box: box ?? this.box }) + if (edata.isCancelled === true) return + // default action + if (box != null) { + // clean previous box + if (query(this.box).find('#tabs_'+ this.name + '_right').length > 0) { + query(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-tabs') + .html('') + } + this.box = box + } + if (!this.box) return false + // render all buttons + let html =` +
    +
    +
    ${this.right}
    +
    +
    +
    ` + query(this.box) + .attr('name', this.name) + .addClass('w2ui-reset w2ui-tabs') + .html(html) + if (query(this.box).length > 0) { + query(this.box)[0].style.cssText += this.style + } + w2utils.bindEvents(query(this.box).find('.w2ui-eaction'), this) + // observe div resize + this.last.observeResize = new ResizeObserver(() => { this.resize() }) + this.last.observeResize.observe(this.box) + // event after + edata.finish() + this.refresh() + this.resize() + return Date.now() - time + } + initReorder(id, event) { + if (!this.reorder) return + let self = this + let $tab = query(this.box).find('#tabs_' + this.name + '_tab_' + w2utils.escapeId(id)) + let tabIndex = this.get(id, true) + let $ghost = query($tab.get(0).cloneNode(true)) + let edata + $ghost.attr('id', '#tabs_' + this.name + '_tab_ghost') + this.last.moving = { + index: tabIndex, + indexFrom: tabIndex, + $tab: $tab, + $ghost: $ghost, + divX: 0, + left: $tab.get(0).getBoundingClientRect().left, + parentX: query(this.box).get(0).getBoundingClientRect().left, + x: event.pageX, + opacity: $tab.css('opacity') + } + query(document) + .off('.w2uiTabReorder') + .on('mousemove.w2uiTabReorder', function (event) { + if (!self.last.reordering) { + // event before + edata = self.trigger('reorder', { target: self.tabs[tabIndex].id, indexFrom: tabIndex, tab: self.tabs[tabIndex] }) + if (edata.isCancelled === true) return + w2tooltip.hide(this.name + '_tooltip') + self.last.reordering = true + $ghost.addClass('moving') + $ghost.css({ + 'pointer-events': 'none', + 'position': 'absolute', + 'left': $tab.get(0).getBoundingClientRect().left + }) + $tab.css('opacity', 0) + query(self.box).find('.w2ui-scroll-wrapper').append($ghost.get(0)) + query(self.box).find('.w2ui-tab-close').hide() + } + self.last.moving.divX = event.pageX - self.last.moving.x + $ghost.css('left', (self.last.moving.left - self.last.moving.parentX + self.last.moving.divX) + 'px') + self.dragMove(event) + }) + .on('mouseup.w2uiTabReorder', function () { + query(document).off('.w2uiTabReorder') + $ghost.css({ + 'transition': '0.1s', + 'left': self.last.moving.$tab.get(0).getBoundingClientRect().left - self.last.moving.parentX + }) + query(self.box).find('.w2ui-tab-close').show() + setTimeout(() => { + $ghost.remove() + $tab.css({ opacity: self.last.moving.opacity }) + // self.render() + if (self.last.reordering) { + edata.finish({ indexTo: self.last.moving.index }) + } + self.last.reordering = false + }, 100) + }) + } + scroll(direction, instant) { + return new Promise((resolve, reject) => { + let scrollBox = query(this.box).find('.w2ui-scroll-wrapper') + let scrollLeft = scrollBox.get(0).scrollLeft + let right = scrollBox.find('.w2ui-tabs-right').get(0) + let width1 = scrollBox.parent().get(0).getBoundingClientRect().width + let width2 = scrollLeft + parseInt(right.offsetLeft) + parseInt(right.clientWidth ) + switch (direction) { + case 'left': { + let scroll = scrollLeft - width1 + 50 // 35 is width of both button + if (scroll <= 0) scroll = 0 + scrollBox.get(0).scrollTo({ top: 0, left: scroll, behavior: instant ? 'atuo' : 'smooth' }) + break + } + case 'right': { + let scroll = scrollLeft + width1 - 50 // 35 is width of both button + if (scroll >= width2 - width1) scroll = width2 - width1 + scrollBox.get(0).scrollTo({ top: 0, left: scroll, behavior: instant ? 'atuo' : 'smooth' }) + break + } + } + setTimeout(() => { this.resize(); resolve() }, instant ? 0 : 350) + }) + } + scrollIntoView(id, instant) { + return new Promise((resolve, reject) => { + if (id == null) id = this.active + let tab = this.get(id) + if (tab == null) return + let tabEl = query(this.box).find('#tabs_' + this.name + '_tab_' + w2utils.escapeId(id)).get(0) + tabEl.scrollIntoView({ block: 'start', inline: 'center', behavior: instant ? 'atuo' : 'smooth' }) + setTimeout(() => { this.resize(); resolve() }, instant ? 0 : 500) + }) + } + resize() { + let time = Date.now() + if (this.box == null) return + // event before + let edata = this.trigger('resize', { target: this.name }) + if (edata.isCancelled === true) return + // show hide overflow buttons + let box = query(this.box) + box.find('.w2ui-scroll-left, .w2ui-scroll-right').hide() + let scrollBox = box.find('.w2ui-scroll-wrapper').get(0) + let $right = box.find('.w2ui-tabs-right') + let boxWidth = box.get(0).getBoundingClientRect().width + let itemsWidth = ($right.length > 0 ? $right[0].offsetLeft + $right[0].clientWidth : 0) + if (boxWidth < itemsWidth) { + // we have overflown content + if (scrollBox.scrollLeft > 0) { + box.find('.w2ui-scroll-left').show() + } + if (boxWidth < itemsWidth - scrollBox.scrollLeft) { + box.find('.w2ui-scroll-right').show() + } + } + // event after + edata.finish() + return Date.now() - time + } + destroy() { + // event before + let edata = this.trigger('destroy', { target: this.name }) + if (edata.isCancelled === true) return + // clean up + if (query(this.box).find('#tabs_'+ this.name + '_right').length > 0) { + query(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-tabs') + .html('') + } + this.last.observeResize?.disconnect() + delete w2ui[this.name] + // event after + edata.finish() + } + // =================================================== + // -- Internal Event Handlers + click(id, event) { + let tab = this.get(id) + if (tab == null || tab.disabled || this.last.reordering) return false + // event before + let edata = this.trigger('click', { target: id, tab: tab, object: tab, originalEvent: event }) + if (edata.isCancelled === true) return + // default action + query(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.active)).removeClass('active') + this.active = tab.id + query(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(this.active)).addClass('active') + // route processing + if (typeof tab.route == 'string') { + let route = tab.route !== '' ? String('/'+ tab.route).replace(/\/{2,}/g, '/') : '' + let info = w2utils.parseRoute(route) + if (info.keys.length > 0) { + for (let k = 0; k < info.keys.length; k++) { + if (this.routeData[info.keys[k].name] == null) continue + route = route.replace((new RegExp(':'+ info.keys[k].name, 'g')), this.routeData[info.keys[k].name]) + } + } + setTimeout(() => { window.location.hash = route }, 1) + } + // event after + edata.finish() + } + clickClose(id, event) { + let tab = this.get(id) + if (tab == null || tab.disabled) return false + // event before + let edata = this.trigger('close', { target: id, object: tab, tab, originalEvent: event }) + if (edata.isCancelled === true) return + this.animateClose(id).then(() => { + this.remove(id) + edata.finish() + this.refresh() + }) + if (event) event.stopPropagation() + } + animateClose(id) { + return new Promise((resolve, reject) => { + let $tab = query(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(id)) + let width = parseInt($tab.get(0).clientWidth || 0) + let anim = `
    ` + let $anim = $tab.replace(anim) + setTimeout(() => { $anim.css({ width: '0px' }) }, 1) + setTimeout(() => { + $anim.remove() + this.resize() + resolve() + }, 500) + }) + } + animateInsert(id, tab) { + return new Promise((resolve, reject) => { + let $before = query(this.box).find('#tabs_'+ this.name +'_tab_'+ w2utils.escapeId(id)) + let $tab = query.html(this.getTabHTML(tab.id)) + if ($before.length == 0) { + $before = query(this.box).find('#tabs_tabs_right') + $before.before($tab) + this.resize() + } else { + $tab.css({ opacity: 0 }) + // first insert tab on the right to get its proper dimentions + query(this.box).find('#tabs_tabs_right').before($tab.get(0)) + let $tmp = query(this.box).find('#' + $tab.attr('id')) + let width = $tmp.get(0).clientWidth ?? 0 + // insert animation div + let $anim = query.html('
    ') + $before.before($anim) + // hide tab and move it in the right position + $tab.hide() + $anim.before($tab[0]) + setTimeout(() => { $anim.css({ width: width + 'px' }) }, 1) + setTimeout(() => { + $anim.remove() + $tab.css({ opacity: 1 }).show() + this.refresh(tab.id) + this.resize() + resolve() + }, 500) + } + }) + } +} +/** + * Part of w2ui 2.0 library + * - Dependencies: mQuery, w2utils, w2base, w2tabs, w2toolbar + * + * == 2.0 changes + * - CSP - fixed inline events + * - remove jQuery dependency + * - layout.confirm - refactored + * - layout.message - refactored + * - panel.removed + */ + +let w2panels = ['top', 'left', 'main', 'preview', 'right', 'bottom'] +class w2layout extends w2base { + constructor(options) { + super(options.name) + this.box = null // DOM Element that holds the element + this.name = null // unique name for w2ui + this.panels = [] + this.last = {} + this.padding = 1 // panel padding + this.resizer = 4 // resizer width or height + this.style = '' + this.onShow = null + this.onHide = null + this.onResizing = null + this.onResizerClick = null + this.onRender = null + this.onRefresh = null + this.onChange = null + this.onResize = null + this.onDestroy = null + this.panel_template = { + type: null, // left, right, top, bottom + title: '', + size: 100, // width or height depending on panel name + minSize: 20, + maxSize: false, + hidden: false, + resizable: false, + overflow: 'auto', + style: '', + html: '', // can be String or Object with .render(box) method + tabs: null, + toolbar: null, + width: null, // read only + height: null, // read only + show: { + toolbar: false, + tabs: false + }, + removed: null, // function to call when content is overwritten + onRefresh: null, + onShow: null, + onHide: null + } + // mix in options + Object.assign(this, options) + if (!Array.isArray(this.panels)) this.panels = [] + // add defined panels + this.panels.forEach((panel, ind) => { + this.panels[ind] = w2utils.extend({}, this.panel_template, panel) + if (w2utils.isPlainObject(panel.tabs) || Array.isArray(panel.tabs)) initTabs(this, panel.type) + if (w2utils.isPlainObject(panel.toolbar) || Array.isArray(panel.toolbar)) initToolbar(this, panel.type) + }) + // add all other panels + w2panels.forEach(tab => { + if (this.get(tab) != null) return + this.panels.push(w2utils.extend({}, this.panel_template, { type: tab, hidden: (tab !== 'main'), size: 50 })) + }) + // render if box specified + if (typeof this.box == 'string') this.box = query(this.box).get(0) + if (this.box) this.render(this.box) + function initTabs(object, panel, tabs) { + let pan = object.get(panel) + if (pan != null && tabs == null) tabs = pan.tabs + if (pan == null || tabs == null) return false + // instantiate tabs + if (Array.isArray(tabs)) tabs = { tabs: tabs } + let name = object.name + '_' + panel + '_tabs' + if (w2ui[name]) w2ui[name].destroy() // destroy if existed + pan.tabs = new w2tabs(w2utils.extend({}, tabs, { owner: object, name: object.name + '_' + panel + '_tabs' })) + pan.show.tabs = true + return true + } + function initToolbar(object, panel, toolbar) { + let pan = object.get(panel) + if (pan != null && toolbar == null) toolbar = pan.toolbar + if (pan == null || toolbar == null) return false + // instantiate toolbar + if (Array.isArray(toolbar)) toolbar = { items: toolbar } + let name = object.name + '_' + panel + '_toolbar' + if (w2ui[name]) w2ui[name].destroy() // destroy if existed + pan.toolbar = new w2toolbar(w2utils.extend({}, toolbar, { owner: object, name: object.name + '_' + panel + '_toolbar' })) + pan.show.toolbar = true + return true + } + } + html(panel, data, transition) { + let p = this.get(panel) + let promise = { + panel: panel, + html: p.html, + error: false, + cancelled: false, + removed(cb) { + if (typeof cb == 'function') { + p.removed = cb + } + } + } + if (typeof p.removed == 'function') { + p.removed({ panel: panel, html: p.html, html_new: data, transition: transition || 'none' }) + p.removed = null // this is one time call back only + } + // if it is CSS panel + if (panel == 'css') { + query(this.box).find('#layout_'+ this.name +'_panel_css').html('') + promise.status = true + return promise + } + if (p == null) { + console.log('ERROR: incorrect panel name. Panel name can be main, left, right, top, bottom, preview or css') + promise.error = true + return promise + } + if (data == null) { + return promise + } + // event before + let edata = this.trigger('change', { target: panel, panel: p, html_new: data, transition: transition }) + if (edata.isCancelled === true) { + promise.cancelled = true + return promise + } + let pname = '#layout_'+ this.name + '_panel_'+ p.type + let current = query(this.box).find(pname + '> .w2ui-panel-content') + let panelTop = 0 + if (current.length > 0) { + query(this.box).find(pname).get(0).scrollTop = 0 + panelTop = query(current).css('top') + } + if (p.html === '') { + p.html = data + this.refresh(panel) + } else { + p.html = data + if (!p.hidden) { + if (transition != null && transition !== '') { + // apply transition + query(this.box).addClass('animating') + let div1 = query(this.box).find(pname + '> .w2ui-panel-content') + div1.after('
    ') + let div2 = query(this.box).find(pname + '> .w2ui-panel-content.new-panel') + div1.css('top', panelTop) + div2.css('top', panelTop) + if (typeof data == 'object') { + data.box = div2[0] // do not do .render(box); + data.render() + } else { + div2.hide().html(data) + } + w2utils.transition(div1[0], div2[0], transition, () => { + div1.remove() + div2.removeClass('new-panel') + div2.css('overflow', p.overflow) + // make sure only one content left + query(query(this.box).find(pname + '> .w2ui-panel-content').get(1)).remove() + query(this.box).removeClass('animating') + this.refresh(panel) + }) + } else { + this.refresh(panel) + } + } + } + // event after + edata.finish() + return promise + } + message(panel, options) { + let p = this.get(panel) + let box = query(this.box).find('#layout_'+ this.name + '_panel_'+ p.type) + let oldOverflow = box.css('overflow') + box.css('overflow', 'hidden') + let prom = w2utils.message({ + owner: this, + box : box.get(0), + after: '.w2ui-panel-title', + param: panel + }, options) + if (prom) { + prom.self.on('close:after', () => { + box.css('overflow', oldOverflow) + }) + } + return prom + } + confirm(panel, options) { + let p = this.get(panel) + let box = query(this.box).find('#layout_'+ this.name + '_panel_'+ p.type) + let oldOverflow = box.css('overflow') + box.css('overflow', 'hidden') + let prom = w2utils.confirm({ + owner : this, + box : box.get(0), + after : '.w2ui-panel-title', + param : panel + }, options) + if (prom) { + prom.self.on('close:after', () => { + box.css('overflow', oldOverflow) + }) + } + return prom + } + load(panel, url, transition) { + return new Promise((resolve, reject) => { + if ((panel == 'css' || this.get(panel) != null) && url != null) { + fetch(url) + .then(resp => resp.text()) + .then(text => { + this.resize() + resolve(this.html(panel, text, transition)) + }) + } else { + reject() + } + }) + } + sizeTo(panel, size, instant) { + let pan = this.get(panel) + if (pan == null) return false + // resize + query(this.box).find(':scope > div > .w2ui-panel') + .css('transition', (instant !== true ? '.2s' : '0s')) + setTimeout(() => { this.set(panel, { size: size }) }, 1) + // clean + setTimeout(() => { + query(this.box).find(':scope > div > .w2ui-panel').css('transition', '0s') + this.resize() + }, 300) + return true + } + show(panel, immediate) { + // event before + let edata = this.trigger('show', { target: panel, thisect: this.get(panel), immediate: immediate }) + if (edata.isCancelled === true) return + let p = this.get(panel) + if (p == null) return false + p.hidden = false + if (immediate === true) { + query(this.box).find('#layout_'+ this.name +'_panel_'+panel) + .css({ 'opacity': '1' }) + edata.finish() + this.resize() + } else { + // resize + query(this.box).addClass('animating') + query(this.box).find('#layout_'+ this.name +'_panel_'+panel) + .css({ 'opacity': '0' }) + query(this.box).find(':scope > div > .w2ui-panel') + .css('transition', '.2s') + setTimeout(() => { this.resize() }, 1) + // show + setTimeout(() => { + query(this.box).find('#layout_'+ this.name +'_panel_'+ panel).css({ 'opacity': '1' }) + }, 250) + // clean + setTimeout(() => { + query(this.box).find(':scope > div > .w2ui-panel') + .css('transition', '0s') + query(this.box).removeClass('animating') + edata.finish() + this.resize() + }, 300) + } + return true + } + hide(panel, immediate) { + // event before + let edata = this.trigger('hide', { target: panel, object: this.get(panel), immediate: immediate }) + if (edata.isCancelled === true) return + let p = this.get(panel) + if (p == null) return false + p.hidden = true + if (immediate === true) { + query(this.box).find('#layout_'+ this.name +'_panel_'+panel) + .css({ 'opacity': '0' }) + edata.finish() + this.resize() + } else { + // hide + query(this.box).addClass('animating') + query(this.box).find(':scope > div > .w2ui-panel') + .css('transition', '.2s') + query(this.box).find('#layout_'+ this.name +'_panel_'+panel) + .css({ 'opacity': '0' }) + setTimeout(() => { this.resize() }, 1) + // clean + setTimeout(() => { + query(this.box).find(':scope > div > .w2ui-panel') + .css('transition', '0s') + query(this.box).removeClass('animating') + edata.finish() + this.resize() + }, 300) + } + return true + } + toggle(panel, immediate) { + let p = this.get(panel) + if (p == null) return false + if (p.hidden) return this.show(panel, immediate); else return this.hide(panel, immediate) + } + set(panel, options) { + let ind = this.get(panel, true) + if (ind == null) return false + w2utils.extend(this.panels[ind], options) + // refresh only when content changed + if (options.html != null || options.resizable != null) { + this.refresh(panel) + } + // show/hide resizer + this.resize() // resize is needed when panel size is changed + return true + } + get(panel, returnIndex) { + for (let p = 0; p < this.panels.length; p++) { + if (this.panels[p].type == panel) { + if (returnIndex === true) return p; else return this.panels[p] + } + } + return null + } + el(panel) { + let el = query(this.box).find('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-content') + if (el.length != 1) return null + return el[0] + } + hideToolbar(panel) { + let pan = this.get(panel) + if (!pan) return + pan.show.toolbar = false + query(this.box).find('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-toolbar').hide() + this.resize() + } + showToolbar(panel) { + let pan = this.get(panel) + if (!pan) return + pan.show.toolbar = true + query(this.box).find('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-toolbar').show() + this.resize() + } + toggleToolbar(panel) { + let pan = this.get(panel) + if (!pan) return + if (pan.show.toolbar) this.hideToolbar(panel); else this.showToolbar(panel) + } + assignToolbar(panel, toolbar) { + if (typeof toolbar == 'string' && w2ui[toolbar] != null) toolbar = w2ui[toolbar] + let pan = this.get(panel) + pan.toolbar = toolbar + let tmp = query(this.box).find(panel +'> .w2ui-panel-toolbar') + if (pan.toolbar != null) { + if (tmp.find('[name='+ pan.toolbar.name +']').length === 0) { + pan.toolbar.render(tmp.get(0)) + } else if (pan.toolbar != null) { + pan.toolbar.refresh() + } + toolbar.owner = this + this.showToolbar(panel) + this.refresh(panel) + } else { + tmp.html('') + this.hideToolbar(panel) + } + } + hideTabs(panel) { + let pan = this.get(panel) + if (!pan) return + pan.show.tabs = false + query(this.box).find('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-tabs').hide() + this.resize() + } + showTabs(panel) { + let pan = this.get(panel) + if (!pan) return + pan.show.tabs = true + query(this.box).find('#layout_'+ this.name +'_panel_'+ panel +'> .w2ui-panel-tabs').show() + this.resize() + } + toggleTabs(panel) { + let pan = this.get(panel) + if (!pan) return + if (pan.show.tabs) this.hideTabs(panel); else this.showTabs(panel) + } + render(box) { + let time = Date.now() + let self = this + if (typeof box == 'string') box = query(box).get(0) + // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + // event before + let edata = this.trigger('render', { target: this.name, box: box ?? this.box }) + if (edata.isCancelled === true) return + // default action + if (box != null) { + // clean previous box + if (query(this.box).find('#layout_'+ this.name +'_panel_main').length > 0) { + query(this.box) + .removeAttr('name') + .removeClass('w2ui-layout') + .html('') + } + this.box = box + } + if (!this.box) return false + // render layout + query(this.box) + .attr('name', this.name) + .addClass('w2ui-layout') + .html('
    ') + if (query(this.box).length > 0) { + query(this.box)[0].style.cssText += this.style + } + // create all panels + for (let p1 = 0; p1 < w2panels.length; p1++) { + let html = '
    '+ + '
    '+ + '
    '+ + '
    '+ + '
    '+ + '
    '+ + '
    ' + query(this.box).find(':scope > div').append(html) + } + query(this.box).find(':scope > div') + .append('
    ') + this.refresh() // if refresh is not called here, the layout will not be available right after initialization + // observe div resize + this.last.observeResize = new ResizeObserver(() => { this.resize() }) + this.last.observeResize.observe(this.box) + // process event + edata.finish() + // re-init events + setTimeout(() => { // needed this timeout to allow browser to render first if there are tabs or toolbar + self.last.events = { resizeStart, mouseMove, mouseUp } + this.resize() + }, 0) + return Date.now() - time + function resizeStart(type, evnt) { + if (!self.box) return + if (!evnt) evnt = window.event + query(document) + .off('mousemove', self.last.events.mouseMove) + .on('mousemove', self.last.events.mouseMove) + query(document) + .off('mouseup', self.last.events.mouseUp) + .on('mouseup', self.last.events.mouseUp) + self.last.resize = { + type : type, + x : evnt.screenX, + y : evnt.screenY, + diff_x : 0, + diff_y : 0, + value : 0 + } + // lock all panels + w2panels.forEach(panel => { + let $tmp = query(self.el(panel)).find('.w2ui-lock') + if ($tmp.length > 0) { + $tmp.data('locked', 'yes') + } else { + self.lock(panel, { opacity: 0 }) + } + }) + let el = query(self.box).find('#layout_'+ self.name +'_resizer_'+ type).get(0) + if (type == 'left' || type == 'right') { + self.last.resize.value = parseInt(el.style.left) + } + if (type == 'top' || type == 'preview' || type == 'bottom') { + self.last.resize.value = parseInt(el.style.top) + } + } + function mouseUp(evnt) { + if (!self.box) return + if (!evnt) evnt = window.event + query(document).off('mousemove', self.last.events.mouseMove) + query(document).off('mouseup', self.last.events.mouseUp) + if (self.last.resize == null) return + // unlock all panels + w2panels.forEach(panel => { + let $tmp = query(self.el(panel)).find('.w2ui-lock') + if ($tmp.data('locked') == 'yes') { + $tmp.removeData('locked') + } else { + self.unlock(panel) + } + }) + // set new size + if (self.last.diff_x !== 0 || self.last.resize.diff_y !== 0) { // only recalculate if changed + let ptop = self.get('top') + let pbottom = self.get('bottom') + let panel = self.get(self.last.resize.type) + let width = w2utils.getSize(query(self.box), 'width') + let height = w2utils.getSize(query(self.box), 'height') + let str = String(panel.size) + let ns, nd + switch (self.last.resize.type) { + case 'top': + ns = parseInt(panel.sizeCalculated) + self.last.resize.diff_y + nd = 0 + break + case 'bottom': + ns = parseInt(panel.sizeCalculated) - self.last.resize.diff_y + nd = 0 + break + case 'preview': + ns = parseInt(panel.sizeCalculated) - self.last.resize.diff_y + nd = (ptop && !ptop.hidden ? ptop.sizeCalculated : 0) + + (pbottom && !pbottom.hidden ? pbottom.sizeCalculated : 0) + break + case 'left': + ns = parseInt(panel.sizeCalculated) + self.last.resize.diff_x + nd = 0 + break + case 'right': + ns = parseInt(panel.sizeCalculated) - self.last.resize.diff_x + nd = 0 + break + } + // set size + if (str.substr(str.length-1) == '%') { + panel.size = Math.floor(ns * 100 / (panel.type == 'left' || panel.type == 'right' ? width : height - nd) * 100) / 100 + '%' + } else { + if (String(panel.size).substr(0, 1) == '-') { + panel.size = parseInt(panel.size) - panel.sizeCalculated + ns + } else { + panel.size = ns + } + } + self.resize() + } + query(self.box) + .find('#layout_'+ self.name + '_resizer_'+ self.last.resize.type) + .removeClass('active') + delete self.last.resize + } + function mouseMove(evnt) { + if (!self.box) return + if (!evnt) evnt = window.event + if (self.last.resize == null) return + let panel = self.get(self.last.resize.type) + // event before + let tmp = self.last.resize + let edata = self.trigger('resizing', { target: self.name, object: panel, originalEvent: evnt, + panel: tmp ? tmp.type : 'all', diff_x: tmp ? tmp.diff_x : 0, diff_y: tmp ? tmp.diff_y : 0 }) + if (edata.isCancelled === true) return + let p = query(self.box).find('#layout_'+ self.name + '_resizer_'+ tmp.type) + let resize_x = (evnt.screenX - tmp.x) + let resize_y = (evnt.screenY - tmp.y) + let mainPanel = self.get('main') + if (!p.hasClass('active')) p.addClass('active') + switch (tmp.type) { + case 'left': + if (panel.minSize - resize_x > panel.width) { + resize_x = panel.minSize - panel.width + } + if (panel.maxSize && (panel.width + resize_x > panel.maxSize)) { + resize_x = panel.maxSize - panel.width + } + if (mainPanel.minSize + resize_x > mainPanel.width) { + resize_x = mainPanel.width - mainPanel.minSize + } + break + case 'right': + if (panel.minSize + resize_x > panel.width) { + resize_x = panel.width - panel.minSize + } + if (panel.maxSize && (panel.width - resize_x > panel.maxSize)) { + resize_x = panel.width - panel.maxSize + } + if (mainPanel.minSize - resize_x > mainPanel.width) { + resize_x = mainPanel.minSize - mainPanel.width + } + break + case 'top': + if (panel.minSize - resize_y > panel.height) { + resize_y = panel.minSize - panel.height + } + if (panel.maxSize && (panel.height + resize_y > panel.maxSize)) { + resize_y = panel.maxSize - panel.height + } + if (mainPanel.minSize + resize_y > mainPanel.height) { + resize_y = mainPanel.height - mainPanel.minSize + } + break + case 'preview': + case 'bottom': + if (panel.minSize + resize_y > panel.height) { + resize_y = panel.height - panel.minSize + } + if (panel.maxSize && (panel.height - resize_y > panel.maxSize)) { + resize_y = panel.height - panel.maxSize + } + if (mainPanel.minSize - resize_y > mainPanel.height) { + resize_y = mainPanel.minSize - mainPanel.height + } + break + } + tmp.diff_x = resize_x + tmp.diff_y = resize_y + switch (tmp.type) { + case 'top': + case 'preview': + case 'bottom': + tmp.diff_x = 0 + if (p.length > 0) p[0].style.top = (tmp.value + tmp.diff_y) + 'px' + break + case 'left': + case 'right': + tmp.diff_y = 0 + if (p.length > 0) p[0].style.left = (tmp.value + tmp.diff_x) + 'px' + break + } + // event after + edata.finish() + } + } + refresh(panel) { + let self = this + // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + if (panel == null) panel = null + let time = Date.now() + // event before + let edata = self.trigger('refresh', { target: (panel != null ? panel : self.name), object: self.get(panel) }) + if (edata.isCancelled === true) return + // self.unlock(panel); + if (typeof panel == 'string') { + let p = self.get(panel) + if (p == null) return + let pname = '#layout_'+ self.name + '_panel_'+ p.type + let rname = '#layout_'+ self.name +'_resizer_'+ p.type + // apply properties to the panel + query(self.box).find(pname).css({ display: p.hidden ? 'none' : 'block' }) + if (p.resizable) { + query(self.box).find(rname).show() + } else { + query(self.box).find(rname).hide() + } + // insert content + if (typeof p.html == 'object' && typeof p.html.render === 'function') { + p.html.box = query(self.box).find(pname +'> .w2ui-panel-content')[0] + setTimeout(() => { + // need to remove unnecessary classes + if (query(self.box).find(pname +'> .w2ui-panel-content').length > 0) { + query(self.box).find(pname +'> .w2ui-panel-content') + .removeClass() + .removeAttr('name') + .addClass('w2ui-panel-content') + .css('overflow', p.overflow)[0].style.cssText += ';' + p.style + } + if (p.html && typeof p.html.render == 'function') { + p.html.render() // do not do .render(box); + } + }, 1) + } else { + // need to remove unnecessary classes + if (query(self.box).find(pname +'> .w2ui-panel-content').length > 0) { + query(self.box).find(pname +'> .w2ui-panel-content') + .removeClass() + .removeAttr('name') + .addClass('w2ui-panel-content') + .html(p.html) + .css('overflow', p.overflow)[0].style.cssText += ';' + p.style + } + } + // if there are tabs and/or toolbar - render it + let tmp = query(self.box).find(pname +'> .w2ui-panel-tabs') + if (p.show.tabs) { + if (tmp.find('[name='+ p.tabs.name +']').length === 0 && p.tabs != null) { + p.tabs.render(tmp.get(0)) + } else { + p.tabs.refresh() + } + } else { + tmp.html('').removeClass('w2ui-tabs').hide() + } + tmp = query(self.box).find(pname +'> .w2ui-panel-toolbar') + if (p.show.toolbar) { + if (tmp.find('[name='+ p.toolbar.name +']').length === 0 && p.toolbar != null) { + p.toolbar.render(tmp.get(0)) + } else { + p.toolbar.refresh() + } + } else { + tmp.html('').removeClass('w2ui-toolbar').hide() + } + // show title + tmp = query(self.box).find(pname +'> .w2ui-panel-title') + if (p.title) { + tmp.html(p.title).show() + } else { + tmp.html('').hide() + } + } else { + if (query(self.box).find('#layout_'+ self.name +'_panel_main').length === 0) { + self.render() + return + } + self.resize() + // refresh all of them + for (let p1 = 0; p1 < this.panels.length; p1++) { self.refresh(this.panels[p1].type) } + } + edata.finish() + return Date.now() - time + } + resize() { + // if (window.getSelection) window.getSelection().removeAllRanges(); // clear selection + if (!this.box) return false + let time = Date.now() + // event before + let tmp = this.last.resize + let edata = this.trigger('resize', { target: this.name, + panel: tmp ? tmp.type : 'all', diff_x: tmp ? tmp.diff_x : 0, diff_y: tmp ? tmp.diff_y : 0 }) + if (edata.isCancelled === true) return + if (this.padding < 0) this.padding = 0 + // layout itself + // width includes border and padding, we need to exclude that so panels + // are sized correctly + let width = w2utils.getSize(query(this.box), 'width') + let height = w2utils.getSize(query(this.box), 'height') + let self = this + // panels + let pmain = this.get('main') + let pprev = this.get('preview') + let pleft = this.get('left') + let pright = this.get('right') + let ptop = this.get('top') + let pbottom = this.get('bottom') + let sprev = (pprev != null && pprev.hidden !== true ? true : false) + let sleft = (pleft != null && pleft.hidden !== true ? true : false) + let sright = (pright != null && pright.hidden !== true ? true : false) + let stop = (ptop != null && ptop.hidden !== true ? true : false) + let sbottom = (pbottom != null && pbottom.hidden !== true ? true : false) + let l, t, w, h + // calculate % + for (let p = 0; p < w2panels.length; p++) { + if (w2panels[p] === 'main') continue + tmp = this.get(w2panels[p]) + if (!tmp) continue + let str = String(tmp.size || 0) + if (str.substr(str.length-1) == '%') { + let tmph = height + if (tmp.type == 'preview') { + tmph = tmph - + (ptop && !ptop.hidden ? ptop.sizeCalculated : 0) - + (pbottom && !pbottom.hidden ? pbottom.sizeCalculated : 0) + } + tmp.sizeCalculated = parseInt((tmp.type == 'left' || tmp.type == 'right' ? width : tmph) * parseFloat(tmp.size) / 100) + } else { + tmp.sizeCalculated = parseInt(tmp.size) + } + tmp.sizeCalculated = Math.max(tmp.sizeCalculated, parseInt(tmp.minSize)) + } + // negative size + if (String(pright.size).substr(0, 1) == '-') { + if (sleft && String(pleft.size).substr(0, 1) == '-') { + console.log('ERROR: you cannot have both left panel.size and right panel.size be negative.') + } else { + pright.sizeCalculated = width - (sleft ? pleft.sizeCalculated : 0) + parseInt(pright.size) + } + } + if (String(pleft.size).substr(0, 1) == '-') { + if (sright && String(pright.size).substr(0, 1) == '-') { + console.log('ERROR: you cannot have both left panel.size and right panel.size be negative.') + } else { + pleft.sizeCalculated = width - (sright ? pright.sizeCalculated : 0) + parseInt(pleft.size) + } + } + // top if any + if (ptop != null && ptop.hidden !== true) { + l = 0 + t = 0 + w = width + h = ptop.sizeCalculated + query(this.box).find('#layout_'+ this.name +'_panel_top') + .css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px' + }) + ptop.width = w + ptop.height = h + // resizer + if (ptop.resizable) { + t = ptop.sizeCalculated - (this.padding === 0 ? this.resizer : 0) + h = (this.resizer > this.padding ? this.resizer : this.padding) + query(this.box).find('#layout_'+ this.name +'_resizer_top') + .css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px', + 'cursor': 'ns-resize' + }) + .off('mousedown') + .on('mousedown', function(event) { + event.preventDefault() + // event before + let edata = self.trigger('resizerClick', { target: 'top', originalEvent: event }) + if (edata.isCancelled === true) return + // default action + w2ui[self.name].last.events.resizeStart('top', event) + // event after + edata.finish() + return false + }) + } + } else { + query(this.box).find('#layout_'+ this.name +'_panel_top').hide() + query(this.box).find('#layout_'+ this.name +'_resizer_top').hide() + } + // left if any + if (pleft != null && pleft.hidden !== true) { + l = 0 + t = 0 + (stop ? ptop.sizeCalculated + this.padding : 0) + w = pleft.sizeCalculated + h = height - (stop ? ptop.sizeCalculated + this.padding : 0) - + (sbottom ? pbottom.sizeCalculated + this.padding : 0) + query(this.box).find('#layout_'+ this.name +'_panel_left') + .css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px' + }) + pleft.width = w + pleft.height = h + // resizer + if (pleft.resizable) { + l = pleft.sizeCalculated - (this.padding === 0 ? this.resizer : 0) + w = (this.resizer > this.padding ? this.resizer : this.padding) + query(this.box).find('#layout_'+ this.name +'_resizer_left') + .css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px', + 'cursor': 'ew-resize' + }) + .off('mousedown') + .on('mousedown', function(event) { + event.preventDefault() + // event before + let edata = self.trigger('resizerClick', { target: 'left', originalEvent: event }) + if (edata.isCancelled === true) return + // default action + w2ui[self.name].last.events.resizeStart('left', event) + // event after + edata.finish() + return false + }) + } + } else { + query(this.box).find('#layout_'+ this.name +'_panel_left').hide() + query(this.box).find('#layout_'+ this.name +'_resizer_left').hide() + } + // right if any + if (pright != null && pright.hidden !== true) { + l = width - pright.sizeCalculated + t = 0 + (stop ? ptop.sizeCalculated + this.padding : 0) + w = pright.sizeCalculated + h = height - (stop ? ptop.sizeCalculated + this.padding : 0) - + (sbottom ? pbottom.sizeCalculated + this.padding : 0) + query(this.box).find('#layout_'+ this.name +'_panel_right') + .css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px' + }) + pright.width = w + pright.height = h + // resizer + if (pright.resizable) { + l = l - this.padding + w = (this.resizer > this.padding ? this.resizer : this.padding) + query(this.box).find('#layout_'+ this.name +'_resizer_right') + .css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px', + 'cursor': 'ew-resize' + }) + .off('mousedown') + .on('mousedown', function(event) { + event.preventDefault() + // event before + let edata = self.trigger('resizerClick', { target: 'right', originalEvent: event }) + if (edata.isCancelled === true) return + // default action + w2ui[self.name].last.events.resizeStart('right', event) + // event after + edata.finish() + return false + }) + } + } else { + query(this.box).find('#layout_'+ this.name +'_panel_right').hide() + query(this.box).find('#layout_'+ this.name +'_resizer_right').hide() + } + // bottom if any + if (pbottom != null && pbottom.hidden !== true) { + l = 0 + t = height - pbottom.sizeCalculated + w = width + h = pbottom.sizeCalculated + query(this.box).find('#layout_'+ this.name +'_panel_bottom') + .css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px' + }) + pbottom.width = w + pbottom.height = h + // resizer + if (pbottom.resizable) { + t = t - (this.padding === 0 ? 0 : this.padding) + h = (this.resizer > this.padding ? this.resizer : this.padding) + query(this.box).find('#layout_'+ this.name +'_resizer_bottom') + .css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px', + 'cursor': 'ns-resize' + }) + .off('mousedown') + .on('mousedown', function(event) { + event.preventDefault() + // event before + let edata = self.trigger('resizerClick', { target: 'bottom', originalEvent: event }) + if (edata.isCancelled === true) return + // default action + w2ui[self.name].last.events.resizeStart('bottom', event) + // event after + edata.finish() + return false + }) + } + } else { + query(this.box).find('#layout_'+ this.name +'_panel_bottom').hide() + query(this.box).find('#layout_'+ this.name +'_resizer_bottom').hide() + } + // main - always there + l = 0 + (sleft ? pleft.sizeCalculated + this.padding : 0) + t = 0 + (stop ? ptop.sizeCalculated + this.padding : 0) + w = width - (sleft ? pleft.sizeCalculated + this.padding : 0) - + (sright ? pright.sizeCalculated + this.padding: 0) + h = height - (stop ? ptop.sizeCalculated + this.padding : 0) - + (sbottom ? pbottom.sizeCalculated + this.padding : 0) - + (sprev ? pprev.sizeCalculated + this.padding : 0) + query(this.box) + .find('#layout_'+ this.name +'_panel_main') + .css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px' + }) + pmain.width = w + pmain.height = h + // preview if any + if (pprev != null && pprev.hidden !== true) { + l = 0 + (sleft ? pleft.sizeCalculated + this.padding : 0) + t = height - (sbottom ? pbottom.sizeCalculated + this.padding : 0) - pprev.sizeCalculated + w = width - (sleft ? pleft.sizeCalculated + this.padding : 0) - + (sright ? pright.sizeCalculated + this.padding : 0) + h = pprev.sizeCalculated + query(this.box).find('#layout_'+ this.name +'_panel_preview') + .css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px' + }) + pprev.width = w + pprev.height = h + // resizer + if (pprev.resizable) { + t = t - (this.padding === 0 ? 0 : this.padding) + h = (this.resizer > this.padding ? this.resizer : this.padding) + query(this.box).find('#layout_'+ this.name +'_resizer_preview') + .css({ + 'display': 'block', + 'left': l + 'px', + 'top': t + 'px', + 'width': w + 'px', + 'height': h + 'px', + 'cursor': 'ns-resize' + }) + .off('mousedown') + .on('mousedown', function(event) { + event.preventDefault() + // event before + let edata = self.trigger('resizerClick', { target: 'preview', originalEvent: event }) + if (edata.isCancelled === true) return + // default action + w2ui[self.name].last.events.resizeStart('preview', event) + // event after + edata.finish() + return false + }) + } + } else { + query(this.box).find('#layout_'+ this.name +'_panel_preview').hide() + query(this.box).find('#layout_'+ this.name +'_resizer_preview').hide() + } + // display tabs and toolbar if needed + for (let p1 = 0; p1 < w2panels.length; p1++) { + let pan = this.get(w2panels[p1]) + let tmp2 = '#layout_'+ this.name +'_panel_'+ w2panels[p1] +' > .w2ui-panel-' + let tabHeight = 0 + if (pan) { + if (pan.title) { + let el = query(this.box).find(tmp2 + 'title').css({ top: tabHeight + 'px', display: 'block' }) + tabHeight += w2utils.getSize(el, 'height') + } + if (pan.show.tabs) { + let el = query(this.box).find(tmp2 + 'tabs').css({ top: tabHeight + 'px', display: 'block' }) + tabHeight += w2utils.getSize(el, 'height') + } + if (pan.show.toolbar) { + let el = query(this.box).find(tmp2 + 'toolbar').css({ top: tabHeight + 'px', display: 'block' }) + tabHeight += w2utils.getSize(el, 'height') + } + } + query(this.box).find(tmp2 + 'content').css({ display: 'block' }).css({ top: tabHeight + 'px' }) + } + edata.finish() + return Date.now() - time + } + destroy() { + // event before + let edata = this.trigger('destroy', { target: this.name }) + if (edata.isCancelled === true) return + if (w2ui[this.name] == null) return false + // clean up + if (query(this.box).find('#layout_'+ this.name +'_panel_main').length > 0) { + query(this.box) + .removeAttr('name') + .removeClass('w2ui-layout') + .html('') + } + this.last.observeResize?.disconnect() + delete w2ui[this.name] + // event after + edata.finish() + if (this.last.events && this.last.events.resize) { + query(window).off('resize', this.last.events.resize) + } + return true + } + lock(panel, msg, showSpinner) { + if (w2panels.indexOf(panel) == -1) { + console.log('ERROR: First parameter needs to be the a valid panel name.') + return + } + let args = Array.from(arguments) + args[0] = '#layout_'+ this.name + '_panel_' + panel + w2utils.lock(...args) + } + unlock(panel, speed) { + if (w2panels.indexOf(panel) == -1) { + console.log('ERROR: First parameter needs to be the a valid panel name.') + return + } + let nm = '#layout_'+ this.name + '_panel_' + panel + w2utils.unlock(nm, speed) + } +} +/** + * Part of w2ui 2.0 library + * - Dependencies: jQuery, w2utils, w2base, w2toolbar, w2field + * + * == TODO == + * - problem with .set() and arrays, array get extended too, but should be replaced + * - allow functions in routeData (also add routeData to list/enum) + * - send parsed URL to the event if there is routeData + * - add selectType: 'none' so that no selection can be make but with mouse + * - focus/blur for selectType = cell not display grayed out selection + * - allow enum in inline edit (see https://github.com/vitmalina/w2ui/issues/911#issuecomment-107341193) + * - remote source, but localSort/localSearch + * - promise for request, load, save, etc. + * - onloadmore event (so it will be easy to implement remote data source with local sort) + * - status() - clears on next select, etc. Should not if it is off + * + * == DEMOS To create == + * - batch for disabled buttons + * - natural sort + * - resize on max content + * + * == 2.0 changes + * - toolbarInput - deprecated, toolbarSearch stays + * - searchSuggest + * - searchSave, searchSelected, savedSearches, defaultSearches, useLocalStorage, searchFieldTooltip + * - cache, cacheSave + * - onSearchSave, onSearchRemove, onSearchSelect + * - show.searchLogic + * - show.searchSave + * - refreshSearch + * - initAllFields -> searchInitInput + * - textSearch - deprecated in favor of defaultOperator + * - grid.confirm - refactored + * - grid.message - refactored + * - search.type == 'text' can have 'in' and 'not in' operators, then it will switch to enum + * - grid.find(..., displayedOnly) + * - column.render(..., this) - added + * - observeResize for the box + * - remove edit.type == 'select' + * - editDone(...) + * - liveSearch + * - deprecated onUnselect event + * - requestComplete(data, action, callBack, resolve, reject) - new argument list + * - msgAJAXError -> msgHTTPError + * - aded msgServerError + * - deleted grid.method + * - added mouseEnter/mouseLeave + * - grid.show.columnReorder -> grid.reorderRows + * - updagte docs search.label (not search.text) + */ + +class w2grid extends w2base { + constructor(options) { + super(options.name) + this.name = null + this.box = null // HTML element that hold this element + this.columns = [] // { field, text, size, attr, render, hidden, gridMinWidth, editable } + this.columnGroups = [] // { span: int, text: 'string', main: true/false, style: 'string' } + this.records = [] // { recid: int(required), field1: 'value1', ... fieldN: 'valueN', style: 'string', changes: object } + this.summary = [] // array of summary records, same structure as records array + this.searches = [] // { type, label, field, attr, text, hidden } + this.toolbar = {} // if not empty object; then it is toolbar object + this.ranges = [] + this.contextMenu = [] + this.searchMap = {} // re-map search fields + this.searchData = [] + this.sortMap = {} // re-map sort fields + this.sortData = [] + this.savedSearches = [] + this.defaultSearches = [] + this.total = 0 // server total + this.recid = null // field from records to be used as recid + // internal + this.last = { + field : '', // last search field, e.g. 'all' + label : '', // last search field label, e.g. 'All Fields' + logic : 'AND', // last search logic, e.g. 'AND' or 'OR' + search : '', // last search text + searchIds : [], // last search IDs + selection : { // last selection details + indexes : [], + columns : {} + }, + saved_sel : null, // last result of selectionSave() + multi : false, // last multi flag, true when searching for multiple fields + scrollTop : 0, // last scrollTop position + scrollLeft : 0, // last scrollLeft position + colStart : 0, // for column virtual scrolling + colEnd : 0, // for column virtual scrolling + fetch: { + action : '', // last fetch command, e.g. 'load' + offset : null, // last fetch offset, integer + start : 0, // timestamp of start of last fetch request + response : 0, // time it took to complete the last fetch request in seconds + options : null, + controller: null, + loaded : false, // data is loaded from the server + hasMore : false // flag to indicate if there are more items to pull from the server + }, + pull_more : false, + pull_refresh : true, + range_start : null, // last range start cell + range_end : null, // last range end cell + sel_ind : null, // last selected cell index + sel_col : null, // last selected column + sel_type : null, // last selection type, e.g. 'click' or 'key' + sel_recid : null, // last selected record id + idCache : {}, // object, id cache for get() + move : null, // object, move details + cancelClick : null, // boolean flag to indicate if the click event should be ignored, set during mouseMove() + inEditMode : false, // flag to indicate if we're currently in edit mode during inline editing + _edit : null, // object with details on the last edited cell, { value, index, column, recid } + kbd_timer : null, // last id of blur() timer + marker_timer : null, // last id of markSearch() timer + click_time : null, // timestamp of last click + click_recid : null, // last clicked record id + bubbleEl : null, // last bubble element + colResizing : false, // flag to indicate that a column is currently being resized + tmp : null, // object with last column resizing details + copy_event : null, // last copy event + userSelect : '', // last user select type, e.g. 'text' + columnDrag : false, // false or an object with a remove() method + state : null, // last grid state + show_extra : 0, // last show extra for virtual scrolling + toolbar_height: 0, // height of grid's toolbar + } + this.header = '' + this.url = '' + this.limit = 100 + this.offset = 0 // how many records to skip (for infinite scroll) when pulling from server + this.postData = {} + this.routeData = {} + this.httpHeaders = {} + this.show = { + header : false, + toolbar : false, + footer : false, + columnMenu : true, + columnHeaders : true, + lineNumbers : false, + expandColumn : false, + selectColumn : false, + emptyRecords : true, + toolbarReload : true, + toolbarColumns : false, + toolbarSearch : true, + toolbarAdd : false, + toolbarEdit : false, + toolbarDelete : false, + toolbarSave : false, + searchAll : true, + searchLogic : true, + searchHiddenMsg : false, + searchSave : true, + statusRange : true, + statusBuffered : false, + statusRecordID : true, + statusSelection : true, + statusResponse : true, + statusSort : false, + statusSearch : false, + recordTitles : false, + selectionBorder : true, + skipRecords : true, + saveRestoreState: true + } + this.stateId = null // Custom state name for stateSave, stateRestore and stateReset + this.hasFocus = false + this.autoLoad = true // for infinite scroll + this.fixedBody = true // if false; then grid grows with data + this.recordHeight = 32 + this.lineNumberWidth = 34 + this.keyboard = true + this.selectType = 'row' // can be row|cell + this.liveSearch = false // if true, it will auto search if typed in search_all + this.multiSearch = true + this.multiSelect = true + this.multiSort = true + this.reorderColumns = false + this.reorderRows = false + this.showExtraOnSearch = 0 // show extra records before and after on search + this.markSearch = true + this.columnTooltip = 'top|bottom' // can be top, bottom, left, right + this.disableCVS = false // disable Column Virtual Scroll + this.nestedFields = true // use field name containing dots as separator to look into object + this.vs_start = 150 + this.vs_extra = 5 + this.style = '' + this.tabIndex = null + this.dataType = null // if defined, then overwrites w2utils.settings.dataType + this.parser = null + this.advanceOnEdit = true // automatically begin editing the next cell after submitting an inline edit? + this.useLocalStorage = true + // default values for the column + this.colTemplate = { + text : '', // column text (can be a function) + field : '', // field name to map the column to a record + size : null, // size of column in px or % + min : 20, // minimum width of column in px + max : null, // maximum width of column in px + gridMinWidth : null, // minimum width of the grid when column is visible + sizeCorrected : null, // read only, corrected size (see explanation below) + sizeCalculated : null, // read only, size in px (see explanation below) + sizeOriginal : null, // size as defined + sizeType : null, // px or % + hidden : false, // indicates if column is hidden + sortable : false, // indicates if column is sortable + sortMode : null, // sort mode ('default'|'natural'|'i18n') or custom compare function + searchable : false, // bool/string: int,float,date,... or an object to create search field + resizable : true, // indicates if column is resizable + hideable : true, // indicates if column can be hidden + autoResize : null, // indicates if column can be auto-resized by double clicking on the resizer + attr : '', // string that will be inside the tag + style : '', // additional style for the td tag + render : null, // string or render function + title : null, // string or function for the title property for the column cells + tooltip : null, // string for the title property for the column header + editable : {}, // editable object (see explanation below) + frozen : false, // indicates if the column is fixed to the left + info : null, // info bubble, can be bool/object + clipboardCopy : false, // if true (or string or function), it will display clipboard copy icon + } + // these column properties will be saved in stateSave() + this.stateColProps = { + text : false, + field : true, + size : true, + min : false, + max : false, + gridMinWidth : false, + sizeCorrected : false, + sizeCalculated : true, + sizeOriginal : true, + sizeType : true, + hidden : true, + sortable : false, + sortMode : true, + searchable : false, + resizable : false, + hideable : false, + autoResize : false, + attr : false, + style : false, + render : false, + title : false, + tooltip : false, + editable : false, + frozen : true, + info : false, + clipboardCopy : false + } + this.msgDelete = 'Are you sure you want to delete ${count} ${records}?' + this.msgNotJSON = 'Returned data is not in valid JSON format.' + this.msgHTTPError = 'HTTP error. See console for more details.' + this.msgServerError= 'Server error' + this.msgRefresh = 'Refreshing...' + this.msgNeedReload = 'Your remote data source record count has changed, reloading from the first record.' + this.msgEmpty = '' // if not blank, then it is message when server returns no records + this.buttons = { + 'reload' : { type: 'button', id: 'w2ui-reload', icon: 'w2ui-icon-reload', tooltip: 'Reload data in the list' }, + 'columns' : { type: 'menu-check', id: 'w2ui-column-on-off', icon: 'w2ui-icon-columns', tooltip: 'Show/hide columns', + overlay: { align: 'none' } + }, + 'search' : { type: 'html', id: 'w2ui-search', + html: '' + }, + 'add' : { type: 'button', id: 'w2ui-add', text: 'Add New', tooltip: 'Add new record', icon: 'w2ui-icon-plus' }, + 'edit' : { type: 'button', id: 'w2ui-edit', text: 'Edit', tooltip: 'Edit selected record', icon: 'w2ui-icon-pencil', batch: 1, disabled: true }, + 'delete' : { type: 'button', id: 'w2ui-delete', text: 'Delete', tooltip: 'Delete selected records', icon: 'w2ui-icon-cross', batch: true, disabled: true }, + 'save' : { type: 'button', id: 'w2ui-save', text: 'Save', tooltip: 'Save changed records', icon: 'w2ui-icon-check' } + } + this.operators = { // for search fields + 'text' : ['is', 'begins', 'contains', 'ends'], // could have "in" and "not in" + 'number' : ['=', 'between', '>', '<', '>=', '<='], + 'date' : ['is', { oper: 'less', text: 'before'}, { oper: 'more', text: 'since' }, 'between'], + 'list' : ['is'], + 'hex' : ['is', 'between'], + 'color' : ['is', 'begins', 'contains', 'ends'], + 'enum' : ['in', 'not in'] + // -- all possible + // "text" : ['is', 'begins', 'contains', 'ends'], + // "number" : ['is', 'between', 'less:less than', 'more:more than', 'null:is null', 'not null:is not null'], + // "list" : ['is', 'null:is null', 'not null:is not null'], + // "enum" : ['in', 'not in', 'null:is null', 'not null:is not null'] + } + this.defaultOperator = { + 'text' : 'begins', + 'number' : '=', + 'date' : 'is', + 'list' : 'is', + 'enum' : 'in', + 'hex' : 'begins', + 'color' : 'begins' + } + // map search field type to operator + this.operatorsMap = { + 'text' : 'text', + 'int' : 'number', + 'float' : 'number', + 'money' : 'number', + 'currency' : 'number', + 'percent' : 'number', + 'hex' : 'hex', + 'alphanumeric' : 'text', + 'color' : 'color', + 'date' : 'date', + 'time' : 'date', + 'datetime' : 'date', + 'list' : 'list', + 'combo' : 'text', + 'enum' : 'enum', + 'file' : 'enum', + 'select' : 'list', + 'radio' : 'list', + 'checkbox' : 'list', + 'toggle' : 'list' + } + // events + this.onAdd = null + this.onEdit = null + this.onRequest = null // called on any server event + this.onLoad = null + this.onDelete = null + this.onSave = null + this.onSelect = null + this.onClick = null + this.onDblClick = null + this.onContextMenu = null + this.onContextMenuClick = null // when context menu item selected + this.onColumnClick = null + this.onColumnDblClick = null + this.onColumnContextMenu = null + this.onColumnResize = null + this.onColumnAutoResize = null + this.onSort = null + this.onSearch = null + this.onSearchOpen = null + this.onChange = null // called when editable record is changed + this.onRestore = null // called when editable record is restored + this.onExpand = null + this.onCollapse = null + this.onError = null + this.onKeydown = null + this.onToolbar = null // all events from toolbar + this.onColumnOnOff = null + this.onCopy = null + this.onPaste = null + this.onSelectionExtend = null + this.onEditField = null + this.onRender = null + this.onRefresh = null + this.onReload = null + this.onResize = null + this.onDestroy = null + this.onStateSave = null + this.onStateRestore = null + this.onFocus = null + this.onBlur = null + this.onReorderRow = null + this.onSearchSave = null + this.onSearchRemove = null + this.onSearchSelect = null + this.onColumnSelect = null + this.onColumnDragStart = null + this.onColumnDragEnd = null + this.onResizerDblClick = null + this.onMouseEnter = null // mouse enter over record event + this.onMouseLeave = null + // need deep merge, should be extend, not objectAssign + w2utils.extend(this, options) + // check if there are records without recid + if (Array.isArray(this.records)) { + let remove = [] // remove from records as they are summary + this.records.forEach((rec, ind) => { + if (rec[this.recid] != null) { + rec.recid = rec[this.recid] + } + if (rec.recid == null) { + console.log('ERROR: Cannot add records without recid. (obj: '+ this.name +')') + } + if (rec.w2ui?.summary === true) { + this.summary.push(rec) + remove.push(ind) // cannot remove here as it will mess up array walk thru + } + }) + remove.sort() + for (let t = remove.length-1; t >= 0; t--) { + this.records.splice(remove[t], 1) + } + } + // add searches + if (Array.isArray(this.columns)) { + this.columns.forEach((col, ind) => { + col = w2utils.extend({}, this.colTemplate, col) + this.columns[ind] = col + let search = col.searchable + if (search == null || search === false || this.getSearch(col.field) != null) return + if (w2utils.isPlainObject(search)) { + this.addSearch(w2utils.extend({ field: col.field, label: col.text, type: 'text' }, search)) + } else { + let stype = col.searchable + let attr = '' + if (col.searchable === true) { + stype = 'text' + attr = 'size="20"' + } + this.addSearch({ field: col.field, label: col.text, type: stype, attr: attr }) + } + }) + } + // add icon to default searches if not defined + if (Array.isArray(this.defaultSearches)) { + this.defaultSearches.forEach((search, ind) => { + search.id = 'default-'+ ind + search.icon ??= 'w2ui-icon-search' + }) + } + // check if there are saved searches in localStorage + let data = this.cache('searches') + if (Array.isArray(data)) { + data.forEach(search => { + this.savedSearches.push({ + id: search.id ?? 'none', + text: search.text ?? 'none', + icon: 'w2ui-icon-search', + remove: true, + logic: search.logic ?? 'AND', + data: search.data ?? [] + }) + }) + } + // render if box specified + if (typeof this.box == 'string') this.box = query(this.box).get(0) + if (this.box) this.render(this.box) + } + add(record, first) { + if (!Array.isArray(record)) record = [record] + let added = 0 + for (let i = 0; i < record.length; i++) { + let rec = record[i] + if (rec[this.recid] != null) { + rec.recid = rec[this.recid] + } + if (rec.recid == null) { + console.log('ERROR: Cannot add record without recid. (obj: '+ this.name +')') + continue + } + if (rec.w2ui?.summary === true) { + if (first) this.summary.unshift(rec); else this.summary.push(rec) + } else { + if (first) this.records.unshift(rec); else this.records.push(rec) + } + added++ + } + let url = this.url?.get ?? this.url + if (!url) { + this.total = this.records.length + this.localSort(false, true) + this.localSearch() + // do not call this.refresh(), this is unnecessary, heavy, and messes with the toolbar. + // this.refreshBody() + // this.resizeRecords() + this.refresh() + } else { + this.refresh() // ?? should it be reload? + } + return added + } + find(obj, returnIndex, displayedOnly) { + if (obj == null) obj = {} + let recs = [] + let hasDots = false + // check if property is nested - needed for speed + for (let o in obj) if (String(o).indexOf('.') != -1) hasDots = true + // look for an item + let start = displayedOnly ? this.last.range_start : 0 + let end = displayedOnly ? this.last.range_end + 1: this.records.length + if (end > this.records.length) end = this.records.length + for (let i = start; i < end; i++) { + let match = true + for (let o in obj) { + let val = this.records[i][o] + if (hasDots && String(o).indexOf('.') != -1) val = this.parseField(this.records[i], o) + if (obj[o] == 'not-null') { + if (val == null || val === '') match = false + } else { + if (obj[o] != val) match = false + } + } + if (match && returnIndex !== true) recs.push(this.records[i].recid) + if (match && returnIndex === true) recs.push(i) + } + return recs + } + set(recid, record, noRefresh) { // does not delete existing, but overrides on top of it + if ((typeof recid == 'object') && (recid !== null)) { + noRefresh = record + record = recid + recid = null + } + // update all records + if (recid == null) { + for (let i = 0; i < this.records.length; i++) { + w2utils.extend(this.records[i], record) // recid is the whole record + } + if (noRefresh !== true) this.refresh() + } else { // find record to update + let ind = this.get(recid, true) + if (ind == null) return false + let isSummary = (this.records[ind] && this.records[ind].recid == recid ? false : true) + if (isSummary) { + w2utils.extend(this.summary[ind], record) + } else { + w2utils.extend(this.records[ind], record) + } + if (noRefresh !== true) this.refreshRow(recid, ind) // refresh only that record + } + return true + } + get(recid, returnIndex) { + // search records + if (Array.isArray(recid)) { + let recs = [] + for (let i = 0; i < recid.length; i++) { + let v = this.get(recid[i], returnIndex) + if (v !== null) + recs.push(v) + } + return recs + } else { + // get() must be fast, implements a cache to bypass loop over all records + // most of the time. + let idCache = this.last.idCache + if (!idCache) { + this.last.idCache = idCache = {} + } + let i = idCache[recid] + if (typeof(i) === 'number') { + if (i >= 0 && i < this.records.length && this.records[i].recid == recid) { + if (returnIndex === true) return i; else return this.records[i] + } + // summary indexes are stored as negative numbers, try them now. + i = ~i + if (i >= 0 && i < this.summary.length && this.summary[i].recid == recid) { + if (returnIndex === true) return i; else return this.summary[i] + } + // wrong index returned, clear cache + this.last.idCache = idCache = {} + } + for (let i = 0; i < this.records.length; i++) { + if (this.records[i].recid == recid) { + idCache[recid] = i + if (returnIndex === true) return i; else return this.records[i] + } + } + // search summary + for (let i = 0; i < this.summary.length; i++) { + if (this.summary[i].recid == recid) { + idCache[recid] = ~i + if (returnIndex === true) return i; else return this.summary[i] + } + } + return null + } + } + getFirst(offset) { + if (this.records.length == 0) return null + let rec = this.records[0] + let tmp = this.last.searchIds + if (this.searchData.length > 0) { + if (Array.isArray(tmp) && tmp.length > 0) { + rec = this.records[tmp[offset || 0]] + } else { + rec = null + } + } + return rec + } + remove() { + let removed = 0 + for (let a = 0; a < arguments.length; a++) { + for (let r = this.records.length-1; r >= 0; r--) { + if (this.records[r].recid == arguments[a]) { this.records.splice(r, 1); removed++ } + } + for (let r = this.summary.length-1; r >= 0; r--) { + if (this.summary[r].recid == arguments[a]) { this.summary.splice(r, 1); removed++ } + } + } + let url = this.url?.get ?? this.url + if (!url) { + this.localSort(false, true) + this.localSearch() + } + this.refresh() + return removed + } + addColumn(before, columns) { + let added = 0 + if (arguments.length == 1) { + columns = before + before = this.columns.length + } else { + if (typeof before == 'string') before = this.getColumn(before, true) + if (before == null) before = this.columns.length + } + if (!Array.isArray(columns)) columns = [columns] + for (let i = 0; i < columns.length; i++) { + let col = w2utils.extend({}, this.colTemplate, columns[i]) + this.columns.splice(before, 0, col) + // if column is searchable, add search field + if (columns[i].searchable) { + let stype = columns[i].searchable + let attr = '' + if (columns[i].searchable === true) { stype = 'text'; attr = 'size="20"' } + this.addSearch({ field: columns[i].field, label: columns[i].text, type: stype, attr: attr }) + } + before++ + added++ + } + this.refresh() + return added + } + removeColumn() { + let removed = 0 + for (let a = 0; a < arguments.length; a++) { + for (let r = this.columns.length-1; r >= 0; r--) { + if (this.columns[r].field == arguments[a]) { + if (this.columns[r].searchable) this.removeSearch(arguments[a]) + this.columns.splice(r, 1) + removed++ + } + } + } + this.refresh() + return removed + } + getColumn(field, returnIndex) { + // no arguments - return fields of all columns + if (arguments.length === 0) { + let ret = [] + for (let i = 0; i < this.columns.length; i++) ret.push(this.columns[i].field) + return ret + } + // find column + for (let i = 0; i < this.columns.length; i++) { + if (this.columns[i].field == field) { + if (returnIndex === true) return i; else return this.columns[i] + } + } + return null + } + updateColumn(fields, updates) { + let effected = 0 + fields = (Array.isArray(fields) ? fields : [fields]) + fields.forEach((colName) => { + this.columns.forEach((col) => { + if (col.field == colName) { + let _updates = w2utils.clone(updates) + Object.keys(_updates).forEach((key) => { + // if it is a function + if (typeof _updates[key] == 'function') { + _updates[key] = _updates[key](col) + } + if (col[key] != _updates[key]) effected++ + }) + w2utils.extend(col, _updates) + } + }) + }) + if (effected > 0) { + this.refresh() // need full refresh due to colgroups not reassigning properly + } + return effected + } + toggleColumn() { + return this.updateColumn(Array.from(arguments), { hidden(col) { return !col.hidden } }) + } + showColumn() { + return this.updateColumn(Array.from(arguments), { hidden: false }) + } + hideColumn() { + return this.updateColumn(Array.from(arguments), { hidden: true }) + } + addSearch(before, search) { + let added = 0 + if (arguments.length == 1) { + search = before + before = this.searches.length + } else { + if (typeof before == 'string') before = this.getSearch(before, true) + if (before == null) before = this.searches.length + } + if (!Array.isArray(search)) search = [search] + for (let i = 0; i < search.length; i++) { + this.searches.splice(before, 0, search[i]) + before++ + added++ + } + this.searchClose() + return added + } + removeSearch() { + let removed = 0 + for (let a = 0; a < arguments.length; a++) { + for (let r = this.searches.length-1; r >= 0; r--) { + if (this.searches[r].field == arguments[a]) { this.searches.splice(r, 1); removed++ } + } + } + this.searchClose() + return removed + } + getSearch(field, returnIndex) { + // no arguments - return fields of all searches + if (arguments.length === 0) { + let ret = [] + for (let i = 0; i < this.searches.length; i++) ret.push(this.searches[i].field) + return ret + } + // find search + for (let i = 0; i < this.searches.length; i++) { + if (this.searches[i].field == field) { + if (returnIndex === true) return i; else return this.searches[i] + } + } + return null + } + toggleSearch() { + let effected = 0 + for (let a = 0; a < arguments.length; a++) { + for (let r = this.searches.length-1; r >= 0; r--) { + if (this.searches[r].field == arguments[a]) { + this.searches[r].hidden = !this.searches[r].hidden + effected++ + } + } + } + this.searchClose() + return effected + } + showSearch() { + let shown = 0 + for (let a = 0; a < arguments.length; a++) { + for (let r = this.searches.length-1; r >= 0; r--) { + if (this.searches[r].field == arguments[a] && this.searches[r].hidden !== false) { + this.searches[r].hidden = false + shown++ + } + } + } + this.searchClose() + return shown + } + hideSearch() { + let hidden = 0 + for (let a = 0; a < arguments.length; a++) { + for (let r = this.searches.length-1; r >= 0; r--) { + if (this.searches[r].field == arguments[a] && this.searches[r].hidden !== true) { + this.searches[r].hidden = true + hidden++ + } + } + } + this.searchClose() + return hidden + } + getSearchData(field) { + for (let i = 0; i < this.searchData.length; i++) { + if (this.searchData[i].field == field) return this.searchData[i] + } + return null + } + localSort(silent, noResetRefresh) { + let obj = this + let url = this.url?.get ?? this.url + if (url) { + console.log('ERROR: grid.localSort can only be used on local data source, grid.url should be empty.') + return + } + if (Object.keys(this.sortData).length === 0) return + let time = Date.now() + // process date fields + this.selectionSave() + this.prepareData() + if (!noResetRefresh) { + this.reset() + } + // process sortData + for (let i = 0; i < this.sortData.length; i++) { + let column = this.getColumn(this.sortData[i].field) + if (!column) return // TODO: ability to sort columns when they are not part of colums array + if (typeof column.render == 'string') { + if (['date', 'age'].indexOf(column.render.split(':')[0]) != -1) { + this.sortData[i].field_ = column.field + '_' + } + if (['time'].indexOf(column.render.split(':')[0]) != -1) { + this.sortData[i].field_ = column.field + '_' + } + } + } + // prepare paths and process sort + preparePaths() + this.records.sort((a, b) => { + return compareRecordPaths(a, b) + }) + cleanupPaths() + this.selectionRestore(noResetRefresh) + time = Date.now() - time + if (silent !== true && this.show.statusSort) { + setTimeout(() => { + this.status(w2utils.lang('Sorting took ${count} seconds', { count: time/1000 })) + }, 10) + } + return time + // grab paths before sorting for efficiency and because calling obj.get() + // while sorting 'obj.records' is unsafe, at least on webkit + function preparePaths() { + for (let i = 0; i < obj.records.length; i++) { + let rec = obj.records[i] + if (rec.w2ui?.parent_recid != null) { + rec.w2ui._path = getRecordPath(rec) + } + } + } + // cleanup and release memory allocated by preparePaths() + function cleanupPaths() { + for (let i = 0; i < obj.records.length; i++) { + let rec = obj.records[i] + if (rec.w2ui?.parent_recid != null) { + rec.w2ui._path = null + } + } + } + // compare two paths, from root of tree to given records + function compareRecordPaths(a, b) { + if ((!a.w2ui || a.w2ui.parent_recid == null) && (!b.w2ui || b.w2ui.parent_recid == null)) { + return compareRecords(a, b) // no tree, fast path + } + let pa = getRecordPath(a) + let pb = getRecordPath(b) + for (let i = 0; i < Math.min(pa.length, pb.length); i++) { + let diff = compareRecords(pa[i], pb[i]) + if (diff !== 0) return diff // different subpath + } + if (pa.length > pb.length) return 1 + if (pa.length < pb.length) return -1 + console.log('ERROR: two paths should not be equal.') + return 0 + } + // return an array of all records from root to and including 'rec' + function getRecordPath(rec) { + if (!rec.w2ui || rec.w2ui.parent_recid == null) return [rec] + if (rec.w2ui._path) + return rec.w2ui._path + // during actual sort, we should never reach this point + let subrec = obj.get(rec.w2ui.parent_recid) + if (!subrec) { + console.log('ERROR: no parent record: ' + rec.w2ui.parent_recid) + return [rec] + } + return (getRecordPath(subrec).concat(rec)) + } + // compare two records according to sortData and finally recid + function compareRecords(a, b) { + if (a === b) return 0 // optimize, same object + for (let i = 0; i < obj.sortData.length; i++) { + let fld = obj.sortData[i].field + let sortFld = (obj.sortData[i].field_) ? obj.sortData[i].field_ : fld + let aa = a[sortFld] + let bb = b[sortFld] + if (String(fld).indexOf('.') != -1) { + aa = obj.parseField(a, sortFld) + bb = obj.parseField(b, sortFld) + } + let col = obj.getColumn(fld) + if (col && Object.keys(col.editable).length > 0) { // for drop editable fields and drop downs + if (w2utils.isPlainObject(aa) && aa.text) aa = aa.text + if (w2utils.isPlainObject(bb) && bb.text) bb = bb.text + } + let ret = compareCells(aa, bb, i, obj.sortData[i].direction, col.sortMode || 'default') + if (ret !== 0) return ret + } + // break tie for similar records, + // required to have consistent ordering for tree paths + let ret = compareCells(a.recid, b.recid, -1, 'asc') + return ret + } + // compare two values, aa and bb, producing consistent ordering + function compareCells(aa, bb, i, direction, sortMode) { + // if both objects are strictly equal, we're done + if (aa === bb) + return 0 + // all nulls, empty and undefined on bottom + if ((aa == null || aa === '') && (bb != null && bb !== '')) + return 1 + if ((aa != null && aa !== '') && (bb == null || bb === '')) + return -1 + let dir = (direction.toLowerCase() === 'asc') ? 1 : -1 + // for different kind of objects, sort by object type + if (typeof aa != typeof bb) + return (typeof aa > typeof bb) ? dir : -dir + // for different kind of classes, sort by classes + if (aa.constructor.name != bb.constructor.name) + return (aa.constructor.name > bb.constructor.name) ? dir : -dir + // if we're dealing with non-null objects, call valueOf(). + // this mean that Date() or custom objects will compare properly. + if (aa && typeof aa == 'object') + aa = aa.valueOf() + if (bb && typeof bb == 'object') + bb = bb.valueOf() + // if we're still dealing with non-null objects that have + // a useful Object => String conversion, convert to string. + let defaultToString = {}.toString + if (aa && typeof aa == 'object' && aa.toString != defaultToString) + aa = String(aa) + if (bb && typeof bb == 'object' && bb.toString != defaultToString) + bb = String(bb) + // do case-insensitive string comparison + if (typeof aa == 'string') + aa = aa.toLowerCase().trim() + if (typeof bb == 'string') + bb = bb.toLowerCase().trim() + switch (sortMode) { + case 'natural': + sortMode = w2utils.naturalCompare + break + case 'i18n': + sortMode = w2utils.i18nCompare + break + } + if (typeof sortMode == 'function') { + return sortMode(aa,bb) * dir + } + // compare both objects + if (aa > bb) + return dir + if (aa < bb) + return -dir + return 0 + } + } + localSearch(silent) { + let obj = this + let url = this.url?.get ?? this.url + if (url) { + console.log('ERROR: grid.localSearch can only be used on local data source, grid.url should be empty.') + return + } + let time = Date.now() + let defaultToString = {}.toString + let duplicateMap = {} + this.total = this.records.length + // mark all records as shown + this.last.searchIds = [] + // prepare date/time fields + this.prepareData() + // hide records that did not match + if (this.searchData.length > 0 && !url) { + this.total = 0 + for (let i = 0; i < this.records.length; i++) { + let rec = this.records[i] + let match = searchRecord(rec) + if (match) { + if (rec?.w2ui) addParent(rec.w2ui.parent_recid) + if (this.showExtraOnSearch > 0) { + let before = this.showExtraOnSearch + let after = this.showExtraOnSearch + if (i < before) before = i + if (i + after > this.records.length) after = this.records.length - i + if (before > 0) { + for (let j = i - before; j < i; j++) { + if (this.last.searchIds.indexOf(j) < 0) + this.last.searchIds.push(j) + } + } + if (this.last.searchIds.indexOf(i) < 0) this.last.searchIds.push(i) + if (after > 0) { + for (let j = (i + 1) ; j <= (i + after) ; j++) { + if (this.last.searchIds.indexOf(j) < 0) this.last.searchIds.push(j) + } + } + } else { + this.last.searchIds.push(i) + } + } + } + this.total = this.last.searchIds.length + } + time = Date.now() - time + if (silent !== true && this.show.statusSearch) { + setTimeout(() => { + this.status(w2utils.lang('Search took ${count} seconds', { count: time/1000 })) + }, 10) + } + return time + // check if a record (or one of its closed children) matches the search data + function searchRecord(rec) { + let fl = 0, val1, val2, val3, tmp + let orEqual = false + for (let j = 0; j < obj.searchData.length; j++) { + let sdata = obj.searchData[j] + let search = obj.getSearch(sdata.field) + if (sdata == null) continue + if (search == null) search = { field: sdata.field, type: sdata.type } + let val1b = obj.parseField(rec, search.field) + val1 = (val1b !== null && val1b !== undefined && + (typeof val1b != 'object' || val1b.toString != defaultToString)) ? + String(val1b).toLowerCase() : '' // do not match a bogus string + if (sdata.value != null) { + if (!Array.isArray(sdata.value)) { + val2 = String(sdata.value).toLowerCase() + } else { + val2 = sdata.value[0] + val3 = sdata.value[1] + } + } + switch (sdata.operator) { + case '=': + case 'is': + if (obj.parseField(rec, search.field) == sdata.value) fl++ // do not hide record + else if (search.type == 'date') { + tmp = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)) + val1 = w2utils.formatDate(tmp, 'yyyy-mm-dd') + val2 = w2utils.formatDate(w2utils.isDate(val2, w2utils.settings.dateFormat, true), 'yyyy-mm-dd') + if (val1 == val2) fl++ + } + else if (search.type == 'time') { + tmp = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)) + val1 = w2utils.formatTime(tmp, 'hh24:mi') + val2 = w2utils.formatTime(val2, 'hh24:mi') + if (val1 == val2) fl++ + } + else if (search.type == 'datetime') { + tmp = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)) + val1 = w2utils.formatDateTime(tmp, 'yyyy-mm-dd|hh24:mm:ss') + val2 = w2utils.formatDateTime(w2utils.isDateTime(val2, w2utils.settings.datetimeFormat, true), 'yyyy-mm-dd|hh24:mm:ss') + if (val1 == val2) fl++ + } + break + case 'between': + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(search.type) != -1) { + if (parseFloat(obj.parseField(rec, search.field)) >= parseFloat(val2) && parseFloat(obj.parseField(rec, search.field)) <= parseFloat(val3)) fl++ + } + else if (search.type == 'date') { + tmp = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)) + val1 = w2utils.isDate(tmp, w2utils.settings.dateFormat, true) + val2 = w2utils.isDate(val2, w2utils.settings.dateFormat, true) + val3 = w2utils.isDate(val3, w2utils.settings.dateFormat, true) + if (val3 != null) val3 = new Date(val3.getTime() + 86400000) // 1 day + if (val1 >= val2 && val1 < val3) fl++ + } + else if (search.type == 'time') { + val1 = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)) + val2 = w2utils.isTime(val2, true) + val3 = w2utils.isTime(val3, true) + val2 = (new Date()).setHours(val2.hours, val2.minutes, val2.seconds ? val2.seconds : 0, 0) + val3 = (new Date()).setHours(val3.hours, val3.minutes, val3.seconds ? val3.seconds : 0, 0) + if (val1 >= val2 && val1 < val3) fl++ + } + else if (search.type == 'datetime') { + val1 = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)) + val2 = w2utils.isDateTime(val2, w2utils.settings.datetimeFormat, true) + val3 = w2utils.isDateTime(val3, w2utils.settings.datetimeFormat, true) + if (val3) val3 = new Date(val3.getTime() + 86400000) // 1 day + if (val1 >= val2 && val1 < val3) fl++ + } + break + case '<=': + orEqual = true + case '<': + case 'less': + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(search.type) != -1) { + val1 = parseFloat(obj.parseField(rec, search.field)) + val2 = parseFloat(sdata.value) + if (val1 < val2 || (orEqual && val1 === val2)) fl++ + } + else if (search.type == 'date') { + tmp = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)) + val1 = w2utils.isDate(tmp, w2utils.settings.dateFormat, true) + val2 = w2utils.isDate(val2, w2utils.settings.dateFormat, true) + if (val1 < val2 || (orEqual && val1 === val2)) fl++ + } + else if (search.type == 'time') { + tmp = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)) + val1 = w2utils.formatTime(tmp, 'hh24:mi') + val2 = w2utils.formatTime(val2, 'hh24:mi') + if (val1 < val2 || (orEqual && val1 === val2)) fl++ + } + else if (search.type == 'datetime') { + tmp = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)) + val1 = w2utils.formatDateTime(tmp, 'yyyy-mm-dd|hh24:mm:ss') + val2 = w2utils.formatDateTime(w2utils.isDateTime(val2, w2utils.settings.datetimeFormat, true), 'yyyy-mm-dd|hh24:mm:ss') + if (val1.length == val2.length && (val1 < val2 || (orEqual && val1 === val2))) fl++ + } + break + case '>=': + orEqual = true + case '>': + case 'more': + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(search.type) != -1) { + val1 = parseFloat(obj.parseField(rec, search.field)) + val2 = parseFloat(sdata.value) + if (val1 > val2 || (orEqual && val1 === val2)) fl++ + } + else if (search.type == 'date') { + tmp = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)) + val1 = w2utils.isDate(tmp, w2utils.settings.dateFormat, true) + val2 = w2utils.isDate(val2, w2utils.settings.dateFormat, true) + if (val1 > val2 || (orEqual && val1 === val2)) fl++ + } + else if (search.type == 'time') { + tmp = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)) + val1 = w2utils.formatTime(tmp, 'hh24:mi') + val2 = w2utils.formatTime(val2, 'hh24:mi') + if (val1 > val2 || (orEqual && val1 === val2)) fl++ + } + else if (search.type == 'datetime') { + tmp = (obj.parseField(rec, search.field + '_') instanceof Date ? obj.parseField(rec, search.field + '_') : obj.parseField(rec, search.field)) + val1 = w2utils.formatDateTime(tmp, 'yyyy-mm-dd|hh24:mm:ss') + val2 = w2utils.formatDateTime(w2utils.isDateTime(val2, w2utils.settings.datetimeFormat, true), 'yyyy-mm-dd|hh24:mm:ss') + if (val1.length == val2.length && (val1 > val2 || (orEqual && val1 === val2))) fl++ + } + break + case 'in': + tmp = sdata.value + if (sdata.svalue) tmp = sdata.svalue + if ((tmp.indexOf(w2utils.isFloat(val1b) ? parseFloat(val1b) : val1b) !== -1) || tmp.indexOf(val1) !== -1) fl++ + break + case 'not in': + tmp = sdata.value + if (sdata.svalue) tmp = sdata.svalue + if (!((tmp.indexOf(w2utils.isFloat(val1b) ? parseFloat(val1b) : val1b) !== -1) || tmp.indexOf(val1) !== -1)) fl++ + break + case 'begins': + case 'begins with': // need for back compatibility + if (val1.indexOf(val2) === 0) fl++ // do not hide record + break + case 'contains': + if (val1.indexOf(val2) >= 0) fl++ // do not hide record + break + case 'null': + if (obj.parseField(rec, search.field) == null) fl++ // do not hide record + break + case 'not null': + if (obj.parseField(rec, search.field) != null) fl++ // do not hide record + break + case 'ends': + case 'ends with': // need for back compatibility + let lastIndex = val1.lastIndexOf(val2) + if (lastIndex !== -1 && lastIndex == val1.length - val2.length) fl++ // do not hide record + break + } + } + if ((obj.last.logic == 'OR' && fl !== 0) || + (obj.last.logic == 'AND' && fl == obj.searchData.length)) + return true + if (rec.w2ui?.children && rec.w2ui?.expanded !== true) { + // there are closed children, search them too. + for (let r = 0; r < rec.w2ui.children.length; r++) { + let subRec = rec.w2ui.children[r] + if (searchRecord(subRec)) + return true + } + } + return false + } + // add parents nodes recursively + function addParent(recid) { + let i = obj.get(recid, true) + if (i == null || recid == null || duplicateMap[recid] || obj.last.searchIds.includes(i)) { + return + } + duplicateMap[recid] = true + let rec = obj.records[i] + if (rec?.w2ui) { + addParent(rec.w2ui.parent_recid) + } + obj.last.searchIds.push(i) + } + } + getRangeData(range, extra) { + let rec1 = this.get(range[0].recid, true) + let rec2 = this.get(range[1].recid, true) + let col1 = range[0].column + let col2 = range[1].column + let res = [] + if (col1 == col2) { // one row + for (let r = rec1; r <= rec2; r++) { + let record = this.records[r] + let dt = record[this.columns[col1].field] || null + if (extra !== true) { + res.push(dt) + } else { + res.push({ data: dt, column: col1, index: r, record: record }) + } + } + } else if (rec1 == rec2) { // one line + let record = this.records[rec1] + for (let i = col1; i <= col2; i++) { + let dt = record[this.columns[i].field] || null + if (extra !== true) { + res.push(dt) + } else { + res.push({ data: dt, column: i, index: rec1, record: record }) + } + } + } else { + for (let r = rec1; r <= rec2; r++) { + let record = this.records[r] + res.push([]) + for (let i = col1; i <= col2; i++) { + let dt = record[this.columns[i].field] + if (extra !== true) { + res[res.length-1].push(dt) + } else { + res[res.length-1].push({ data: dt, column: i, index: r, record: record }) + } + } + } + } + return res + } + addRange(ranges) { + let added = 0, first, last + if (this.selectType == 'row') return added + if (!Array.isArray(ranges)) ranges = [ranges] + // if it is selection + for (let i = 0; i < ranges.length; i++) { + if (typeof ranges[i] != 'object') ranges[i] = { name: 'selection' } + if (ranges[i].name == 'selection') { + if (this.show.selectionBorder === false) continue + let sel = this.getSelection() + if (sel.length === 0) { + this.removeRange('selection') + continue + } else { + first = sel[0] + last = sel[sel.length-1] + } + } else { // other range + first = ranges[i].range[0] + last = ranges[i].range[1] + } + if (first) { + let rg = { + name: ranges[i].name, + range: [{ recid: first.recid, column: first.column }, { recid: last.recid, column: last.column }], + style: ranges[i].style || '' + } + // add range + let ind = false + for (let j = 0; j < this.ranges.length; j++) if (this.ranges[j].name == ranges[i].name) { ind = j; break } + if (ind !== false) { + this.ranges[ind] = rg + } else { + this.ranges.push(rg) + } + added++ + } + } + this.refreshRanges() + return added + } + removeRange() { + let removed = 0 + for (let a = 0; a < arguments.length; a++) { + let name = arguments[a] + query(this.box).find('#grid_'+ this.name +'_'+ name).remove() + query(this.box).find('#grid_'+ this.name +'_f'+ name).remove() + for (let r = this.ranges.length-1; r >= 0; r--) { + if (this.ranges[r].name == name) { + this.ranges.splice(r, 1) + removed++ + } + } + } + return removed + } + refreshRanges() { + if (this.ranges.length === 0) return + let self = this + let range + let time = Date.now() + let rec1 = query(this.box).find(`#grid_${this.name}_frecords`) + let rec2 = query(this.box).find(`#grid_${this.name}_records`) + for (let i = 0; i < this.ranges.length; i++) { + let rg = this.ranges[i] + let first = rg.range[0] + let last = rg.range[1] + if (first.index == null) first.index = this.get(first.recid, true) + if (last.index == null) last.index = this.get(last.recid, true) + let td1 = query(this.box).find('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(first.recid) + ' td[col="'+ first.column +'"]') + let td2 = query(this.box).find('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(last.recid) + ' td[col="'+ last.column +'"]') + let td1f = query(this.box).find('#grid_'+ this.name +'_frec_'+ w2utils.escapeId(first.recid) + ' td[col="'+ first.column +'"]') + let td2f = query(this.box).find('#grid_'+ this.name +'_frec_'+ w2utils.escapeId(last.recid) + ' td[col="'+ last.column +'"]') + let _lastColumn = last.column + // adjustment due to column virtual scroll + if (first.column < this.last.colStart && last.column > this.last.colStart) { + td1 = query(this.box).find('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(first.recid) + ' td[col="start"]') + } + if (first.column < this.last.colEnd && last.column > this.last.colEnd) { + td2 = query(this.box).find('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(last.recid) + ' td[col="end"]') + _lastColumn = '"end"' + } + // if virtual scrolling kicked in + let index_top = parseInt(query(this.box).find('#grid_'+ this.name +'_rec_top').next().attr('index')) + let index_bottom = parseInt(query(this.box).find('#grid_'+ this.name +'_rec_bottom').prev().attr('index')) + let index_ftop = parseInt(query(this.box).find('#grid_'+ this.name +'_frec_top').next().attr('index')) + let index_fbottom = parseInt(query(this.box).find('#grid_'+ this.name +'_frec_bottom').prev().attr('index')) + if (td1.length === 0 && first.index < index_top && last.index > index_top) { + td1 = query(this.box).find('#grid_'+ this.name +'_rec_top').next().find('td[col="'+ first.column +'"]') + } + if (td2.length === 0 && last.index > index_bottom && first.index < index_bottom) { + td2 = query(this.box).find('#grid_'+ this.name +'_rec_bottom').prev().find('td[col="'+ _lastColumn +'"]') + } + if (td1f.length === 0 && first.index < index_ftop && last.index > index_ftop) { // frozen + td1f = query(this.box).find('#grid_'+ this.name +'_frec_top').next().find('td[col="'+ first.column +'"]') + } + if (td2f.length === 0 && last.index > index_fbottom && first.index < index_fbottom) { // frozen + td2f = query(this.box).find('#grid_'+ this.name +'_frec_bottom').prev().find('td[col="'+ last.column +'"]') + } + // do not show selection cell if it is editable + let edit = query(this.box).find('#grid_'+ this.name + '_editable') + let tmp = edit.find('.w2ui-input') + let tmp1 = tmp.attr('recid') + let tmp2 = tmp.attr('column') + if (rg.name == 'selection' && rg.range[0].recid == tmp1 && rg.range[0].column == tmp2) continue + // frozen regular columns range + range = query(this.box).find('#grid_'+ this.name +'_f'+ rg.name) + if (td1f.length > 0 || td2f.length > 0) { + if (range.length === 0) { + rec1.append('
    '+ + (rg.name == 'selection' ? '
    ' : '')+ + '
    ') + range = query(this.box).find('#grid_'+ this.name +'_f'+ rg.name) + } else { + range.attr('style', rg.style) + range.find('.w2ui-selection-resizer').show() + } + if (td2f.length === 0) { + td2f = query(this.box).find('#grid_'+ this.name +'_frec_'+ w2utils.escapeId(last.recid) +' td:last-child') + if (td2f.length === 0) td2f = query(this.box).find('#grid_'+ this.name +'_frec_bottom td:first-child') + range.css('border-right', '0px') + range.find('.w2ui-selection-resizer').hide() + } + if (first.recid != null && last.recid != null && td1f.length > 0 && td2f.length > 0) { + let style = getComputedStyle(td2f[0]) + let top1 = (td1f.prop('offsetTop') - td1f.prop('scrollTop')) + let left1 = (td1f.prop('offsetLeft') + td1f.prop('scrollLeft')) + let top2 = (td2f.prop('offsetTop') - td2f.prop('scrollTop')) + let left2 = (td2f.prop('offsetLeft') + td2f.prop('scrollLeft')) + range.show().css({ + top : (top1 > 0 ? top1 : 0) + 'px', + left : (left1 > 0 ? left1 : 0) + 'px', + width : (left2 - left1 + parseFloat(style.width) + 2) + 'px', + height : (top2 - top1 + parseFloat(style.height) + 1) + 'px' + }) + } else { + range.hide() + } + } else { + range.hide() + } + // regular columns range + range = query(this.box).find('#grid_'+ this.name +'_'+ rg.name) + if (td1.length > 0 || td2.length > 0) { + if (range.length === 0) { + rec2.append('
    '+ + (rg.name == 'selection' ? '
    ' : '')+ + '
    ') + range = query(this.box).find('#grid_'+ this.name +'_'+ rg.name) + } else { + range.attr('style', rg.style) + } + if (td1.length === 0) { + td1 = query(this.box).find('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(first.recid) +' td:first-child') + if (td1.length === 0) td1 = query(this.box).find('#grid_'+ this.name +'_rec_top td:first-child') + } + if (td2f.length !== 0) { + range.css('border-left', '0px') + } + if (first.recid != null && last.recid != null && td1.length > 0 && td2.length > 0) { + let style = getComputedStyle(td2[0]) + let top1 = (td1.prop('offsetTop') - td1.prop('scrollTop')) + let left1 = (td1.prop('offsetLeft') + td1.prop('scrollLeft')) + let top2 = (td2.prop('offsetTop') - td2.prop('scrollTop')) + let left2 = (td2.prop('offsetLeft') + td2.prop('scrollLeft')) + range.show().css({ + top : (top1 > 0 ? top1 : 0) + 'px', + left : (left1 > 0 ? left1 : 0) + 'px', + width : (left2 - left1 + parseFloat(style.width) + 2) + 'px', + height : (top2 - top1 + parseFloat(style.height) + 1) + 'px' + }) + } else { + range.hide() + } + } else { + range.hide() + } + } + // add resizer events + query(this.box).find('.w2ui-selection-resizer') + .off('.resizer') + .on('mousedown.resizer', mouseStart) + .on('dblclick.resizer', (event) => { + let edata = this.trigger('resizerDblClick', { target: this.name, originalEvent: event }) + if (edata.isCancelled === true) return + edata.finish() + }) + let edata = { target: this.name, originalRange: null, newRange: null } + return Date.now() - time + function mouseStart(event) { + let sel = self.getSelection() + self.last.move = { + type : 'expand', + x : event.screenX, + y : event.screenY, + divX : 0, + divY : 0, + recid : sel[0].recid, + column : sel[0].column, + originalRange : [w2utils.clone(sel[0]), w2utils.clone(sel[sel.length-1]) ], + newRange : [w2utils.clone(sel[0]), w2utils.clone(sel[sel.length-1]) ] + } + query('body') + .off('.w2ui-' + self.name) + .on('mousemove.w2ui-' + self.name, mouseMove) + .on('mouseup.w2ui-' + self.name, mouseStop) + // do not blur grid + event.preventDefault() + } + function mouseMove(event) { + let mv = self.last.move + if (!mv || mv.type != 'expand') return + mv.divX = (event.screenX - mv.x) + mv.divY = (event.screenY - mv.y) + // find new cell + let recid, column + let tmp = event.target + if (tmp.tagName.toUpperCase() != 'TD') tmp = query(tmp).closest('td')[0] + if (query(tmp).attr('col') != null) column = parseInt(query(tmp).attr('col')) + if (column == null) { + return + } + tmp = query(tmp).closest('tr')[0] + recid = self.records[query(tmp).attr('index')].recid + // new range + if (mv.newRange[1].recid == recid && mv.newRange[1].column == column) return + let prevNewRange = w2utils.clone(mv.newRange) + mv.newRange = [{ recid: mv.recid, column: mv.column }, { recid: recid, column: column }] + // event before + if (edata.detail) { + edata.detail.newRange = w2utils.clone(mv.newRange) + edata.detail.originalRange = w2utils.clone(mv.originalRange) + } + edata = self.trigger('selectionExtend', edata) + if (edata.isCancelled === true) { + mv.newRange = prevNewRange + edata.detail.newRange = prevNewRange + return + } else { + // default behavior + self.removeRange('grid-selection-expand') + self.addRange({ + name : 'grid-selection-expand', + range : mv.newRange, + style : 'background-color: rgba(100,100,100,0.1); border: 2px dotted rgba(100,100,100,0.5);' + }) + } + } + function mouseStop(event) { + // default behavior + self.removeRange('grid-selection-expand') + delete self.last.move + query('body').off('.w2ui-' + self.name) + // event after + if (edata.finish) edata.finish() + } + } + select() { + if (arguments.length === 0) return 0 + let selected = 0 + let sel = this.last.selection + if (!this.multiSelect) this.selectNone(true) + // if too many arguments > 150k, then it errors off + let args = Array.from(arguments) + if (Array.isArray(args[0])) args = args[0] + // event before + let tmp = { target: this.name } + if (args.length == 1) { + tmp.multiple = false + if (w2utils.isPlainObject(args[0])) { + tmp.clicked = { + recid: args[0].recid, + column: args[0].column + } + } else { + tmp.recid = args[0] + } + } else { + tmp.multiple = true + tmp.clicked = { recids: args } + } + let edata = this.trigger('select', tmp) + if (edata.isCancelled === true) return 0 + // default action + if (this.selectType == 'row') { + for (let a = 0; a < args.length; a++) { + let recid = typeof args[a] == 'object' ? args[a].recid : args[a] + let index = this.get(recid, true) + if (index == null) continue + let recEl1 = null + let recEl2 = null + if (this.searchData.length !== 0 || (index + 1 >= this.last.range_start && index + 1 <= this.last.range_end)) { + recEl1 = query(this.box).find('#grid_'+ this.name +'_frec_'+ w2utils.escapeId(recid)) + recEl2 = query(this.box).find('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)) + } + if (this.selectType == 'row') { + if (sel.indexes.indexOf(index) != -1) continue + sel.indexes.push(index) + if (recEl1 && recEl2) { + recEl1.addClass('w2ui-selected').find('.w2ui-col-number').addClass('w2ui-row-selected') + recEl2.addClass('w2ui-selected').find('.w2ui-col-number').addClass('w2ui-row-selected') + recEl1.find('.w2ui-grid-select-check').prop('checked', true) + } + selected++ + } + } + } else { + // normalize for performance + let new_sel = {} + for (let a = 0; a < args.length; a++) { + let recid = typeof args[a] == 'object' ? args[a].recid : args[a] + let column = typeof args[a] == 'object' ? args[a].column : null + new_sel[recid] = new_sel[recid] || [] + if (Array.isArray(column)) { + new_sel[recid] = column + } else if (w2utils.isInt(column)) { + new_sel[recid].push(column) + } else { + for (let i = 0; i < this.columns.length; i++) { if (this.columns[i].hidden) continue; new_sel[recid].push(parseInt(i)) } + } + } + // add all + let col_sel = [] + for (let recid in new_sel) { + let index = this.get(recid, true) + if (index == null) continue + let recEl1 = null + let recEl2 = null + if (index + 1 >= this.last.range_start && index + 1 <= this.last.range_end) { + recEl1 = query(this.box).find('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)) + recEl2 = query(this.box).find('#grid_'+ this.name +'_frec_'+ w2utils.escapeId(recid)) + } + let s = sel.columns[index] || [] + // default action + if (sel.indexes.indexOf(index) == -1) { + sel.indexes.push(index) + } + // only only those that are new + for (let t = 0; t < new_sel[recid].length; t++) { + if (s.indexOf(new_sel[recid][t]) == -1) s.push(new_sel[recid][t]) + } + s.sort((a, b) => { return a-b }) // sort function must be for numerical sort + for (let t = 0; t < new_sel[recid].length; t++) { + let col = new_sel[recid][t] + if (col_sel.indexOf(col) == -1) col_sel.push(col) + if (recEl1) { + recEl1.find('#grid_'+ this.name +'_data_'+ index +'_'+ col).addClass('w2ui-selected') + recEl1.find('.w2ui-col-number').addClass('w2ui-row-selected') + recEl1.find('.w2ui-grid-select-check').prop('checked', true) + } + if (recEl2) { + recEl2.find('#grid_'+ this.name +'_data_'+ index +'_'+ col).addClass('w2ui-selected') + recEl2.find('.w2ui-col-number').addClass('w2ui-row-selected') + recEl2.find('.w2ui-grid-select-check').prop('checked', true) + } + selected++ + } + // save back to selection object + sel.columns[index] = s + } + // select columns (need here for speed) + for (let c = 0; c < col_sel.length; c++) { + query(this.box).find('#grid_'+ this.name +'_column_'+ col_sel[c] +' .w2ui-col-header').addClass('w2ui-col-selected') + } + } + // need to sort new selection for speed + sel.indexes.sort((a, b) => { return a-b }) + // all selected? + let areAllSelected = (this.records.length > 0 && sel.indexes.length == this.records.length), + areAllSearchedSelected = (sel.indexes.length > 0 && this.searchData.length !== 0 && sel.indexes.length == this.last.searchIds.length) + if (areAllSelected || areAllSearchedSelected) { + query(this.box).find('#grid_'+ this.name +'_check_all').prop('checked', true) + } else { + query(this.box).find('#grid_'+ this.name +'_check_all').prop('checked', false) + } + this.status() + this.addRange('selection') + this.updateToolbar(sel, areAllSelected) + // event after + edata.finish() + return selected + } + unselect() { + let unselected = 0 + let sel = this.last.selection + // if too many arguments > 150k, then it errors off + let args = Array.from(arguments) + if (Array.isArray(args[0])) args = args[0] + // event before + let tmp = { target: this.name } + if (args.length == 1) { + tmp.multiple = false + if (w2utils.isPlainObject(args[0])) { + tmp.clicked = { + recid: args[0].recid, + column: args[0].column + } + } else { + tmp.clicked = { recid: args[0] } + } + } else { + tmp.multiple = true + tmp.recids = args + } + let edata = this.trigger('select', tmp) + if (edata.isCancelled === true) return 0 + for (let a = 0; a < args.length; a++) { + let recid = typeof args[a] == 'object' ? args[a].recid : args[a] + let record = this.get(recid) + if (record == null) continue + let index = this.get(record.recid, true) + let recEl1 = query(this.box).find('#grid_'+ this.name +'_frec_'+ w2utils.escapeId(recid)) + let recEl2 = query(this.box).find('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)) + if (this.selectType == 'row') { + if (sel.indexes.indexOf(index) == -1) continue + // default action + sel.indexes.splice(sel.indexes.indexOf(index), 1) + recEl1.removeClass('w2ui-selected w2ui-inactive').find('.w2ui-col-number').removeClass('w2ui-row-selected') + recEl2.removeClass('w2ui-selected w2ui-inactive').find('.w2ui-col-number').removeClass('w2ui-row-selected') + if (recEl1.length != 0) { + recEl1[0].style.cssText = 'height: '+ this.recordHeight +'px; ' + recEl1.attr('custom_style') + recEl2[0].style.cssText = 'height: '+ this.recordHeight +'px; ' + recEl2.attr('custom_style') + } + recEl1.find('.w2ui-grid-select-check').prop('checked', false) + unselected++ + } else { + let col = args[a].column + if (!w2utils.isInt(col)) { // unselect all columns + let cols = [] + for (let i = 0; i < this.columns.length; i++) { if (this.columns[i].hidden) continue; cols.push({ recid: recid, column: i }) } + return this.unselect(cols) + } + let s = sel.columns[index] + if (!Array.isArray(s) || s.indexOf(col) == -1) continue + // default action + s.splice(s.indexOf(col), 1) + query(this.box).find(`#grid_${this.name}_rec_${w2utils.escapeId(recid)} > td[col="${col}"]`).removeClass('w2ui-selected w2ui-inactive') + query(this.box).find(`#grid_${this.name}_frec_${w2utils.escapeId(recid)} > td[col="${col}"]`).removeClass('w2ui-selected w2ui-inactive') + // check if any row/column still selected + let isColSelected = false + let isRowSelected = false + let tmp = this.getSelection() + for (let i = 0; i < tmp.length; i++) { + if (tmp[i].column == col) isColSelected = true + if (tmp[i].recid == recid) isRowSelected = true + } + if (!isColSelected) { + query(this.box).find(`.w2ui-grid-columns td[col="${col}"] .w2ui-col-header, .w2ui-grid-fcolumns td[col="${col}"] .w2ui-col-header`).removeClass('w2ui-col-selected') + } + if (!isRowSelected) { + query(this.box).find('#grid_'+ this.name +'_frec_'+ w2utils.escapeId(recid)).find('.w2ui-col-number').removeClass('w2ui-row-selected') + } + unselected++ + if (s.length === 0) { + delete sel.columns[index] + sel.indexes.splice(sel.indexes.indexOf(index), 1) + recEl1.find('.w2ui-grid-select-check').prop('checked', false) + } + } + } + // all selected? + let areAllSelected = (this.records.length > 0 && sel.indexes.length == this.records.length), + areAllSearchedSelected = (sel.indexes.length > 0 && this.searchData.length !== 0 && sel.indexes.length == this.last.searchIds.length) + if (areAllSelected || areAllSearchedSelected) { + query(this.box).find('#grid_'+ this.name +'_check_all').prop('checked', true) + } else { + query(this.box).find('#grid_'+ this.name +'_check_all').prop('checked', false) + } + // show number of selected + this.status() + this.addRange('selection') + this.updateToolbar(sel, areAllSelected) + // event after + edata.finish() + return unselected + } + selectAll() { + let time = Date.now() + if (this.multiSelect === false) return + // default action + let url = this.url?.get ?? this.url + let sel = w2utils.clone(this.last.selection) + let cols = [] + for (let i = 0; i < this.columns.length; i++) cols.push(i) + // if local data source and searched + sel.indexes = [] + if (!url && this.searchData.length !== 0) { + // local search applied + for (let i = 0; i < this.last.searchIds.length; i++) { + sel.indexes.push(this.last.searchIds[i]) + if (this.selectType != 'row') sel.columns[this.last.searchIds[i]] = cols.slice() // .slice makes copy of the array + } + } else { + let buffered = this.records.length + if (this.searchData.length != 0 && !url) buffered = this.last.searchIds.length + for (let i = 0; i < buffered; i++) { + sel.indexes.push(i) + if (this.selectType != 'row') sel.columns[i] = cols.slice() // .slice makes copy of the array + } + } + // event before + let edata = this.trigger('select', { target: this.name, multiple: true, all: true, clicked: sel }) + if (edata.isCancelled === true) return + this.last.selection = sel + // add selected class + if (this.selectType == 'row') { + query(this.box).find('.w2ui-grid-records tr:not(.w2ui-empty-record)') + .addClass('w2ui-selected').find('.w2ui-col-number').addClass('w2ui-row-selected') + query(this.box).find('.w2ui-grid-frecords tr:not(.w2ui-empty-record)') + .addClass('w2ui-selected').find('.w2ui-col-number').addClass('w2ui-row-selected') + query(this.box).find('input.w2ui-grid-select-check').prop('checked', true) + } else { + query(this.box).find('.w2ui-grid-columns td .w2ui-col-header, .w2ui-grid-fcolumns td .w2ui-col-header').addClass('w2ui-col-selected') + query(this.box).find('.w2ui-grid-records tr .w2ui-col-number').addClass('w2ui-row-selected') + query(this.box).find('.w2ui-grid-records tr:not(.w2ui-empty-record)') + .find('.w2ui-grid-data:not(.w2ui-col-select)').addClass('w2ui-selected') + query(this.box).find('.w2ui-grid-frecords tr .w2ui-col-number').addClass('w2ui-row-selected') + query(this.box).find('.w2ui-grid-frecords tr:not(.w2ui-empty-record)') + .find('.w2ui-grid-data:not(.w2ui-col-select)').addClass('w2ui-selected') + query(this.box).find('input.w2ui-grid-select-check').prop('checked', true) + } + // enable/disable toolbar buttons + sel = this.getSelection(true) + this.addRange('selection') + query(this.box).find('#grid_'+ this.name +'_check_all').prop('checked', true) + this.status() + this.updateToolbar({ indexes: sel }, true) + // event after + edata.finish() + return Date.now() - time + } + selectNone(skipEvent) { + let time = Date.now() + // event before + let edata + if (!skipEvent) { + edata = this.trigger('select', { target: this.name, clicked: [] }) + if (edata.isCancelled === true) return + } + // default action + let sel = this.last.selection + // remove selected class + if (this.selectType == 'row') { + query(this.box).find('.w2ui-grid-records tr.w2ui-selected').removeClass('w2ui-selected w2ui-inactive') + .find('.w2ui-col-number').removeClass('w2ui-row-selected') + query(this.box).find('.w2ui-grid-frecords tr.w2ui-selected').removeClass('w2ui-selected w2ui-inactive') + .find('.w2ui-col-number').removeClass('w2ui-row-selected') + query(this.box).find('input.w2ui-grid-select-check').prop('checked', false) + } else { + query(this.box).find('.w2ui-grid-columns td .w2ui-col-header, .w2ui-grid-fcolumns td .w2ui-col-header').removeClass('w2ui-col-selected') + query(this.box).find('.w2ui-grid-records tr .w2ui-col-number').removeClass('w2ui-row-selected') + query(this.box).find('.w2ui-grid-frecords tr .w2ui-col-number').removeClass('w2ui-row-selected') + query(this.box).find('.w2ui-grid-data.w2ui-selected').removeClass('w2ui-selected w2ui-inactive') + query(this.box).find('input.w2ui-grid-select-check').prop('checked', false) + } + sel.indexes = [] + sel.columns = {} + this.removeRange('selection') + query(this.box).find('#grid_'+ this.name +'_check_all').prop('checked', false) + this.status() + this.updateToolbar(sel, false) + // event after + if (!skipEvent) { + edata.finish() + } + return Date.now() - time + } + updateToolbar(sel) { + let obj = this + let cnt = sel && sel.indexes ? sel.indexes.length : 0 + this.toolbar.items.forEach((item) => { + _checkItem(item, '') + if (Array.isArray(item.items)) { + item.items.forEach((it) => { + _checkItem(it, item.id + ':') + }) + } + }) + // enable/disable toolbar search button + if (this.show.toolbarSave) { + if (this.getChanges().length > 0) { + this.toolbar.enable('w2ui-save') + } else { + this.toolbar.disable('w2ui-save') + } + } + function _checkItem(item, prefix) { + if (item.batch != null) { + let enabled = false + if (item.batch === true) { + if (cnt > 0) enabled = true + } else if (typeof item.batch == 'number') { + if (cnt === item.batch) enabled = true + } else if (typeof item.batch == 'function') { + enabled = item.batch({ cnt, sel }) + } + if (enabled) { + obj.toolbar.enable(prefix + item.id) + } else { + obj.toolbar.disable(prefix + item.id) + } + } + } + } + getSelection(returnIndex) { + let ret = [] + let sel = this.last.selection + if (this.selectType == 'row') { + for (let i = 0; i < sel.indexes.length; i++) { + if (!this.records[sel.indexes[i]]) continue + if (returnIndex === true) ret.push(sel.indexes[i]); else ret.push(this.records[sel.indexes[i]].recid) + } + return ret + } else { + for (let i = 0; i < sel.indexes.length; i++) { + let cols = sel.columns[sel.indexes[i]] + if (!this.records[sel.indexes[i]]) continue + for (let j = 0; j < cols.length; j++) { + ret.push({ recid: this.records[sel.indexes[i]].recid, index: parseInt(sel.indexes[i]), column: cols[j] }) + } + } + return ret + } + } + search(field, value) { + let url = this.url?.get ?? this.url + let searchData = [] + let last_multi = this.last.multi + let last_logic = this.last.logic + let last_field = this.last.field + let last_search = this.last.search + let hasHiddenSearches = false + let overlay = query(`#w2overlay-${this.name}-search-overlay`) + // add hidden searches + for (let i = 0; i < this.searches.length; i++) { + if (!this.searches[i].hidden || this.searches[i].value == null) continue + searchData.push({ + field : this.searches[i].field, + operator : this.searches[i].operator || 'is', + type : this.searches[i].type, + value : this.searches[i].value || '' + }) + hasHiddenSearches = true + } + if (arguments.length === 0 && overlay.length === 0) { + if (this.multiSearch) { + field = this.searchData + value = this.last.logic + } else { + field = this.last.field + value = this.last.search + } + } + // 1: search() - advanced search (reads from popup) + if (arguments.length === 0 && overlay.length !== 0) { + this.focus() // otherwise search drop down covers searches + last_logic = overlay.find(`#grid_${this.name}_logic`).val() + last_search = '' + // advanced search + for (let i = 0; i < this.searches.length; i++) { + let search = this.searches[i] + let operator = overlay.find('#grid_'+ this.name + '_operator_'+ i).val() + let field1 = overlay.find('#grid_'+ this.name + '_field_'+ i) + let field2 = overlay.find('#grid_'+ this.name + '_field2_'+ i) + let value1 = field1.val() + let value2 = field2.val() + let svalue = null + let text = null + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(search.type) != -1) { + let fld1 = field1[0]._w2field + let fld2 = field2[0]._w2field + if (fld1) value1 = fld1.clean(value1) + if (fld2) value2 = fld2.clean(value2) + } + if (['list', 'enum'].indexOf(search.type) != -1 || ['in', 'not in'].indexOf(operator) != -1) { + value1 = field1[0]._w2field.selected || {} + if (Array.isArray(value1)) { + svalue = [] + for (let j = 0; j < value1.length; j++) { + svalue.push(w2utils.isFloat(value1[j].id) ? parseFloat(value1[j].id) : String(value1[j].id).toLowerCase()) + delete value1[j].hidden + } + if (Object.keys(value1).length === 0) value1 = '' + } else { + text = value1.text || '' + value1 = value1.id || '' + } + } + if ((value1 !== '' && value1 != null) || (value2 != null && value2 !== '')) { + let tmp = { + field : search.field, + type : search.type, + operator : operator + } + if (operator == 'between') { + w2utils.extend(tmp, { value: [value1, value2] }) + } else if (operator == 'in' && typeof value1 == 'string') { + w2utils.extend(tmp, { value: value1.split(',') }) + } else if (operator == 'not in' && typeof value1 == 'string') { + w2utils.extend(tmp, { value: value1.split(',') }) + } else { + w2utils.extend(tmp, { value: value1 }) + } + if (svalue) w2utils.extend(tmp, { svalue: svalue }) + if (text) w2utils.extend(tmp, { text: text }) + // convert date to unix time + try { + if (search.type == 'date' && operator == 'between') { + tmp.value[0] = value1 // w2utils.isDate(value1, w2utils.settings.dateFormat, true).getTime(); + tmp.value[1] = value2 // w2utils.isDate(value2, w2utils.settings.dateFormat, true).getTime(); + } + if (search.type == 'date' && operator == 'is') { + tmp.value = value1 // w2utils.isDate(value1, w2utils.settings.dateFormat, true).getTime(); + } + } catch (e) { + } + searchData.push(tmp) + last_multi = true // if only hidden searches, then do not set + } + } + } + // 2: search(field, value) - regular search + if (typeof field == 'string') { + // if only one argument - search all + if (arguments.length == 1) { + value = field + field = 'all' + } + last_field = field + last_search = value + last_multi = false + last_logic = (hasHiddenSearches ? 'AND' : 'OR') + // loop through all searches and see if it applies + if (value != null) { + if (field.toLowerCase() == 'all') { + // if there are search fields loop thru them + if (this.searches.length > 0) { + for (let i = 0; i < this.searches.length; i++) { + let search = this.searches[i] + if (search.type == 'text' || (search.type == 'alphanumeric' && w2utils.isAlphaNumeric(value)) + || (search.type == 'int' && w2utils.isInt(value)) || (search.type == 'float' && w2utils.isFloat(value)) + || (search.type == 'percent' && w2utils.isFloat(value)) || ((search.type == 'hex' || search.type == 'color') && w2utils.isHex(value)) + || (search.type == 'currency' && w2utils.isMoney(value)) || (search.type == 'money' && w2utils.isMoney(value)) + || (search.type == 'date' && w2utils.isDate(value)) || (search.type == 'time' && w2utils.isTime(value)) + || (search.type == 'datetime' && w2utils.isDateTime(value)) || (search.type == 'datetime' && w2utils.isDate(value)) + || (search.type == 'enum' && w2utils.isAlphaNumeric(value)) || (search.type == 'list' && w2utils.isAlphaNumeric(value)) + ) { + let def = this.defaultOperator[this.operatorsMap[search.type]] + let tmp = { + field : search.field, + type : search.type, + operator : (search.operator != null ? search.operator : def), + value : value + } + if (String(value).trim() != '') searchData.push(tmp) + } + // range in global search box + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(search.type) != -1 && String(value).trim().split('-').length == 2) { + let t = String(value).trim().split('-') + let tmp = { + field : search.field, + type : search.type, + operator : (search.operator != null ? search.operator : 'between'), + value : [t[0], t[1]] + } + searchData.push(tmp) + } + // lists fields + if (['list', 'enum'].indexOf(search.type) != -1) { + let new_values = [] + if (search.options == null) search.options = {} + if (!Array.isArray(search.options.items)) search.options.items = [] + for (let j = 0; j < search.options.items; j++) { + let tmp = search.options.items[j] + try { + let re = new RegExp(value, 'i') + if (re.test(tmp)) new_values.push(j) + if (tmp.text && re.test(tmp.text)) new_values.push(tmp.id) + } catch (e) {} + } + if (new_values.length > 0) { + let tmp = { + field : search.field, + type : search.type, + operator : (search.operator != null ? search.operator : 'in'), + value : new_values + } + searchData.push(tmp) + } + } + } + } else { + // no search fields, loop thru columns + for (let i = 0; i < this.columns.length; i++) { + let tmp = { + field : this.columns[i].field, + type : 'text', + operator : this.defaultOperator.text, + value : value + } + searchData.push(tmp) + } + } + } else { + let el = overlay.find('#grid_'+ this.name +'_search_all') + let search = this.getSearch(field) + if (search == null) search = { field: field, type: 'text' } + if (search.field == field) this.last.label = search.label + if (value !== '') { + let op = this.defaultOperator[this.operatorsMap[search.type]] + let val = value + if (['date', 'time', 'datetime'].indexOf(search.type) != -1) op = 'is' + if (['list', 'enum'].indexOf(search.type) != -1) { + op = 'is' + let tmp = el._w2field.get() + if (tmp && Object.keys(tmp).length > 0) val = tmp.id; else val = '' + } + if (search.type == 'int' && value !== '') { + op = 'is' + if (String(value).indexOf('-') != -1) { + let tmp = value.split('-') + if (tmp.length == 2) { + op = 'between' + val = [parseInt(tmp[0]), parseInt(tmp[1])] + } + } + if (String(value).indexOf(',') != -1) { + let tmp = value.split(',') + op = 'in' + val = [] + for (let i = 0; i < tmp.length; i++) val.push(tmp[i]) + } + } + if (search.operator != null) op = search.operator + let tmp = { + field : search.field, + type : search.type, + operator : op, + value : val + } + searchData.push(tmp) + } + } + } + } + // 3: search([{ field, value, [operator,] [type] }, { field, value, [operator,] [type] } ], logic) - submit whole structure + if (Array.isArray(field)) { + let logic = 'AND' + if (typeof value == 'string') { + logic = value.toUpperCase() + if (logic != 'OR' && logic != 'AND') logic = 'AND' + } + last_search = '' + last_multi = true + last_logic = logic + for (let i = 0; i < field.length; i++) { + let data = field[i] + if (typeof data.value == 'number' && data.operator == null) data.operator = this.defaultOperator.number + if (typeof data.value == 'string' && data.operator == null) data.operator = this.defaultOperator.text + if (Array.isArray(data.value) && data.operator == null) data.operator = this.defaultOperator.enum + if (w2utils.isDate(data.value) && data.operator == null) data.operator = this.defaultOperator.date + // merge current field and search if any + searchData.push(data) + } + } + // event before + let edata = this.trigger('search', { + target: this.name, + multi: (arguments.length === 0 ? true : false), + searchField: (field ? field : 'multi'), + searchValue: (field ? value : 'multi'), + searchData: searchData, + searchLogic: last_logic + }) + if (edata.isCancelled === true) return + // default action + this.searchData = edata.detail.searchData + this.last.field = last_field + this.last.search = last_search + this.last.multi = last_multi + this.last.logic = edata.detail.searchLogic + this.last.scrollTop = 0 + this.last.scrollLeft = 0 + this.last.selection.indexes = [] + this.last.selection.columns = {} + // -- clear all search field + this.searchClose() + // apply search + if (url) { + this.last.fetch.offset = 0 + this.reload() + } else { + // local search + this.localSearch() + this.refresh() + } + // event after + edata.finish() + } + // open advanced search popover + searchOpen() { + if (!this.box) return + if (this.searches.length === 0) return + // event before + let edata = this.trigger('searchOpen', { target: this.name }) + if (edata.isCancelled === true) { + return + } + let $btn = query(this.toolbar.box).find('.w2ui-grid-search-input .w2ui-search-drop') + $btn.addClass('checked') + // show search + w2tooltip.show({ + name: this.name + '-search-overlay', + anchor: query(this.box).find('#grid_'+ this.name +'_search_all').get(0), + position: 'bottom|top', + html: this.getSearchesHTML(), + align: 'left', + arrowSize: 12, + class: 'w2ui-grid-search-advanced', + hideOn: ['doc-click'] + }) + .then(event => { + this.initSearches() + this.last.search_opened = true + let overlay = query(`#w2overlay-${this.name}-search-overlay`) + overlay + .data('gridName', this.name) + .off('.grid-search') + .on('click.grid-search', () => { + // hide any tooltip opened by searches + overlay.find('input, select').each(el => { + let names = query(el).data('tooltipName') + if (names) names.forEach(name => { + w2tooltip.hide(name) + }) + }) + }) + w2utils.bindEvents(overlay.find('select, input, button'), this) + // init first field + let sfields = query(`#w2overlay-${this.name}-search-overlay *[rel=search]`) + if (sfields.length > 0) sfields[0].focus() + // event after + edata.finish() + }) + .hide(event => { + $btn.removeClass('checked') + this.last.search_opened = false + }) + } + searchClose() { + w2tooltip.hide(this.name + '-search-overlay') + } + // if clicked on a field in the search strip + searchFieldTooltip(ind, sd_ind, el) { + let sf = this.searches[ind] + let sd = this.searchData[sd_ind] + let oper = sd.operator + if (oper == 'more' && sd.type == 'date') oper = 'since' + if (oper == 'less' && sd.type == 'date') oper = 'before' + let options = '' + let val = sd.value + if (Array.isArray(sd.value)) { // && Array.isArray(sf.options.items)) { + sd.value.forEach(opt => { + options += `${opt.text || opt}` + }) + if (sd.type == 'date') { + options = '' + sd.value.forEach(opt => { + options += `${w2utils.formatDate(opt)}` + }) + } + } else { + if (sd.type == 'date') { + val = w2utils.formatDateTime(val) + } + } + w2tooltip.hide(this.name + '-search-props') + w2tooltip.show({ + name: this.name + '-search-props', + anchor: el, + class: 'w2ui-white', + hideOn: 'doc-click', + html: ` +
    + ${sf.label} + ${w2utils.lang(oper)} + ${Array.isArray(sd.value) + ? `${options}` + : `${val}` + } +
    + +
    +
    ` + }).then(event => { + query(event.detail.overlay.box).find('#remove').on('click', () => { + this.searchData.splice(`${sd_ind}`, 1) + this.reload() + this.localSearch() + w2tooltip.hide(this.name + '-search-props') + }) + }) + } + // drop down with save searches + searchSuggest(imediate, forceHide, input) { + clearTimeout(this.last.kbd_timer) + clearTimeout(this.last.overlay_timer) + this.searchShowFields(true) + this.searchClose() + if (forceHide === true) { + w2tooltip.hide(this.name + '-search-suggest') + return + } + if (query(`#w2overlay-${this.name}-search-suggest`).length > 0) { + // already shown + return + } + if (!imediate) { + this.last.overlay_timer = setTimeout(() => { this.searchSuggest(true) }, 100) + return + } + let el = query(this.box).find(`#grid_${this.name}_search_all`).get(0) + let searches = [ + ...this.defaultSearches ?? [], + ...this.defaultSearches?.length > 0 && this.savedSearches?.length > 0 ? ['--'] : [], + ...this.savedSearches ?? [] + ] + if (Array.isArray(searches) && searches.length > 0) { + w2menu.show({ + name: this.name + '-search-suggest', + anchor: el, + align: 'both', + items: searches, + hideOn: ['doc-click', 'sleect', 'remove'], + render(item) { + let ret = item.text + if (item.isDefault) ret = `${ret}` + return ret + } + }) + .select(event => { + let edata = this.trigger('searchSelect', { + target: this.name, + index: event.detail.index, + item: event.detail.item + }) + if (edata.isCancelled === true) { + event.preventDefault() + return + } + event.detail.overlay.hide() + this.last.logic = event.detail.item.logic || 'AND' + this.last.search = '' + this.last.label = '[Multiple Fields]' + this.searchData = w2utils.clone(event.detail.item.data) + this.searchSelected = w2utils.clone(event.detail.item, { exclude: ['icon', 'remove'] }) + this.reload() + edata.finish() + }) + .remove(event => { + let item = event.detail.item + let edata = this.trigger('searchRemove', { target: this.name, index: event.detail.index, item }) + if (edata.isCancelled === true) { + event.preventDefault() + return + } + event.detail.overlay.hide() + this.confirm(w2utils.lang('Do you want to delete search "${item}"?', { item: item.text })) + .yes(evt => { + // remove from searches + let search = this.savedSearches.findIndex((s) => s.id == item.id ? true : false) + if (search !== -1) { + this.savedSearches.splice(search, 1) + } + this.cacheSave('searches', this.savedSearches.map(s => w2utils.clone(s, { exclude: ['remove', 'icon'] }))) + evt.detail.self.close() + // evt after + edata.finish() + }) + .no(evt => { + evt.detail.self.close() + }) + }) + } + } + searchSave() { + let value = '' + if (this.searchSelected) { + value = this.searchSelected.text + } + let ind = this.savedSearches.findIndex(s => { return s.id == this.searchSelected?.id ? true : false }) + // event before + let edata = this.trigger('searchSave', { target: this.name, saveLocalStorage: true }) + if (edata.isCancelled === true) return + this.message({ + width: 350, + height: 150, + body: ``, + buttons: ` + + + ` + }).open(async (event) => { + query(event.detail.box).find('input, button').eq(0).val(value) + await event.complete + query(event.detail.box).find('#grid-search-cancel').on('click', () => { + this.message() + }) + query(event.detail.box).find('#grid-search-save').on('click', () => { + let name = query(event.detail.box).find('.w2ui-message .search-name').val() + // save in savedSearches + if (this.searchSelected && ind != -1) { + Object.assign(this.savedSearches[ind], { + id: name, + text: name, + logic: this.last.logic, + data: w2utils.clone(this.searchData) + }) + } else { + this.savedSearches.push({ + id: name, + text: name, + icon: 'w2ui-icon-search', + remove: true, + logic: this.last.logic, + data: this.searchData + }) + } + // save local storage + this.cacheSave('searches', this.savedSearches.map(s => w2utils.clone(s, { exclude: ['remove', 'icon'] }))) + this.message() + // update on screen + if (this.searchSelected) { + this.searchSelected.text = name + query(this.box).find(`#grid_${this.name}_search_name .name-text`).html(name) + } else { + this.searchSelected = { + text: name, + logic: this.last.logic, + data: w2utils.clone(this.searchData) + } + query(event.detail.box).find(`#grid_${this.name}_search_all`).val(' ').prop('readOnly', true) + query(event.detail.box).find(`#grid_${this.name}_search_name`).show().find('.name-text').html(name) + } + edata.finish({ name }) + }) + query(event.detail.box).find('input, button') + .off('.message') + .on('keydown.message', evt => { + let val = String(query(event.detail.box).find('.w2ui-message-body input').val()).trim() + if (evt.keyCode == 13 && val != '') { + query(event.detail.box).find('#grid-search-save').trigger('click') // enter + } + if (evt.keyCode == 27) { // escape + this.message() + } + }) + .eq(0) + .on('input.message', evt => { + let $save = query(event.detail.box).closest('.w2ui-message').find('#grid-search-save') + if (String(query(event.detail.box).val()).trim() === '') { + $save.prop('disabled', true) + } else { + $save.prop('disabled', false) + } + }) + .get(0) + .focus() + }) + } + cache(type) { + if (w2utils.hasLocalStorage && this.useLocalStorage) { + try { + let data = JSON.parse(localStorage.w2ui || '{}') + data[(this.stateId || this.name)] ??= {} + return data[(this.stateId || this.name)][type] + } catch (e) { + } + } + return null + } + cacheSave(type, value) { + if (w2utils.hasLocalStorage && this.useLocalStorage) { + try { + let data = JSON.parse(localStorage.w2ui || '{}') + data[(this.stateId || this.name)] ??= {} + data[(this.stateId || this.name)][type] = value + localStorage.w2ui = JSON.stringify(data) + return true + } catch (e) { + delete localStorage.w2ui + } + } + return false + } + searchReset(noReload) { + let searchData = [] + let hasHiddenSearches = false + // add hidden searches + for (let i = 0; i < this.searches.length; i++) { + if (!this.searches[i].hidden || this.searches[i].value == null) continue + searchData.push({ + field : this.searches[i].field, + operator : this.searches[i].operator || 'is', + type : this.searches[i].type, + value : this.searches[i].value || '' + }) + hasHiddenSearches = true + } + // event before + let edata = this.trigger('search', { reset: true, target: this.name, searchData: searchData }) + if (edata.isCancelled === true) return + // default action + let input = query(this.box).find('#grid_'+ this.name +'_search_all') + this.searchData = edata.detail.searchData + this.searchSelected = null + this.last.search = '' + this.last.logic = (hasHiddenSearches ? 'AND' : 'OR') + // --- do not reset to All Fields (I think) + input.next().hide() // advanced search button + if (this.searches.length > 0) { + if (!this.multiSearch || !this.show.searchAll) { + let tmp = 0 + while (tmp < this.searches.length && (this.searches[tmp].hidden || this.searches[tmp].simple === false)) tmp++ + if (tmp >= this.searches.length) { + // all searches are hidden + this.last.field = '' + this.last.label = '' + } else { + this.last.field = this.searches[tmp].field + this.last.label = this.searches[tmp].label + } + } else { + this.last.field = 'all' + this.last.label = 'All Fields' + input.next().show() // advanced search button + } + } + this.last.multi = false + this.last.fetch.offset = 0 + // reset scrolling position + this.last.scrollTop = 0 + this.last.scrollLeft = 0 + this.last.selection.indexes = [] + this.last.selection.columns = {} + // -- clear all search field + this.searchClose() + let all = input.val('').get(0) + if (all?._w2field) { all._w2field.reset() } + // apply search + if (!noReload) this.reload() + // event after + edata.finish() + } + searchShowFields(forceHide) { + if (forceHide === true) { + w2tooltip.hide(this.name + '-search-fields') + return + } + let items = [] + for (let s = -1; s < this.searches.length; s++) { + let search = this.searches[s] + let sField = (search ? search.field : null) + let column = this.getColumn(sField) + let disabled = false + let tooltip = null + if (this.show.searchHiddenMsg == true && s != -1 + && (column == null || (column.hidden === true && column.hideable !== false))) { + disabled = true + tooltip = w2utils.lang(`This column ${column == null ? 'does not exist' : 'is hidden'}`) + } + if (s == -1) { // -1 is All Fields search + if (!this.multiSearch || !this.show.searchAll) continue + search = { field: 'all', label: 'All Fields' } + } else { + if (column != null && column.hideable === false) continue + if (search.hidden === true) { + tooltip = w2utils.lang('This column is hidden') + // don't show hidden (not simple) searches + if (search.simple === false) continue + } + } + if (search.label == null && search.caption != null) { + console.log('NOTICE: grid search.caption property is deprecated, please use search.label. Search ->', search) + search.label = search.caption + } + items.push({ + id: search.field, + text: w2utils.lang(search.label), + search, + tooltip, + disabled, + checked: (search.field == this.last.field) + }) + } + w2menu.show({ + type: 'radio', + name: this.name + '-search-fields', + anchor: query(this.box).find('#grid_'+ this.name +'_search_name').parent().find('.w2ui-search-down').get(0), + items, + align: 'none', + hideOn: ['doc-click', 'select'] + }) + .select(event => { + this.searchInitInput(event.detail.item.search.field) + }) + } + searchInitInput(field, value) { + let search + let el = query(this.box).find('#grid_'+ this.name +'_search_all') + if (field == 'all') { + search = { field: 'all', label: w2utils.lang('All Fields') } + } else { + search = this.getSearch(field) + if (search == null) return + } + // update field + if (this.last.search != '') { + this.last.label = search.label + this.search(search.field, this.last.search) + } else { + this.last.field = search.field + this.last.label = search.label + } + el.attr('placeholder', w2utils.lang('Search') + ' ' + w2utils.lang(search.label || search.caption || search.field, true)) + } + // clears records and related params + clear(noRefresh) { + this.total = 0 + this.records = [] + this.summary = [] + this.last.fetch.offset = 0 // need this for reload button to work on remote data set + this.last.idCache = {} // optimization to free memory + this.last.selection = { indexes: [], columns: {} } + this.reset(true) + // refresh + if (!noRefresh) this.refresh() + } + // clears scroll position, selection, ranges + reset(noRefresh) { + // position + this.last.scrollTop = 0 + this.last.scrollLeft = 0 + this.last.range_start = null + this.last.range_end = null + // additional + query(this.box).find(`#grid_${this.name}_records`).prop('scrollTop', 0) + // refresh + if (!noRefresh) this.refresh() + } + skip(offset, callBack) { + let url = this.url?.get ?? this.url + if (url) { + this.offset = parseInt(offset) + if (this.offset > this.total) this.offset = this.total - this.limit + if (this.offset < 0 || !w2utils.isInt(this.offset)) this.offset = 0 + this.clear(true) + this.reload(callBack) + } else { + console.log('ERROR: grid.skip() can only be called when you have remote data source.') + } + } + load(url, callBack) { + if (url == null) { + console.log('ERROR: You need to provide url argument when calling .load() method of "'+ this.name +'" object.') + return new Promise((resolve, reject) => { reject() }) + } + // default action + this.clear(true) + return this.request('load', {}, url, callBack) + } + reload(callBack) { + let grid = this + let url = this.url?.get ?? this.url + grid.selectionSave() + if (url) { + // need to remember selection (not just last.selection object) + return this.load(url, () => { + grid.selectionRestore() + if (typeof callBack == 'function') callBack() + }) + } else { + this.reset(true) + this.localSearch() + this.selectionRestore() + if (typeof callBack == 'function') callBack({ status: 'success' }) + return new Promise(resolve => { resolve() }) + } + } + request(action, postData, url, callBack) { + let self = this + let resolve, reject + let requestProm = new Promise((res, rej) => { resolve = res; reject = rej }) + if (postData == null) postData = {} + if (!url) url = this.url + if (!url) return new Promise((resolve, reject) => { reject() }) + // build parameters list + if (!w2utils.isInt(this.offset)) this.offset = 0 + if (!w2utils.isInt(this.last.fetch.offset)) this.last.fetch.offset = 0 + // add list params + let edata + let params = { + limit: this.limit, + offset: parseInt(this.offset) + parseInt(this.last.fetch.offset), + searchLogic: this.last.logic, + search: this.searchData.map((search) => { + let _search = w2utils.clone(search) + if (this.searchMap && this.searchMap[_search.field]) _search.field = this.searchMap[_search.field] + return _search + }), + sort: this.sortData.map((sort) => { + let _sort = w2utils.clone(sort) + if (this.sortMap && this.sortMap[_sort.field]) _sort.field = this.sortMap[_sort.field] + return _sort + }) + } + if (this.searchData.length === 0) { + delete params.search + delete params.searchLogic + } + if (this.sortData.length === 0) { + delete params.sort + } + // append other params + w2utils.extend(params, this.postData) + w2utils.extend(params, postData) + // other actions + if (action == 'delete' || action == 'save') { + delete params.limit + delete params.offset + params.action = action + if (action == 'delete') { + params[this.recid || 'recid'] = this.getSelection() + } + } + // event before + if (action == 'load') { + edata = this.trigger('request', { target: this.name, url, postData: params, httpMethod: 'GET', + httpHeaders: this.httpHeaders }) + if (edata.isCancelled === true) return new Promise((resolve, reject) => { reject() }) + } else { + edata = { detail: { + url, + postData: params, + httpMethod: action == 'save' ? 'PUT' : 'DELETE', + httpHeaders: this.httpHeaders + }} + } + // call server to get data + if (this.last.fetch.offset === 0) { + this.lock(w2utils.lang(this.msgRefresh), true) + } + if (this.last.fetch.controller) try { this.last.fetch.controller.abort() } catch (e) {} + // URL + url = edata.detail.url + switch (action) { + case 'save': + if (url?.save) url = url.save + break + case 'delete': + if (url?.remove) url = url.remove + break + default: + url = url?.get ?? url + } + // process url with routeData + if (Object.keys(this.routeData).length > 0) { + let info = w2utils.parseRoute(url) + if (info.keys.length > 0) { + for (let k = 0; k < info.keys.length; k++) { + if (this.routeData[info.keys[k].name] == null) continue + url = url.replace((new RegExp(':'+ info.keys[k].name, 'g')), this.routeData[info.keys[k].name]) + } + } + } + url = new URL(url, location) + // ajax options + let fetchOptions = w2utils.prepareParams(url, { + method: edata.detail.httpMethod, + headers: edata.detail.httpHeaders, + body: edata.detail.postData + }, this.dataType) + Object.assign(this.last.fetch, { + action: action, + options: fetchOptions, + controller: new AbortController(), + start: Date.now(), + loaded: false + }) + fetchOptions.signal = this.last.fetch.controller.signal + fetch(url, fetchOptions) + .catch(processError) + .then(resp => { + if (resp == null) return // request aborted + if (resp?.status != 200) { + processError(resp ?? {}) + return + } + self.unlock() + resp.json() + .catch(processError) + .then(data => { + this.requestComplete(data, action, callBack, resolve, reject) + }) + }) + if (action == 'load') { + // event after + edata.finish() + } + return requestProm + function processError(response) { + if (response?.name === 'AbortError') { + // request was aborted by the grid + return + } + self.unlock() + // trigger event + let edata2 = self.trigger('error', { response, lastFetch: self.last.fetch }) + if (edata2.isCancelled === true) return + // default behavior + if (response.status && response.status != 200) { + self.error(response.status + ': ' + response.statusText) + } else { + console.log('ERROR: Server communication failed.', + '\n EXPECTED:', { total: 5, records: [{ recid: 1, field: 'value' }] }, + '\n OR:', { error: true, message: 'error message' }) + self.requestComplete({ error: true, message: w2utils.lang(this.msgHTTPError), response }, action, callBack, resolve, reject) + } + // event after + edata2.finish() + } + } + requestComplete(data, action, callBack, resolve, reject) { + let error = data.error ?? false + if (data.error == null && data.status === 'error') error = true + this.last.fetch.response = (Date.now() - this.last.fetch.start) / 1000 + setTimeout(() => { + if (this.show.statusResponse) { + this.status(w2utils.lang('Server Response ${count} seconds', { count: this.last.fetch.response })) + } + }, 10) + this.last.pull_more = false + this.last.pull_refresh = true + // event before + let event_name = 'load' + if (this.last.fetch.action == 'save') event_name = 'save' + if (this.last.fetch.action == 'delete') event_name = 'delete' + let edata = this.trigger(event_name, { target: this.name, error, data, lastFetch: this.last.fetch }) + if (edata.isCancelled === true) { + reject() + return + } + // parse server response + if (!error) { + // default action + if (typeof this.parser == 'function') { + data = this.parser(data) + if (typeof data != 'object') { + console.log('ERROR: Your parser did not return proper object') + } + } else { + if (data == null) { + data = { + error: true, + message: w2utils.lang(this.msgNotJSON), + } + } else if (Array.isArray(data)) { + // if it is plain array, assume these are records + data = { + error, + records: data, + total: data.length + } + } + } + if (action == 'load') { + if (data.total == null) data.total = -1 + if (data.records == null) { + data.records = [] + } + if (data.records.length == this.limit) { + let loaded = this.records.length + data.records.length + this.last.fetch.hasMore = (loaded == this.total ? false : true) + } else { + this.last.fetch.hasMore = false + this.total = this.offset + this.last.fetch.offset + data.records.length + } + if (!this.last.fetch.hasMore) { + // if no more records, then hide spinner + query(this.box).find('#grid_'+ this.name +'_rec_more, #grid_'+ this.name +'_frec_more').hide() + } + if (this.last.fetch.offset === 0) { + this.records = [] + this.summary = [] + } else { + if (data.total != -1 && parseInt(data.total) != parseInt(this.total)) { + let grid = this + this.message(w2utils.lang(this.msgNeedReload)) + .ok(() => { + delete grid.last.fetch.offset + grid.reload() + }) + return new Promise(resolve => { resolve() }) + } + } + if (w2utils.isInt(data.total)) this.total = parseInt(data.total) + // records + if (data.records) { + data.records.forEach(rec => { + if (this.recid) { + rec.recid = this.parseField(rec, this.recid) + } + if (rec.recid == null) { + rec.recid = 'recid-' + this.records.length + } + if (rec.w2ui?.summary === true) { + this.summary.push(rec) + } else { + this.records.push(rec) + } + }) + } + // summary records (if any) + if (data.summary) { + this.summary = [] // reset summary with each call + data.summary.forEach(rec => { + if (this.recid) { + rec.recid = this.parseField(rec, this.recid) + } + if (rec.recid == null) { + rec.recid = 'recid-' + this.summary.length + } + this.summary.push(rec) + }) + } + } else if (action == 'delete') { + this.reset() // unselect old selections + return this.reload() + } + } else { + this.error(w2utils.lang(data.message ?? this.msgServerError)) + reject(data) + } + // event after + let url = this.url?.get ?? this.url + if (!url) { + this.localSort() + this.localSearch() + } + this.total = parseInt(this.total) + // do not refresh if loading on infinite scroll + if (this.last.fetch.offset === 0) { + this.refresh() + } else { + this.scroll() + this.resize() + } + // call back + if (typeof callBack == 'function') callBack(data) // need to be before event:after + resolve(data) + // after event + edata.finish() + this.last.fetch.loaded = true + } + error(msg) { + // let the management of the error outside of the grid + let edata = this.trigger('error', { target: this.name, message: msg }) + if (edata.isCancelled === true) { + return + } + this.message(msg) + // event after + edata.finish() + } + getChanges(recordsBase) { + let changes = [] + if (typeof recordsBase == 'undefined') { + recordsBase = this.records + } + for (let r = 0; r < recordsBase.length; r++) { + let rec = recordsBase[r] + if (rec?.w2ui) { + if (rec.w2ui.changes != null) { + let obj = {} + obj[this.recid || 'recid'] = rec.recid + changes.push(w2utils.extend(obj, rec.w2ui.changes)) + } + // recursively look for changes in non-expanded children + if (rec.w2ui.expanded !== true && rec.w2ui.children && rec.w2ui.children.length) { + changes.push(...this.getChanges(rec.w2ui.children)) + } + } + } + return changes + } + mergeChanges() { + let changes = this.getChanges() + for (let c = 0; c < changes.length; c++) { + let record = this.get(changes[c][this.recid || 'recid']) + for (let s in changes[c]) { + if (s == 'recid' || (this.recid && s == this.recid)) continue // do not allow to change recid + if (typeof changes[c][s] === 'object') changes[c][s] = changes[c][s].text + try { + _setValue(record, s, changes[c][s]) + } catch (e) { + console.log('ERROR: Cannot merge. ', e.message || '', e) + } + if (record.w2ui) delete record.w2ui.changes + } + } + this.refresh() + function _setValue(obj, field, value) { + let fld = field.split('.') + if (fld.length == 1) { + obj[field] = value + } else { + obj = obj[fld[0]] + fld.shift() + _setValue(obj, fld.join('.'), value) + } + } + } + save(callBack) { + let changes = this.getChanges() + let url = this.url?.save ?? this.url + // event before + let edata = this.trigger('save', { target: this.name, changes: changes }) + if (edata.isCancelled === true) return + if (url) { + this.request('save', { 'changes' : edata.detail.changes }, null, + (data) => { + if (!data.error) { + // only merge changes, if save was successful + this.mergeChanges() + } + // event after + edata.finish() + // call back + if (typeof callBack == 'function') callBack(data) + } + ) + } else { + this.mergeChanges() + // event after + edata.finish() + } + } + editField(recid, column, value, event) { + let self = this + if (this.last.inEditMode === true) { + // This is triggerign when user types fast + if (event && event.keyCode == 13) { + let { index, column, value } = this.last._edit + this.editChange({ type: 'custom', value }, index, column, event) + this.editDone(index, column, event) + } else { + // when 2 chars entered fast (spreadsheet) + let input = query(this.box).find('div.w2ui-edit-box .w2ui-input') + if (input.length > 0) { + if (input.get(0).tagName == 'DIV') { + input.text(input.text() + value) + w2utils.setCursorPosition(input.get(0), input.text().length) + } else { + input.val(input.val() + value) + w2utils.setCursorPosition(input.get(0), input.val().length) + } + } + } + return + } + let index = this.get(recid, true) + let edit = this.getCellEditable(index, column) + if (!edit || ['checkbox', 'check'].includes(edit.type)) return + let rec = this.records[index] + let col = this.columns[column] + let prefix = (col.frozen === true ? '_f' : '_') + if (['enum', 'file'].indexOf(edit.type) != -1) { + console.log('ERROR: input types "enum" and "file" are not supported in inline editing.') + return + } + // event before + let edata = this.trigger('editField', { target: this.name, recid, column, value, index, originalEvent: event }) + if (edata.isCancelled === true) return + value = edata.detail.value + // default behaviour + this.last.inEditMode = true + this.last.editColumn = column + this.last._edit = { value: value, index: index, column: column, recid: recid } + this.selectNone(true) // no need to trigger select event + this.select({ recid: recid, column: column }) + // create input element + let tr = query(this.box).find('#grid_'+ this.name + prefix +'rec_' + w2utils.escapeId(recid)) + let div = tr.find('[col="'+ column +'"] > div') // TD -> DIV + this.last._edit.tr = tr + this.last._edit.div = div + // clear previous if any (spreadsheet) + query(this.box).find('div.w2ui-edit-box').remove() + // for spreadsheet - insert into selection + if (this.selectType != 'row') { + query(this.box).find('#grid_'+ this.name + prefix + 'selection') + .attr('id', 'grid_'+ this.name + '_editable') + .removeClass('w2ui-selection') + .addClass('w2ui-edit-box') + .prepend('
    ') + .find('.w2ui-selection-resizer') + .remove() + div = query(this.box).find('#grid_'+ this.name + '_editable > div:first-child') + } + edit.attr = edit.attr ?? '' + edit.text = edit.text ?? '' + edit.style = edit.style ?? '' + edit.items = edit.items ?? [] + let val = (rec.w2ui?.changes?.[col.field] != null + ? w2utils.stripTags(rec.w2ui.changes[col.field]) + : w2utils.stripTags(self.parseField(rec, col.field))) + if (val == null) val = '' + let prevValue = (typeof val != 'object' ? val : '') + if (edata.detail.prevValue != null) prevValue = edata.detail.prevValue + if (value != null) val = value + let addStyle = (col.style != null ? col.style + ';' : '') + if (typeof col.render == 'string' + && ['number', 'int', 'float', 'money', 'percent', 'size'].includes(col.render.split(':')[0])) { + addStyle += 'text-align: right;' + } + // normalize items, if not yet normlized + if (edit.items.length > 0 && !w2utils.isPlainObject(edit.items[0])) { + edit.items = w2utils.normMenu(edit.items) + } + let input + let dropTypes = ['date', 'time', 'datetime', 'color', 'list', 'combo'] + let styles = getComputedStyle(tr.find('[col="'+ column +'"] > div').get(0)) + let font = `font-family: ${styles['font-family']}; font-size: ${styles['font-size']};` + switch (edit.type) { + case 'div': { + div.addClass('w2ui-editable') + .html(w2utils.stripSpaces(`
    +
    ${edit.text}`)) + input = div.find('div.w2ui-input').get(0) + input.innerText = (typeof val != 'object' ? val : '') + if (value != null) { + w2utils.setCursorPosition(input, input.innerText.length) + } else { + w2utils.setCursorPosition(input, 0, input.innerText.length) + } + break + } + default: { + div.addClass('w2ui-editable') + .html(w2utils.stripSpaces(`${edit.text}`)) + input = div.find('input').get(0) + // issue #499 + if (edit.type == 'number') { + val = w2utils.formatNumber(val) + } + if (edit.type == 'date') { + val = w2utils.formatDate(w2utils.isDate(val, edit.format, true) || new Date(), edit.format) + } + input.value = (typeof val != 'object' ? val : '') + // init w2field, attached to input._w2field + let doHide = (event) => { + let escKey = this.last._edit?.escKey + // check if any element is selected in drop down + let selected = false + let name = query(input).data('tooltipName') + if (name && w2tooltip.get(name[0])?.selected != null) { + selected = true + } + // trigger change on new value if selected from overlay + if (this.last.inEditMode && !escKey && dropTypes.includes(edit.type) // drop down types + && (event.detail.overlay.anchor?.id == this.last._edit.input?.id || edit.type == 'list')) { + this.editChange() + this.editDone(undefined, undefined, { keyCode: selected ? 13 : 0 }) // advance on select + } + } + new w2field(w2utils.extend({}, edit, { + el: input, + selected: val, + onSelect: doHide, + onHide: doHide + })) + if (value == null && input) { + // if no new value, then select content + input.select() + } + } + } + Object.assign(this.last._edit, { input, edit }) + query(input) + .off('.w2ui-editable') + .on('blur.w2ui-editable', (event) => { + if (this.last.inEditMode) { + let type = this.last._edit.edit.type + let name = query(input).data('tooltipName') // if popup is open + if (dropTypes.includes(type) && name) { + // drop downs finish edit when popover is closed + return + } + this.editChange(input, index, column, event) + this.editDone() + } + }) + .on('mousedown.w2ui-editable', (event) => { + event.stopPropagation() + }) + .on('click.w2ui-editable', (event) => { + expand.call(input, event) + }) + .on('paste.w2ui-editable', (event) => { + // clean paste to be plain text + event.preventDefault() + let text = event.clipboardData.getData('text/plain') + document.execCommand('insertHTML', false, text) + }) + .on('keyup.w2ui-editable', (event) => { + expand.call(input, event) + }) + .on('keydown.w2ui-editable', (event) => { + switch (event.keyCode) { + case 8: // backspace; + if (edit.type == 'list' && !input._w2field) { // cancel backspace when deleting element + event.preventDefault() + } + break + case 9: + case 13: + event.preventDefault() + break + case 27: // esc button exits edit mode, but if in a popup, it will also close the popup, hence + // if tooltip is open - hide it + let name = query(input).data('tooltipName') + if (name && name.length > 0) { + this.last._edit.escKey = true + w2tooltip.hide(name[0]) + event.preventDefault() + } + event.stopPropagation() + break + } + // need timeout so, this handler is executed after key is processed by browser + setTimeout(() => { + switch (event.keyCode) { + case 9: { // tab + let next = event.shiftKey + ? self.prevCell(index, column, true) + : self.nextCell(index, column, true) + if (next != null) { + let recid = self.records[next.index].recid + this.editChange(input, index, column, event) + this.editDone(index, column, event) + if (self.selectType != 'row') { + self.selectNone(true) // no need to trigger select event + self.select({ recid, column: next.colIndex }) + } else { + self.editField(recid, next.colIndex, null, event) + } + if (event.preventDefault) event.preventDefault() + } + break + } + case 13: { // enter + // check if any element is selected in drop down + let selected = false + let name = query(input).data('tooltipName') + if (name && w2tooltip.get(name[0]).selected != null) { + selected = true + } + // if tooltip is not open or no element is selected + if (!name || !selected) { + this.editChange(input, index, column, event) + this.editDone(index, column, event) + } + break + } + case 27: { // escape + this.last._edit.escKey = false + let old = self.parseField(rec, col.field) + if (rec.w2ui?.changes?.[col.field] != null) old = rec.w2ui.changes[col.field] + if (input._prevValue != null) old = input._prevValue + if (input.tagName == 'DIV') { + input.innerText = old != null ? old : '' + } else { + input.value = old != null ? old : '' + } + this.editDone(index, column, event) + setTimeout(() => { self.select({ recid: recid, column: column }) }, 1) + break + } + } + // if input too small - expand + expand(input) + }, 1) + }) + // save previous value + if (input) input._prevValue = prevValue + // focus and select + if (edit.type != 'list') { + setTimeout(() => { + if (!this.last.inEditMode) return + if (input) { + input.focus() + clearTimeout(this.last.kbd_timer) // keep focus + input.resize = expand + expand(input) + } + }, 50) + } + // event after + edata.finish({ input }) + return + function expand(input) { + try { + let styles = getComputedStyle(input) + let val = (input.tagName.toUpperCase() == 'DIV' ? input.innerText : input.value) + let editBox = query(self.box).find('#grid_'+ self.name + '_editable').get(0) + let style = `font-family: ${styles['font-family']}; font-size: ${styles['font-size']}; white-space: no-wrap;` + let width = w2utils.getStrWidth(val, style) + if (width + 20 > editBox.clientWidth) { + query(editBox).css('width', width + 20 + 'px') + } + } catch (e) { + } + } + } + editChange(input, index, column, event) { + // if params are not specified + input = input ?? this.last._edit.input + index = index ?? this.last._edit.index + column = column ?? this.last._edit.column + event = event ?? {} + // all other fields + let summary = index < 0 + index = index < 0 ? -index - 1 : index + let records = summary ? this.summary : this.records + let rec = records[index] + let col = this.columns[column] + let new_val = (input?.tagName == 'DIV' ? input.innerText : input.value) + let fld = input._w2field + if (fld) { + if (fld.type == 'list') { + new_val = fld.selected + } + if (Object.keys(new_val).length === 0 || new_val == null) new_val = '' + if (!w2utils.isPlainObject(new_val)) new_val = fld.clean(new_val) + } + if (input.type == 'checkbox') { + if (rec.w2ui?.editable === false) input.checked = !input.checked + new_val = input.checked + } + let old_val = this.parseField(rec, col.field) + let prev_val = (rec.w2ui?.changes && rec.w2ui.changes.hasOwnProperty(col.field) ? rec.w2ui.changes[col.field]: old_val) + // change/restore event + let edata = { + target: this.name, input, + recid: rec.recid, index, column, + originalEvent: event, + value: { + new: new_val, + previous: prev_val, + original: old_val, + } + } + if (event.target?._prevValue != null) edata.value.previous = event.target._prevValue + let count = 0 // just in case to avoid infinite loop + while (count < 20) { + count++ + new_val = edata.value.new + if ((typeof new_val != 'object' && String(old_val) != String(new_val)) || + (typeof new_val == 'object' && new_val && new_val.id != old_val + && (typeof old_val != 'object' || old_val == null || new_val.id != old_val.id))) { + // change event + edata = this.trigger('change', edata) + if (edata.isCancelled !== true) { + if (new_val !== edata.detail.value.new) { + // re-evaluate the type of change to be made + continue + } + // default action + if ((edata.detail.value.new === '' || edata.detail.value.new == null) && (prev_val === '' || prev_val == null)) { + // value did not change, was empty is empty + } else { + rec.w2ui = rec.w2ui ?? {} + rec.w2ui.changes = rec.w2ui.changes ?? {} + rec.w2ui.changes[col.field] = edata.detail.value.new + } + // event after + edata.finish() + } + } else { + // restore event + edata = this.trigger('restore', edata) + if (edata.isCancelled !== true) { + if (new_val !== edata.detail.value.new) { + // re-evaluate the type of change to be made + continue + } + // default action + if (rec.w2ui?.changes) { + delete rec.w2ui.changes[col.field] + if (Object.keys(rec.w2ui.changes).length === 0) { + delete rec.w2ui.changes + } + } + // event after + edata.finish() + } + } + break + } + } + editDone(index, column, event) { + // if params are not specified + index = index ?? this.last._edit.index + column = column ?? this.last._edit.column + event = event ?? {} + // removal of input happens when TR is redrawn + if (this.advanceOnEdit && event.keyCode == 13) { + let next = event.shiftKey ? this.prevRow(index, column, 1) : this.nextRow(index, column, 1) + if (next == null) next = index // keep the same + setTimeout(() => { + if (this.selectType != 'row') { + this.selectNone(true) // no need to trigger select event + this.select({ recid: this.records[next].recid, column: column }) + } else { + this.editField(this.records[next].recid, column, null, event) + } + }, 1) + } + let summary = index < 0 + let cell = query(this.last._edit.tr).find('[col="'+ column +'"]') + let rec = this.records[index] + let col = this.columns[column] + // need to set before remove, as remove will trigger blur + this.last.inEditMode = false + this.last._edit = null + // remove - by updating cell data + if (!summary) { + if (rec.w2ui?.changes?.[col.field] != null) { + cell.addClass('w2ui-changed') + } else { + cell.removeClass('w2ui-changed') + } + cell.replace(this.getCellHTML(index, column, summary)) + } + // remove - spreadsheet + query(this.box).find('div.w2ui-edit-box').remove() + // update toolbar buttons + this.updateToolbar() + // keep grid in focus if needed + setTimeout(() => { + let input = query(this.box).find(`#grid_${this.name}_focus`).get(0) + if (document.activeElement !== input && !this.last.inEditMode) { + input.focus() + } + }, 10) + } + 'delete'(force) { + // event before + let edata = this.trigger('delete', { target: this.name, force: force }) + if (force) this.message() // close message + if (edata.isCancelled === true) return + force = edata.detail.force + // default action + let recs = this.getSelection() + if (recs.length === 0) return + if (this.msgDelete != '' && !force) { + this.confirm({ + text: w2utils.lang(this.msgDelete, { + count: recs.length, + records: w2utils.lang( recs.length == 1 ? 'record' : 'records') + }), + width: 380, + height: 170, + yes_text: w2utils.lang('Delete'), + yes_class: 'w2ui-btn-red', + no_text: w2utils.lang('Cancel'), + }) + .yes(event => { + event.detail.self.close() + this.delete(true) + }) + .no(event => { + event.detail.self.close() + }) + return + } + // call delete script + let url = (typeof this.url != 'object' ? this.url : this.url.remove) + if (url) { + this.request('delete') + } else { + if (typeof recs[0] != 'object') { + this.selectNone() + this.remove.apply(this, recs) + } else { + // clear cells + for (let r = 0; r < recs.length; r++) { + let fld = this.columns[recs[r].column].field + let ind = this.get(recs[r].recid, true) + let rec = this.records[ind] + if (ind != null && fld != 'recid') { + this.records[ind][fld] = '' + if (rec.w2ui?.changes) delete rec.w2ui.changes[fld] + // -- style should not be deleted + // if (rec.style != null && w2utils.isPlainObject(rec.style) && rec.style[recs[r].column]) { + // delete rec.style[recs[r].column]; + // } + } + } + this.update() + } + } + // event after + edata.finish() + } + click(recid, event) { + let time = Date.now() + let column = null + if (this.last.cancelClick == true || (event && event.altKey)) return + if ((typeof recid == 'object') && (recid !== null)) { + column = recid.column + recid = recid.recid + } + if (event == null) event = {} + // check for double click + if (time - parseInt(this.last.click_time) < 350 && this.last.click_recid == recid && event.type == 'click') { + this.dblClick(recid, event) + return + } + // hide bubble + if (this.last.bubbleEl) { + this.last.bubbleEl = null + } + this.last.click_time = time + let last_recid = this.last.click_recid + this.last.click_recid = recid + // column user clicked on + if (column == null && event.target) { + let trg = event.target + if (trg.tagName != 'TD') trg = query(trg).closest('td')[0] + if (query(trg).attr('col') != null) column = parseInt(query(trg).attr('col')) + } + // event before + let edata = this.trigger('click', { target: this.name, recid, column, originalEvent: event }) + if (edata.isCancelled === true) return + // default action + let sel = this.getSelection() + query(this.box).find('#grid_'+ this.name +'_check_all').prop('checked', false) + let ind = this.get(recid, true) + let selectColumns = [] + this.last.sel_ind = ind + this.last.sel_col = column + this.last.sel_recid = recid + this.last.sel_type = 'click' + // multi select with shift key + let start, end, t1, t2 + if (event.shiftKey && sel.length > 0 && this.multiSelect) { + if (sel[0].recid) { + start = this.get(sel[0].recid, true) + end = this.get(recid, true) + if (column > sel[0].column) { + t1 = sel[0].column + t2 = column + } else { + t1 = column + t2 = sel[0].column + } + for (let c = t1; c <= t2; c++) selectColumns.push(c) + } else { + start = this.get(last_recid, true) + end = this.get(recid, true) + } + let sel_add = [] + if (start > end) { let tmp = start; start = end; end = tmp } + let url = this.url?.get ? this.url.get : this.url + for (let i = start; i <= end; i++) { + if (this.searchData.length > 0 && !url && !this.last.searchIds.includes(i)) continue + if (this.selectType == 'row') { + sel_add.push(this.records[i].recid) + } else { + for (let sc = 0; sc < selectColumns.length; sc++) { + sel_add.push({ recid: this.records[i].recid, column: selectColumns[sc] }) + } + } + //sel.push(this.records[i].recid); + } + this.select(sel_add) + } else { + let last = this.last.selection + let flag = (last.indexes.indexOf(ind) != -1 ? true : false) + let fselect = false + // if clicked on the checkbox + if (query(event.target).closest('td').hasClass('w2ui-col-select')) fselect = true + // clear other if necessary + if (((!event.ctrlKey && !event.shiftKey && !event.metaKey && !fselect) || !this.multiSelect) && !this.showSelectColumn) { + if (this.selectType != 'row' && !last.columns[ind]?.includes(column)) flag = false + this.selectNone(true) // no need to trigger select event + if (flag === true && sel.length == 1) { + this.unselect({ recid: recid, column: column }) + } else { + this.select({ recid: recid, column: column }) + } + } else { + if (this.selectType != 'row' && !last.columns[ind]?.includes(column)) flag = false + if (flag === true) { + this.unselect({ recid: recid, column: column }) + } else { + this.select({ recid: recid, column: column }) + } + } + } + this.status() + this.initResize() + // event after + edata.finish() + } + columnClick(field, event) { + // ignore click if column was resized + if (this.last.colResizing === true) { + return + } + // event before + let edata = this.trigger('columnClick', { target: this.name, field: field, originalEvent: event }) + if (edata.isCancelled === true) return + // default behaviour + if (this.selectType == 'row') { + let column = this.getColumn(field) + if (column && column.sortable) this.sort(field, null, (event && (event.ctrlKey || event.metaKey) ? true : false)) + if (edata.detail.field == 'line-number') { + if (this.getSelection().length >= this.records.length) { + this.selectNone() + } else { + this.selectAll() + } + } + } else { + if (event.altKey){ + let column = this.getColumn(field) + if (column && column.sortable) this.sort(field, null, (event && (event.ctrlKey || event.metaKey) ? true : false)) + } + // select entire column + if (edata.detail.field == 'line-number') { + if (this.getSelection().length >= this.records.length) { + this.selectNone() + } else { + this.selectAll() + } + } else { + if (!event.shiftKey && !event.metaKey && !event.ctrlKey) { + this.selectNone(true) + } + let tmp = this.getSelection() + let column = this.getColumn(edata.detail.field, true) + let sel = [] + let cols = [] + // check if there was a selection before + if (tmp.length != 0 && event.shiftKey) { + let start = column + let end = tmp[0].column + if (start > end) { + start = tmp[0].column + end = column + } + for (let i = start; i<=end; i++) cols.push(i) + } else { + cols.push(column) + } + edata = this.trigger('columnSelect', { target: this.name, columns: cols }) + if (edata.isCancelled !== true) { + for (let i = 0; i < this.records.length; i++) { + sel.push({ recid: this.records[i].recid, column: cols }) + } + this.select(sel) + } + edata.finish() + } + } + // event after + edata.finish() + } + columnDblClick(field, event) { + // event before + let edata = this.trigger('columnDblClick', { target: this.name, field: field, originalEvent: event }) + if (edata.isCancelled === true) return + // event after + edata.finish() + } + columnContextMenu(field, event) { + let edata = this.trigger('columnContextMenu', {target: this.name, field: field, originalEvent: event }) + if (edata.isCancelled === true) return + if (this.show.columnMenu) { + w2menu.show({ + type: 'check', + anchor: document.body, + originalEvent: event, + items: this.initColumnOnOff() + }) + .then(() => { + query('#w2overlay-context-menu .w2ui-grid-skip') + .off('.w2ui-grid') + .on('click.w2ui-grid', evt => { + evt.stopPropagation() + }) + .on('keypress', evt => { + if (evt.keyCode == 13) { + this.skip(evt.target.value) + this.toolbar.click('w2ui-column-on-off') // close menu + } + }) + }) + .select((event) => { + let id = event.detail.item.id + if (['w2ui-stateSave', 'w2ui-stateReset'].includes(id)) { + this[id.substring(5)]() + } else if (id == 'w2ui-skip') { + // empty + } else { + this.columnOnOff(event, event.detail.item.id) + } + clearTimeout(this.last.kbd_timer) // keep grid in focus + }) + clearTimeout(this.last.kbd_timer) // keep grid in focus + } + event.preventDefault() + edata.finish() + } + focus(event) { + // event before + let edata = this.trigger('focus', { target: this.name, originalEvent: event }) + if (edata.isCancelled === true) return false + // default behaviour + this.hasFocus = true + query(this.box).removeClass('w2ui-inactive').find('.w2ui-inactive').removeClass('w2ui-inactive') + setTimeout(() => { + let txt = query(this.box).find(`#grid_${this.name}_focus`).get(0) + if (txt && document.activeElement != txt) { + txt.focus() + } + }, 10) + // event after + edata.finish() + } + blur(event) { + // event before + let edata = this.trigger('blur', { target: this.name, originalEvent: event }) + if (edata.isCancelled === true) return false + // default behaviour + this.hasFocus = false + query(this.box).addClass('w2ui-inactive').find('.w2ui-selected').addClass('w2ui-inactive') + query(this.box).find('.w2ui-selection').addClass('w2ui-inactive') + // event after + edata.finish() + } + keydown(event) { + // this method is called from w2utils + let obj = this + let url = (typeof this.url != 'object' ? this.url : this.url.get) + if (obj.keyboard !== true) return + // trigger event + let edata = obj.trigger('keydown', { target: obj.name, originalEvent: event }) + if (edata.isCancelled === true) return + // default behavior + if (query(this.box).find('.w2ui-message').length > 0) { + // if there are messages + if (event.keyCode == 27) this.message() + return + } + let empty = false + let records = query(obj.box).find('#grid_'+ obj.name +'_records') + let sel = obj.getSelection() + if (sel.length === 0) empty = true + let recid = sel[0] || null + let columns = [] + let recid2 = sel[sel.length-1] + if (typeof recid == 'object' && recid != null) { + recid = sel[0].recid + columns = [] + let ii = 0 + while (true) { + if (!sel[ii] || sel[ii].recid != recid) break + columns.push(sel[ii].column) + ii++ + } + recid2 = sel[sel.length-1].recid + } + let ind = obj.get(recid, true) + let ind2 = obj.get(recid2, true) + let recEL = query(obj.box).find(`#grid_${obj.name}_rec_${(ind != null ? w2utils.escapeId(obj.records[ind].recid) : 'none')}`) + let pageSize = Math.floor(records[0].clientHeight / obj.recordHeight) + let cancel = false + let key = event.keyCode + let shiftKey = event.shiftKey + switch (key) { + case 8: // backspace + case 46: // delete + // delete if button is visible + obj.delete() + cancel = true + event.stopPropagation() + break + case 27: // escape + obj.selectNone() + cancel = true + break + case 65: // cmd + A + if (!event.metaKey && !event.ctrlKey) break + obj.selectAll() + cancel = true + break + case 13: // enter + // if expandable columns - expand it + if (this.selectType == 'row' && obj.show.expandColumn === true) { + if (recEL.length <= 0) break + obj.toggle(recid, event) + cancel = true + } else { // or enter edit + for (let c = 0; c < this.columns.length; c++) { + let edit = this.getCellEditable(ind, c) + if (edit) { + columns.push(parseInt(c)) + break + } + } + // edit last column that was edited + if (this.selectType == 'row' && this.last._edit && this.last._edit.column) { + columns = [this.last._edit.column] + } + if (columns.length > 0) { + obj.editField(recid, this.last.editColumn || columns[0], null, event) + cancel = true + } + } + break + case 37: // left + moveLeft() + break + case 39: // right + moveRight() + break + case 33: // + moveUp(pageSize) + break + case 34: // + moveDown(pageSize) + break + case 35: // + moveDown(-1) + break + case 36: // + moveUp(-1) + break + case 38: // up + // ctrl (or cmd) + up -> same as home + moveUp(event.metaKey || event.ctrlKey ? -1 : 1) + break + case 40: // down + // ctrl (or cmd) + up -> same as end + moveDown(event.metaKey || event.ctrlKey ? -1 : 1) + break + // copy & paste + case 17: // ctrl key + case 91: // cmd key + // SLOW: 10k records take 7.0 + if (empty) break + // in Safari need to copy to buffer on cmd or ctrl key (otherwise does not work) + if (w2utils.isSafari) { + obj.last.copy_event = obj.copy(false, event) + let focus = query(obj.box).find('#grid_'+ obj.name + '_focus') + focus.val(obj.last.copy_event.detail.text) + focus[0].select() + } + break + case 67: // - c + // this fill trigger event.onComplete + if (event.metaKey || event.ctrlKey) { + if (w2utils.isSafari) { + obj.copy(obj.last.copy_event, event) + } else { + obj.last.copy_event = obj.copy(false, event) + let focus = query(obj.box).find('#grid_'+ obj.name + '_focus') + focus.val(obj.last.copy_event.detail.text) + focus[0].select() + obj.copy(obj.last.copy_event, event) + } + } + break + case 88: // x - cut + if (empty) break + if (event.ctrlKey || event.metaKey) { + if (w2utils.isSafari) { + obj.copy(obj.last.copy_event, event) + } else { + obj.last.copy_event = obj.copy(false, event) + let focus = query(obj.box).find('#grid_'+ obj.name + '_focus') + focus.val(obj.last.copy_event.detail.text) + focus[0].select() + obj.copy(obj.last.copy_event, event) + } + } + break + } + let tmp = [32, 187, 189, 192, 219, 220, 221, 186, 222, 188, 190, 191] // other typeable chars + for (let i = 48; i <= 111; i++) tmp.push(i) // 0-9,a-z,A-Z,numpad + if (tmp.indexOf(key) != -1 && !event.ctrlKey && !event.metaKey && !cancel) { + if (columns.length === 0) columns.push(0) + cancel = false + // move typed key into edit + setTimeout(() => { + let focus = query(obj.box).find('#grid_'+ obj.name + '_focus') + let key = focus.val() + focus.val('') + obj.editField(recid, columns[0], key, event) + }, 1) + } + if (cancel) { // cancel default behaviour + if (event.preventDefault) event.preventDefault() + } + // event after + edata.finish() + function moveLeft() { + if (empty) { // no selection + selectTopRecord() + return + } + if (obj.selectType == 'row') { + if (recEL.length <= 0) return + let tmp = obj.records[ind].w2ui || {} + if (tmp && tmp.parent_recid != null && (!Array.isArray(tmp.children) || tmp.children.length === 0 || !tmp.expanded)) { + obj.unselect(recid) + obj.collapse(tmp.parent_recid, event) + obj.select(tmp.parent_recid) + } else { + obj.collapse(recid, event) + } + } else { + let prev = obj.prevCell(ind, columns[0]) + if (prev?.index != ind) { + prev = null + } else { + prev = prev?.colIndex + } + if (!shiftKey && prev == null) { + obj.selectNone(true) + prev = 0 + } + if (prev != null) { + if (shiftKey && obj.multiSelect) { + if (tmpUnselect()) return + let tmp = [] + let newSel = [] + let unSel = [] + if (columns.indexOf(obj.last.sel_col) === 0 && columns.length > 1) { + for (let i = 0; i < sel.length; i++) { + if (tmp.indexOf(sel[i].recid) == -1) tmp.push(sel[i].recid) + unSel.push({ recid: sel[i].recid, column: columns[columns.length-1] }) + } + obj.unselect(unSel) + obj.scrollIntoView(ind, columns[columns.length-1], true) + } else { + for (let i = 0; i < sel.length; i++) { + if (tmp.indexOf(sel[i].recid) == -1) tmp.push(sel[i].recid) + newSel.push({ recid: sel[i].recid, column: prev }) + } + obj.select(newSel) + obj.scrollIntoView(ind, prev, true) + } + } else { + obj.click({ recid: recid, column: prev }, event) + obj.scrollIntoView(ind, prev, true) + } + } else { + // if selected more then one, then select first + if (!shiftKey) { + obj.selectNone(true) + } + } + } + cancel = true + } + function moveRight() { + if (empty) { + selectTopRecord() + return + } + if (obj.selectType == 'row') { + if (recEL.length <= 0) return + obj.expand(recid, event) + } else { + let next = obj.nextCell(ind, columns[columns.length-1]) // columns is an array of selected columns + if (next.index != ind) { + next = null + } else { + next = next.colIndex + } + if (!shiftKey && next == null) { + obj.selectNone(true) + next = obj.columns.length-1 + } + if (next != null) { + if (shiftKey && key == 39 && obj.multiSelect) { + if (tmpUnselect()) return + let tmp = [] + let newSel = [] + let unSel = [] + if (columns.indexOf(obj.last.sel_col) == columns.length-1 && columns.length > 1) { + for (let i = 0; i < sel.length; i++) { + if (tmp.indexOf(sel[i].recid) == -1) tmp.push(sel[i].recid) + unSel.push({ recid: sel[i].recid, column: columns[0] }) + } + obj.unselect(unSel) + obj.scrollIntoView(ind, columns[0], true) + } else { + for (let i = 0; i < sel.length; i++) { + if (tmp.indexOf(sel[i].recid) == -1) tmp.push(sel[i].recid) + newSel.push({ recid: sel[i].recid, column: next }) + } + obj.select(newSel) + obj.scrollIntoView(ind, next, true) + } + } else { + obj.click({ recid: recid, column: next }, event) + obj.scrollIntoView(ind, next, true) + } + } else { + // if selected more then one, then select first + if (!shiftKey) { + obj.selectNone(true) + } + } + } + cancel = true + } + function moveUp(numRows) { + if (empty) selectTopRecord() + if (recEL.length <= 0) return + // move to the previous record + let prev = obj.prevRow(ind, obj.selectType == 'row' ? 0 : sel[0].column, numRows) + if (!shiftKey && prev == null) { + if (obj.searchData.length != 0 && !url) { + prev = obj.last.searchIds[0] + } else { + prev = 0 + } + } + if (prev != null) { + if (shiftKey && obj.multiSelect) { // expand selection + if (tmpUnselect()) return + if (obj.selectType == 'row') { + if (obj.last.sel_ind > prev && obj.last.sel_ind != ind2) { + obj.unselect(obj.records[ind2].recid) + } else { + obj.select(obj.records[prev].recid) + } + } else { + if (obj.last.sel_ind > prev && obj.last.sel_ind != ind2) { + prev = ind2 + let tmp = [] + for (let c = 0; c < columns.length; c++) tmp.push({ recid: obj.records[prev].recid, column: columns[c] }) + obj.unselect(tmp) + } else { + let tmp = [] + for (let c = 0; c < columns.length; c++) tmp.push({ recid: obj.records[prev].recid, column: columns[c] }) + obj.select(tmp) + } + } + } else { // move selected record + obj.selectNone(true) // no need to trigger select event + obj.click({ recid: obj.records[prev].recid, column: columns[0] }, event) + } + obj.scrollIntoView(prev, null, true, numRows != 1) // top align record + if (event.preventDefault) event.preventDefault() + } else { + // if selected more then one, then select first + if (!shiftKey) { + obj.selectNone(true) + } + } + } + function moveDown(numRows) { + if (empty) selectTopRecord() + if (recEL.length <= 0) return + // move to the next record + let next = obj.nextRow(ind2, obj.selectType == 'row' ? 0 : sel[0].column, numRows) + if (!shiftKey && next == null) { + if (obj.searchData.length != 0 && !url) { + next = obj.last.searchIds[obj.last.searchIds.length - 1] + } else { + next = obj.records.length - 1 + } + } + if (next != null) { + if (shiftKey && obj.multiSelect) { // expand selection + if (tmpUnselect()) return + if (obj.selectType == 'row') { + if (obj.last.sel_ind < next && obj.last.sel_ind != ind) { + obj.unselect(obj.records[ind].recid) + } else { + obj.select(obj.records[next].recid) + } + } else { + if (obj.last.sel_ind < next && obj.last.sel_ind != ind) { + next = ind + let tmp = [] + for (let c = 0; c < columns.length; c++) tmp.push({ recid: obj.records[next].recid, column: columns[c] }) + obj.unselect(tmp) + } else { + let tmp = [] + for (let c = 0; c < columns.length; c++) tmp.push({ recid: obj.records[next].recid, column: columns[c] }) + obj.select(tmp) + } + } + } else { // move selected record + obj.selectNone(true) // no need to trigger select event + obj.click({ recid: obj.records[next].recid, column: columns[0] }, event) + } + obj.scrollIntoView(next, null, true, numRows != 1) // top align record + cancel = true + } else { + // if selected more then one, then select first + if (!shiftKey) { + obj.selectNone(true) // no need to trigger select event + } + } + } + function selectTopRecord() { + if (!obj.records || obj.records.length === 0) return + let ind = Math.floor(records[0].scrollTop / obj.recordHeight) + 1 + if (!obj.records[ind] || ind < 2) ind = 0 + if (typeof obj.records[ind] === 'undefined') return + obj.select({ recid: obj.records[ind].recid, column: 0}) + } + function tmpUnselect () { + if (obj.last.sel_type != 'click') return false + if (obj.selectType != 'row') { + obj.last.sel_type = 'key' + if (sel.length > 1) { + for (let s = 0; s < sel.length; s++) { + if (sel[s].recid == obj.last.sel_recid && sel[s].column == obj.last.sel_col) { + sel.splice(s, 1) + break + } + } + obj.unselect(sel) + return true + } + return false + } else { + obj.last.sel_type = 'key' + if (sel.length > 1) { + sel.splice(sel.indexOf(obj.records[obj.last.sel_ind].recid), 1) + obj.unselect(sel) + return true + } + return false + } + } + } + scrollIntoView(ind, column, instant, recTop) { + let buffered = this.records.length + if (this.searchData.length != 0 && !this.url) buffered = this.last.searchIds.length + if (buffered === 0) return + if (ind == null) { + let sel = this.getSelection() + if (sel.length === 0) return + if (w2utils.isPlainObject(sel[0])) { + ind = sel[0].index + column = sel[0].column + } else { + ind = this.get(sel[0], true) + } + } + let records = query(this.box).find(`#grid_${this.name}_records`) + let recWidth = records[0].clientWidth + let recHeight = records[0].clientHeight + let recSTop = records[0].scrollTop + let recSLeft = records[0].scrollLeft + // if all records in view + let len = this.last.searchIds.length + if (len > 0) ind = this.last.searchIds.indexOf(ind) // if search is applied + // smooth or instant + records.css({ 'scroll-behavior': instant ? 'auto' : 'smooth' }) + // vertical + if (recHeight < this.recordHeight * (len > 0 ? len : buffered) && records.length > 0) { + // scroll to correct one + let t1 = Math.floor(recSTop / this.recordHeight) + let t2 = t1 + Math.floor(recHeight / this.recordHeight) + if (ind == t1) { + records.prop('scrollTop', recSTop - recHeight / 1.3) + } + if (ind == t2) { + records.prop('scrollTop', recSTop + recHeight / 1.3) + } + if (ind < t1 || ind > t2) { + records.prop('scrollTop', (ind - 1) * this.recordHeight) + } + if (recTop === true) { + records.prop('scrollTop', ind * this.recordHeight) + } + } + // horizontal + if (column != null) { + let x1 = 0 + let x2 = 0 + let sb = w2utils.scrollBarSize() + for (let i = 0; i <= column; i++) { + let col = this.columns[i] + if (col.frozen || col.hidden) continue + x1 = x2 + x2 += parseInt(col.sizeCalculated) + } + if (recWidth < x2 - recSLeft) { // right + records.prop('scrollLeft', x1 - sb) + } else if (x1 < recSLeft) { // left + records.prop('scrollLeft', x2 - recWidth + sb * 2) + } + } + } + scrollToColumn(field) { + if (field == null) + return + let sWidth = 0 + let found = false + for (let i = 0; i < this.columns.length; i++) { + let col = this.columns[i] + if (col.field == field) { + found = true + break + } + if (col.frozen || col.hidden) + continue + let cSize = parseInt(col.sizeCalculated ? col.sizeCalculated : col.size) + sWidth += cSize + } + if (!found) + return + this.last.scrollLeft = sWidth+1 + this.scroll() + } + + dblClick(recid, event) { + // find columns + let column = null + if ((typeof recid == 'object') && (recid !== null)) { + column = recid.column + recid = recid.recid + } + if (event == null) event = {} + // column user clicked on + if (column == null && event.target) { + let tmp = event.target + if (tmp.tagName.toUpperCase() != 'TD') tmp = query(tmp).closest('td')[0] + column = parseInt(query(tmp).attr('col')) + } + let index = this.get(recid, true) + let rec = this.records[index] + // event before + let edata = this.trigger('dblClick', { target: this.name, recid: recid, column: column, originalEvent: event }) + if (edata.isCancelled === true) return + // default action + this.selectNone(true) // no need to trigger select event + let edit = this.getCellEditable(index, column) + if (edit) { + this.editField(recid, column, null, event) + } else { + this.select({ recid: recid, column: column }) + if (this.show.expandColumn || (rec && rec.w2ui && Array.isArray(rec.w2ui.children))) this.toggle(recid) + } + // event after + edata.finish() + } + showContextMenu(recid, column, event) { + if (this.last.userSelect == 'text') return + if (event == null) { + event = { offsetX: 0, offsetY: 0, target: query(this.box).find(`#grid_${this.name}_rec_${recid}`)[0] } + } + if (event.offsetX == null) { + event.offsetX = event.layerX - event.target.offsetLeft + event.offsetY = event.layerY - event.target.offsetTop + } + if (w2utils.isFloat(recid)) recid = parseFloat(recid) + let sel = this.getSelection() + if (this.selectType == 'row') { + if (sel.indexOf(recid) == -1) this.click(recid) + } else { + let selected = false + // check if any selected sel in the right row/column + for (let i = 0; i < sel.length; i++) { + if (sel[i].recid == recid || sel[i].column == column) selected = true + } + if (!selected && recid != null) this.click({ recid: recid, column: column }) + if (!selected && column != null) this.columnClick(this.columns[column].field, event) + } + // event before + let edata = this.trigger('contextMenu', { target: this.name, originalEvent: event, recid, column }) + if (edata.isCancelled === true) return + // default action + if (this.contextMenu.length > 0) { + w2menu.show({ + anchor: document.body, + originalEvent: event, + items: this.contextMenu + }) + .select((event) => { + clearTimeout(this.last.kbd_timer) // keep grid in focus + this.contextMenuClick(recid, column, event) + }) + clearTimeout(this.last.kbd_timer) // keep grid in focus + } + // cancel browser context menu + event.preventDefault() + // event after + edata.finish() + } + contextMenuClick(recid, column, event) { + // event before + let edata = this.trigger('contextMenuClick', { + target: this.name, recid, column, originalEvent: event.detail.originalEvent, + menuEvent: event, menuIndex: event.detail.index, menuItem: event.detail.item + }) + if (edata.isCancelled === true) return + // no default action + edata.finish() + } + toggle(recid) { + let rec = this.get(recid) + if (rec == null) return + rec.w2ui = rec.w2ui ?? {} + if (rec.w2ui.expanded === true) return this.collapse(recid); else return this.expand(recid) + } + expand(recid, noRefresh) { + let ind = this.get(recid, true) + let rec = this.records[ind] + rec.w2ui = rec.w2ui ?? {} + let id = w2utils.escapeId(recid) + let children = rec.w2ui.children + let edata + if (Array.isArray(children)) { + if (rec.w2ui.expanded === true || children.length === 0) return false // already shown + edata = this.trigger('expand', { target: this.name, recid: recid }) + if (edata.isCancelled === true) return false + rec.w2ui.expanded = true + children.forEach((child) => { + child.w2ui = child.w2ui ?? {} + child.w2ui.parent_recid = rec.recid + if (child.w2ui.children == null) child.w2ui.children = [] + }) + this.records.splice.apply(this.records, [ind + 1, 0].concat(children)) + if (this.total !== -1) { + this.total += children.length + } + let url = (typeof this.url != 'object' ? this.url : this.url.get) + if (!url) { + this.localSort(true, true) + if (this.searchData.length > 0) { + this.localSearch(true) + } + } + if (noRefresh !== true) this.refresh() + edata.finish() + } else { + if (query(this.box).find('#grid_'+ this.name +'_rec_'+ id +'_expanded_row').length > 0 || this.show.expandColumn !== true) return false + if (rec.w2ui.expanded == 'none') return false + // insert expand row + query(this.box).find('#grid_'+ this.name +'_rec_'+ id).after( + ` + +
    + + + `) + query(this.box).find('#grid_'+ this.name +'_frec_'+ id).after( + ` + ${this.show.lineNumbers ? '' : ''} + +
    + + `) + // event before + edata = this.trigger('expand', { target: this.name, recid: recid, + box_id: 'grid_'+ this.name +'_rec_'+ recid +'_expanded', fbox_id: 'grid_'+ this.name +'_frec_'+ recid +'_expanded' }) + if (edata.isCancelled === true) { + query(this.box).find('#grid_'+ this.name +'_rec_'+ id +'_expanded_row').remove() + query(this.box).find('#grid_'+ this.name +'_frec_'+ id +'_expanded_row').remove() + return false + } + // expand column + let row1 = query(this.box).find('#grid_'+ this.name +'_rec_'+ recid +'_expanded') + let row2 = query(this.box).find('#grid_'+ this.name +'_frec_'+ recid +'_expanded') + let innerHeight = row1.find(':scope div:first-child')[0]?.clientHeight ?? 50 + if (row1[0].clientHeight < innerHeight) { + row1.css({ height: innerHeight + 'px' }) + } + if (row2[0].clientHeight < innerHeight) { + row2.css({ height: innerHeight + 'px' }) + } + // default action + query(this.box).find('#grid_'+ this.name +'_rec_'+ id).attr('expanded', 'yes').addClass('w2ui-expanded') + query(this.box).find('#grid_'+ this.name +'_frec_'+ id).attr('expanded', 'yes').addClass('w2ui-expanded') + query(this.box).find('#grid_'+ this.name +'_cell_'+ this.get(recid, true) +'_expand div').html('-') + rec.w2ui.expanded = true + // event after + edata.finish() + this.resizeRecords() + } + return true + } + collapse(recid, noRefresh) { + let ind = this.get(recid, true) + let rec = this.records[ind] + rec.w2ui = rec.w2ui || {} + let id = w2utils.escapeId(recid) + let children = rec.w2ui.children + let edata + if (Array.isArray(children)) { + if (rec.w2ui.expanded !== true) return false // already hidden + edata = this.trigger('collapse', { target: this.name, recid: recid }) + if (edata.isCancelled === true) return false + clearExpanded(rec) + let stops = [] + for (let r = rec; r != null; r = this.get(r.w2ui.parent_recid)) + stops.push(r.w2ui.parent_recid) + // stops contains 'undefined' plus the ID of all nodes in the path from 'rec' to the tree root + let start = ind + 1 + let end = start + while (true) { + if (this.records.length <= end + 1 || this.records[end+1].w2ui == null || + stops.indexOf(this.records[end+1].w2ui.parent_recid) >= 0) { + break + } + end++ + } + this.records.splice(start, end - start + 1) + if (this.total !== -1) { + this.total -= end - start + 1 + } + let url = (typeof this.url != 'object' ? this.url : this.url.get) + if (!url) { + if (this.searchData.length > 0) { + this.localSearch(true) + } + } + if (noRefresh !== true) this.refresh() + edata.finish() + } else { + if (query(this.box).find('#grid_'+ this.name +'_rec_'+ id +'_expanded_row').length === 0 || this.show.expandColumn !== true) return false + // event before + edata = this.trigger('collapse', { target: this.name, recid: recid, + box_id: 'grid_'+ this.name +'_rec_'+ recid +'_expanded', fbox_id: 'grid_'+ this.name +'_frec_'+ recid +'_expanded' }) + if (edata.isCancelled === true) return false + // default action + query(this.box).find('#grid_'+ this.name +'_rec_'+ id).removeAttr('expanded').removeClass('w2ui-expanded') + query(this.box).find('#grid_'+ this.name +'_frec_'+ id).removeAttr('expanded').removeClass('w2ui-expanded') + query(this.box).find('#grid_'+ this.name +'_cell_'+ this.get(recid, true) +'_expand div').html('+') + query(this.box).find('#grid_'+ this.name +'_rec_'+ id +'_expanded').css('height', '0px') + query(this.box).find('#grid_'+ this.name +'_frec_'+ id +'_expanded').css('height', '0px') + setTimeout(() => { + query(this.box).find('#grid_'+ this.name +'_rec_'+ id +'_expanded_row').remove() + query(this.box).find('#grid_'+ this.name +'_frec_'+ id +'_expanded_row').remove() + rec.w2ui.expanded = false + // event after + edata.finish() + this.resizeRecords() + }, 300) + } + return true + function clearExpanded(rec) { + rec.w2ui.expanded = false + for (let i = 0; i < rec.w2ui.children.length; i++) { + let subRec = rec.w2ui.children[i] + if (subRec.w2ui.expanded) { + clearExpanded(subRec) + } + } + } + } + sort(field, direction, multiField) { // if no params - clears sort + // event before + let edata = this.trigger('sort', { target: this.name, field: field, direction: direction, multiField: multiField }) + if (edata.isCancelled === true) return + // check if needed to quit + if (field != null) { + // default action + let sortIndex = this.sortData.length + for (let s = 0; s < this.sortData.length; s++) { + if (this.sortData[s].field == field) { sortIndex = s; break } + } + if (direction == null) { + if (this.sortData[sortIndex] == null) { + direction = 'asc' + } else { + if (this.sortData[sortIndex].direction == null) { + this.sortData[sortIndex].direction = '' + } + switch (this.sortData[sortIndex].direction.toLowerCase()) { + case 'asc' : direction = 'desc'; break + case 'desc' : direction = 'asc'; break + default : direction = 'asc'; break + } + } + } + if (this.multiSort === false) { this.sortData = []; sortIndex = 0 } + if (multiField != true) { this.sortData = []; sortIndex = 0 } + // set new sort + if (this.sortData[sortIndex] == null) this.sortData[sortIndex] = {} + this.sortData[sortIndex].field = field + this.sortData[sortIndex].direction = direction + } else { + this.sortData = [] + } + // if local + let url = (typeof this.url != 'object' ? this.url : this.url.get) + if (!url) { + this.localSort(false, true) + if (this.searchData.length > 0) this.localSearch(true) + // reset vertical scroll + this.last.scrollTop = 0 + query(this.box).find(`#grid_${this.name}_records`).prop('scrollTop', 0) + // event after + edata.finish({ direction }) + this.refresh() + } else { + // event after + edata.finish({ direction }) + this.last.fetch.offset = 0 + this.reload() + } + } + copy(flag, oEvent) { + if (w2utils.isPlainObject(flag)) { + // event after + flag.finish() + return flag.text + } + // generate text to copy + let sel = this.getSelection() + if (sel.length === 0) return '' + let text = '' + if (typeof sel[0] == 'object') { // cell copy + // find min/max column + let minCol = sel[0].column + let maxCol = sel[0].column + let recs = [] + for (let s = 0; s < sel.length; s++) { + if (sel[s].column < minCol) minCol = sel[s].column + if (sel[s].column > maxCol) maxCol = sel[s].column + if (recs.indexOf(sel[s].index) == -1) recs.push(sel[s].index) + } + recs.sort((a, b) => { return a-b }) // sort function must be for numerical sort + for (let r = 0 ; r < recs.length; r++) { + let ind = recs[r] + for (let c = minCol; c <= maxCol; c++) { + let col = this.columns[c] + if (col.hidden === true) continue + text += this.getCellCopy(ind, c) + '\t' + } + text = text.substr(0, text.length-1) // remove last \t + text += '\n' + } + } else { // row copy + // copy headers + for (let c = 0; c < this.columns.length; c++) { + let col = this.columns[c] + if (col.hidden === true) continue + let colName = (col.text ? col.text : col.field) + if (col.text && col.text.length < 3 && col.tooltip) colName = col.tooltip // if column name is less then 3 char and there is tooltip - use it + text += '"' + w2utils.stripTags(colName) + '"\t' + } + text = text.substr(0, text.length-1) // remove last \t + text += '\n' + // copy selected text + for (let s = 0; s < sel.length; s++) { + let ind = this.get(sel[s], true) + for (let c = 0; c < this.columns.length; c++) { + let col = this.columns[c] + if (col.hidden === true) continue + text += '"' + this.getCellCopy(ind, c) + '"\t' + } + text = text.substr(0, text.length-1) // remove last \t + text += '\n' + } + } + text = text.substr(0, text.length - 1) + // if called without params + let edata + if (flag == null) { + // before event + edata = this.trigger('copy', { target: this.name, text: text, + cut: (oEvent.keyCode == 88 ? true : false), originalEvent: oEvent }) + if (edata.isCancelled === true) return '' + text = edata.detail.text + // event after + edata.finish() + return text + } else if (flag === false) { // only before event + // before event + edata = this.trigger('copy', { target: this.name, text: text, + cut: (oEvent.keyCode == 88 ? true : false), originalEvent: oEvent }) + if (edata.isCancelled === true) return '' + text = edata.detail.text + return edata + } + } + /** + * Gets value to be copied to the clipboard + * @param ind index of the record + * @param col_ind index of the column + * @returns the displayed value of the field's record associated with the cell + */ + getCellCopy(ind, col_ind) { + return w2utils.stripTags(this.getCellHTML(ind, col_ind)) + } + paste(text, event) { + let sel = this.getSelection() + let ind = this.get(sel[0].recid, true) + let col = sel[0].column + // before event + let edata = this.trigger('paste', { target: this.name, text: text, index: ind, column: col, originalEvent: event }) + if (edata.isCancelled === true) return + text = edata.detail.text + // default action + if (this.selectType == 'row' || sel.length === 0) { + console.log('ERROR: You can paste only if grid.selectType = \'cell\' and when at least one cell selected.') + // event after + edata.finish() + return + } + if (typeof text !== 'object') { + let newSel = [] + text = text.split('\n') + for (let t = 0; t < text.length; t++) { + let tmp = text[t].split('\t') + let cnt = 0 + let rec = this.records[ind] + let cols = [] + if (rec == null) continue + for (let dt = 0; dt < tmp.length; dt++) { + if (!this.columns[col + cnt]) continue + setCellPaste(rec, this.columns[col + cnt].field, tmp[dt]) + cols.push(col + cnt) + cnt++ + } + for (let c = 0; c < cols.length; c++) newSel.push({ recid: rec.recid, column: cols[c] }) + ind++ + } + this.selectNone(true) // no need to trigger select event + this.select(newSel) + } else { + this.selectNone(true) // no need to trigger select event + this.select([{ recid: this.records[ind], column: col }]) + } + this.refresh() + // event after + edata.finish() + function setCellPaste(rec, field, paste) { + rec.w2ui = rec.w2ui ?? {} + rec.w2ui.changes = rec.w2ui.changes || {} + rec.w2ui.changes[field] = paste + } + } + // ================================================== + // --- Common functions + resize() { + let time = Date.now() + // make sure the box is right + if (!this.box || query(this.box).attr('name') != this.name) return + // event before + let edata = this.trigger('resize', { target: this.name }) + if (edata.isCancelled === true) return + // resize + this.resizeBoxes() + this.resizeRecords() + // event after + edata.finish() + return Date.now() - time + } + update({ cells, fullCellRefresh, ignoreColumns } = {}) { + let time = Date.now() + let self = this + if (this.box == null) return 0 + if (Array.isArray(cells)) { + for (let i = 0; i < cells.length; i++) { + let index = cells[i].index + let column = cells[i].column + if (index < 0) continue + if (index == null || column == null) { + console.log('ERROR: Wrong argument for grid.update({ cells }), cells should be [{ index: X, column: Y }, ...]') + continue + } + let rec = this.records[index] ?? {} + rec.w2ui = rec.w2ui ?? {} + rec.w2ui._update = rec.w2ui._update ?? { cells: [] } + let row1 = rec.w2ui._update.row1 + let row2 = rec.w2ui._update.row2 + if (row1 == null || !row1.isConnected || row2 == null || !row2.isColSelected) { + row1 = this.box.querySelector(`#grid_${this.name}_rec_${w2utils.escapeId(rec.recid)}`) + row2 = this.box.querySelector(`#grid_${this.name}_frec_${w2utils.escapeId(rec.recid)}`) + rec.w2ui._update.row1 = row1 + rec.w2ui._update.row2 = row2 + } + _update(rec, row1, row2, index, column) + } + } else { + for (let i = this.last.range_start-1; i <= this.last.range_end; i++) { + let index = i + if (this.last.searchIds.length > 0) { // if search is applied + index = this.last.searchIds[i] + } else { + index = i + } + let rec = this.records[index] + if (index < 0 || rec == null) continue + rec.w2ui = rec.w2ui ?? {} + rec.w2ui._update = rec.w2ui._update ?? { cells: [] } + let row1 = rec.w2ui._update.row1 + let row2 = rec.w2ui._update.row2 + if (row1 == null || !row1.isConnected || row2 == null || !row2.isColSelected) { + row1 = this.box.querySelector(`#grid_${this.name}_rec_${w2utils.escapeId(rec.recid)}`) + row2 = this.box.querySelector(`#grid_${this.name}_frec_${w2utils.escapeId(rec.recid)}`) + rec.w2ui._update.row1 = row1 + rec.w2ui._update.row2 = row2 + } + for (let column = 0; column < this.columns.length; column++) { + _update(rec, row1, row2, index, column) + } + } + } + return Date.now() - time + function _update(rec, row1, row2, index, column) { + let pcol = self.columns[column] + if (Array.isArray(ignoreColumns) && (ignoreColumns.includes(column) || ignoreColumns.includes(pcol.field))) { + return + } + let cell = rec.w2ui._update.cells[column] + if (cell == null || !cell.isConnected) { + cell = self.box.querySelector(`#grid_${self.name}_data_${index}_${column}`) + rec.w2ui._update.cells[column] = cell + } + if (cell == null) return + if (fullCellRefresh) { + query(cell).replace(self.getCellHTML(index, column, false)) + // need to reselect as it was replaced + cell = self.box.querySelector(`#grid_${self.name}_data_${index}_${column}`) + rec.w2ui._update.cells[column] = cell + } else { + let div = cell.children[0] // there is always a div inside a cell + // value, attr, style, className, divAttr -- all on TD level except divAttr + let { value, style, className } = self.getCellValue(index, column, false, true) + if (div.innerHTML != value) { + div.innerHTML = value + } + if (style != '' && cell.style.cssText != style) { + cell.style.cssText = style + } + if (className != '') { + let ignore = ['w2ui-grid-data'] + let remove = [] + let add = className.split(' ').filter(cl => !!cl) // remove empty + cell.classList.forEach(cl => { if (!ignore.includes(cl)) remove.push(cl)}) + cell.classList.remove(...remove) + cell.classList.add(...add) + } + } + // column styles if any (lower priority) + if (self.columns[column].style && self.columns[column].style != cell.style.cssText) { + cell.style.cssText = self.columns[column].style ?? '' + } + // record class if any + if (rec.w2ui.class != null) { + if (typeof rec.w2ui.class == 'string') { + let ignore = ['w2ui-odd', 'w2ui-even', 'w2ui-record'] + let remove = [] + let add = rec.w2ui.class.split(' ').filter(cl => !!cl) // remove empty + if (row1 && row2) { + row1.classList.forEach(cl => { if (!ignore.includes(cl)) remove.push(cl)}) + row1.classList.remove(...remove) + row1.classList.add(...add) + row2.classList.remove(...remove) + row2.classList.add(...add) + } + } + if (w2utils.isPlainObject(rec.w2ui.class) && typeof rec.w2ui.class[pcol.field] == 'string') { + let ignore = ['w2ui-grid-data'] + let remove = [] + let add = rec.w2ui.class[pcol.field].split(' ').filter(cl => !!cl) + cell.classList.forEach(cl => { if (!ignore.includes(cl)) remove.push(cl)}) + cell.classList.remove(...remove) + cell.classList.add(...add) + } + } + // record styles if any + if (rec.w2ui.style != null) { + if (row1 && row2 && typeof rec.w2ui.style == 'string' && row1.style.cssText !== rec.w2ui.style) { + row1.style.cssText = 'height: '+ self.recordHeight + 'px;' + rec.w2ui.style + row1.setAttribute('custom_style', rec.w2ui.style) + row2.style.cssText = 'height: '+ self.recordHeight + 'px;' + rec.w2ui.style + row2.setAttribute('custom_style', rec.w2ui.style) + } + if (w2utils.isPlainObject(rec.w2ui.style) && typeof rec.w2ui.style[pcol.field] == 'string' + && cell.style.cssText !== rec.w2ui.style[pcol.field]) { + cell.style.cssText = rec.w2ui.style[pcol.field] + } + } + } + } + refreshCell(recid, field) { + let index = this.get(recid, true) + let col_ind = this.getColumn(field, true) + let isSummary = (this.records[index] && this.records[index].recid == recid ? false : true) + let cell = query(this.box).find(`${isSummary ? '.w2ui-grid-summary ' : ''}#grid_${this.name}_data_${index}_${col_ind}`) + if (cell.length == 0) return false + // set cell html and changed flag + cell.replace(this.getCellHTML(index, col_ind, isSummary)) + return true + } + refreshRow(recid, ind = null) { + let tr1 = query(this.box).find('#grid_'+ this.name +'_frec_'+ w2utils.escapeId(recid)) + let tr2 = query(this.box).find('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)) + if (tr1.length > 0) { + if (ind == null) ind = this.get(recid, true) + let line = tr1.attr('line') + let isSummary = (this.records[ind] && this.records[ind].recid == recid ? false : true) + // if it is searched, find index in search array + let url = (typeof this.url != 'object' ? this.url : this.url.get) + if (this.searchData.length > 0 && !url) for (let s = 0; s < this.last.searchIds.length; s++) if (this.last.searchIds[s] == ind) ind = s + let rec_html = this.getRecordHTML(ind, line, isSummary) + tr1.replace(rec_html[0]) + tr2.replace(rec_html[1]) + // apply style to row if it was changed in render functions + let st = (this.records[ind].w2ui ? this.records[ind].w2ui.style : '') + if (typeof st == 'string') { + tr1 = query(this.box).find('#grid_'+ this.name +'_frec_'+ w2utils.escapeId(recid)) + tr2 = query(this.box).find('#grid_'+ this.name +'_rec_'+ w2utils.escapeId(recid)) + tr1.attr('custom_style', st) + tr2.attr('custom_style', st) + if (tr1.hasClass('w2ui-selected')) { + st = st.replace('background-color', 'none') + } + tr1[0].style.cssText = 'height: '+ this.recordHeight + 'px;' + st + tr2[0].style.cssText = 'height: '+ this.recordHeight + 'px;' + st + } + if (isSummary) { + this.resize() + } + return true + } + return false + } + refresh() { + let time = Date.now() + let url = (typeof this.url != 'object' ? this.url : this.url.get) + if (this.total <= 0 && !url && this.searchData.length === 0) { + this.total = this.records.length + } + if (!this.box) return + // event before + let edata = this.trigger('refresh', { target: this.name }) + if (edata.isCancelled === true) return + // -- header + if (this.show.header) { + query(this.box).find(`#grid_${this.name}_header`).html(w2utils.lang(this.header) +' ').show() + } else { + query(this.box).find(`#grid_${this.name}_header`).hide() + } + // -- toolbar + if (this.show.toolbar) { + query(this.box).find('#grid_'+ this.name +'_toolbar').show() + } else { + query(this.box).find('#grid_'+ this.name +'_toolbar').hide() + } + // -- make sure search is closed + this.searchClose() + // search placeholder + let sInput = query(this.box).find('#grid_'+ this.name +'_search_all') + if (!this.multiSearch && this.last.field == 'all' && this.searches.length > 0) { + this.last.field = this.searches[0].field + this.last.label = this.searches[0].label + } + for (let s = 0; s < this.searches.length; s++) { + if (this.searches[s].field == this.last.field) this.last.label = this.searches[s].label + } + if (this.last.multi) { + sInput.attr('placeholder', '[' + w2utils.lang('Multiple Fields') + ']') + } else { + sInput.attr('placeholder', w2utils.lang('Search') + ' ' + w2utils.lang(this.last.label, true)) + } + if (sInput.val() != this.last.search) { + let val = this.last.search + let tmp = sInput._w2field + if (tmp) val = tmp.format(val) + sInput.val(val) + } + this.refreshSearch() + this.refreshBody() + // -- footer + if (this.show.footer) { + query(this.box).find(`#grid_${this.name}_footer`).html(this.getFooterHTML()).show() + } else { + query(this.box).find(`#grid_${this.name}_footer`).hide() + } + // all selected? + let sel = this.last.selection, + areAllSelected = (this.records.length > 0 && sel.indexes.length == this.records.length), + areAllSearchedSelected = (sel.indexes.length > 0 && this.searchData.length !== 0 && sel.indexes.length == this.last.searchIds.length) + if (areAllSelected || areAllSearchedSelected) { + query(this.box).find('#grid_'+ this.name +'_check_all').prop('checked', true) + } else { + query(this.box).find('#grid_'+ this.name +'_check_all').prop('checked', false) + } + // show number of selected + this.status() + // collapse all records + let rows = this.find({ 'w2ui.expanded': true }, true, true) + for (let r = 0; r < rows.length; r++) { + let tmp = this.records[rows[r]].w2ui + if (tmp && !Array.isArray(tmp.children)) { + tmp.expanded = false + } + } + // mark selection + if (this.markSearch) { + setTimeout(() => { + // mark all search strings + let search = [] + for (let s = 0; s < this.searchData.length; s++) { + let sdata = this.searchData[s] + let fld = this.getSearch(sdata.field) + if (!fld || fld.hidden) continue + let ind = this.getColumn(sdata.field, true) + search.push({ field: sdata.field, search: sdata.value, col: ind }) + } + if (search.length > 0) { + search.forEach((item) => { + let el = query(this.box).find('td[col="'+ item.col +'"]:not(.w2ui-head)') + w2utils.marker(el, item.search) + }) + } + }, 50) + } + this.updateToolbar(this.last.selection) + // event after + edata.finish() + this.resize() + this.addRange('selection') + setTimeout(() => { // allow to render first + this.resize() // needed for horizontal scroll to show (do not remove) + this.scroll() + }, 1) + if (this.reorderColumns && !this.last.columnDrag) { + this.last.columnDrag = this.initColumnDrag() + } else if (!this.reorderColumns && this.last.columnDrag) { + this.last.columnDrag.remove() + } + return Date.now() - time + } + refreshSearch() { + if (this.multiSearch && this.searchData.length > 0) { + if (query(this.box).find('.w2ui-grid-searches').length == 0) { + query(this.box).find('.w2ui-grid-toolbar') + .css('height', (this.last.toolbar_height + 35) + 'px') + .append(`
    `) + } + let searches = ` + +
    ` + this.searchData.forEach((sd, sd_ind) => { + let ind = this.getSearch(sd.field, true) + let sf = this.searches[ind] + let display + if (Array.isArray(sd.value)) { + display = `${sd.value.length}` + } else if (sf && sf.type == 'list') { + display = !!sd.text && sd.text !== sd.value ? `: ${sd.text}` : `: ${sd.value}` + } else { + display = `: ${sd.value}` + } + if (sf && sf.type == 'date') { + if (sd.operator == 'between') { + let dsp1 = sd.value[0] + let dsp2 = sd.value[1] + if (Number(dsp1) === dsp1) { + dsp1 = w2utils.formatDate(dsp1) + } + if (Number(dsp2) === dsp2) { + dsp2 = w2utils.formatDate(dsp2) + } + display = `: ${dsp1} - ${dsp2}` + } else { + let dsp = sd.value + if (Number(dsp) == dsp) { + dsp = w2utils.formatDate(dsp) + } + let oper = sd.operator + if (oper == 'more') oper = 'since' + if (oper == 'less') oper = 'before' + if (oper.substr(0, 5) == 'more:') { + oper = 'since' + } + display = `: ${oper} ${dsp}` + } + } + searches += ` + ${sf ? sf.label : ''} + ${display} + + ` + }) + // clear and save + searches += ` + ${this.show.searchSave + ? `
    + + ` + : '' +} + + ` + query(this.box).find(`#grid_${this.name}_searches`).html(searches) + query(this.box).find(`#grid_${this.name}_search_logic`).html(w2utils.lang(this.last.logic == 'AND' ? 'All' : 'Any')) + } else { + query(this.box).find('.w2ui-grid-toolbar') + .css('height', this.last.toolbar_height + 'px') + .find('.w2ui-grid-searches') + .remove() + } + if (this.searchSelected) { + query(this.box).find(`#grid_${this.name}_search_all`).val(' ').prop('readOnly', true) + query(this.box).find(`#grid_${this.name}_search_name`).show().find('.name-text').html(this.searchSelected.text) + } else { + query(this.box).find(`#grid_${this.name}_search_all`).prop('readOnly', false) + query(this.box).find(`#grid_${this.name}_search_name`).hide().find('.name-text').html('') + } + w2utils.bindEvents(query(this.box).find(`#grid_${this.name}_searches .w2ui-action, #grid_${this.name}_searches button`), this) + } + refreshBody() { + this.scroll() // need to calculate virtual scrolling for columns + let recHTML = this.getRecordsHTML() + let colHTML = this.getColumnsHTML() + let bodyHTML = + '
    '+ + recHTML[0] + + '
    '+ + '
    ' + + recHTML[1] + + '
    '+ + '
    '+ + // Columns need to be after to be able to overlap + '
    '+ + ' '+ colHTML[0] +'
    '+ + '
    '+ + '
    '+ + ' '+ colHTML[1] +'
    '+ + '
    '+ + `` + let gridBody = query(this.box).find(`#grid_${this.name}_body`, this.box).html(bodyHTML) + let records = query(this.box).find(`#grid_${this.name}_records`, this.box) + let frecords = query(this.box).find(`#grid_${this.name}_frecords`, this.box) + if (this.selectType == 'row') { + records.on('mouseover mouseout', { delegate: 'tr' }, (event) => { + let recid = query(event.delegate).attr('recid') + query(this.box).find(`#grid_${this.name}_frec_${w2utils.escapeId(recid)}`) + .toggleClass('w2ui-record-hover', event.type == 'mouseover') + }) + frecords.on('mouseover mouseout', { delegate: 'tr' }, (event) => { + let recid = query(event.delegate).attr('recid') + query(this.box).find(`#grid_${this.name}_rec_${w2utils.escapeId(recid)}`) + .toggleClass('w2ui-record-hover', event.type == 'mouseover') + }) + } + if (w2utils.isIOS) { + records.append(frecords) + .on('click', { delegate: 'tr' }, (event) => { + let recid = query(event.delegate).attr('recid') + this.dblClick(recid, event) + }) + } else { + records.add(frecords) + .on('click', { delegate: 'tr' }, (event) => { + let recid = query(event.delegate).attr('recid') + // do not generate click if empty record is clicked + if (recid != '-none-') { + this.click(recid, event) + } + }) + .on('contextmenu', { delegate: 'tr' }, (event) => { + let recid = query(event.delegate).attr('recid') + let td = query(event.target).closest('td') + let column = parseInt(td.attr('col') ?? -1) + this.showContextMenu(recid, column, event) + }) + .on('mouseover', { delegate: 'tr' }, (event) => { + this.last.rec_out = false + let index = query(event.delegate).attr('index') + let recid = query(event.delegate).attr('recid') + if (index !== this.last.rec_over) { + this.last.rec_over = index + // setTimeout is needed for correct event order enter/leave + setTimeout(() => { + delete this.last.rec_out + let edata = this.trigger('mouseEnter', { target: this.name, originalEvent: event, index, recid }) + edata.finish() + }) + } + }) + .on('mouseout', { delegate: 'tr' }, (event) => { + let index = query(event.delegate).attr('index') + let recid = query(event.delegate).attr('recid') + this.last.rec_out = true + // setTimeouts are needed for correct event order enter/leave + setTimeout(() => { + let recLeave = () => { + let edata = this.trigger('mouseLeave', { target: this.name, originalEvent: event, index, recid }) + edata.finish() + } + if (index !== this.last.rec_over) { + recLeave() + } + setTimeout(() => { + if (this.last.rec_out) { + delete this.last.rec_out + delete this.last.rec_over + recLeave() + } + }) + }) + }) + } + // enable scrolling on frozen records, + gridBody + .data('scroll', { lastDelta: 0, lastTime: 0 }) + .find('.w2ui-grid-frecords') + .on('mousewheel DOMMouseScroll ', (event) => { + event.preventDefault() + // TODO: improve, scroll is not smooth, if scrolled to the end, it takes a while to return + let scroll = gridBody.data('scroll') + let container = gridBody.find('.w2ui-grid-records') + let amount = typeof event.wheelDelta != null ? -event.wheelDelta : (event.detail || event.deltaY) + let newScrollTop = container.prop('scrollTop') + scroll.lastDelta += amount + amount = Math.round(scroll.lastDelta) + gridBody.data('scroll', scroll) + // make scroll amount dependent on visible rows + // amount *= (Math.round(records.prop('clientHeight') / self.recordHeight) - 1) * self.recordHeight / 4 + container.get(0).scroll({ top: newScrollTop + amount, behavior: 'smooth' }) + }) + // scroll on records (and frozen records) + records.off('.body-global') + .on('scroll.body-global', { delegate: '.w2ui-grid-records' }, event => { + this.scroll(event) + }) + query(this.box).find('.w2ui-grid-body') // gridBody + .off('.body-global') + // header column click + .on('click.body-global dblclick.body-global contextmenu.body-global', { delegate: 'td.w2ui-head' }, event => { + let col_ind = query(event.delegate).attr('col') + let col = this.columns[col_ind] ?? { field: col_ind } // it could be line number + switch (event.type) { + case 'click': + this.columnClick(col.field, event) + break + case 'dblclick': + this.columnDblClick(col.field, event) + break + case 'contextmenu': + this.columnContextMenu(col.field, event) + break + } + }) + .on('mouseover.body-global', { delegate: '.w2ui-col-header' }, event => { + let col = query(event.delegate).parent().attr('col') + this.columnTooltipShow(col, event) + query(event.delegate) + .off('.tooltip') + .on('mouseleave.tooltip', () => { + this.columnTooltipHide(col, event) + }) + }) + // select all + .on('click.body-global', { delegate: 'input.w2ui-select-all' }, event => { + if (event.delegate.checked) { this.selectAll() } else { this.selectNone() } + event.stopPropagation() + clearTimeout(this.last.kbd_timer) // keep grid in focus + }) + // tree-like grid (or expandable column) expand/collapse + .on('click.body-global', { delegate: '.w2ui-show-children, .w2ui-col-expand' }, event => { + event.stopPropagation() + this.toggle(query(event.target).parents('tr').attr('recid')) + }) + // info bubbles + .on('click.body-global mouseover.body-global', { delegate: '.w2ui-info' }, event => { + let td = query(event.delegate).closest('td') + let tr = td.parent() + let col = this.columns[td.attr('col')] + let isSummary = tr.parents('.w2ui-grid-body').hasClass('w2ui-grid-summary') + if (['mouseenter', 'mouseover'].includes(col.info?.showOn?.toLowerCase()) && event.type == 'mouseover') { + this.showBubble(tr.attr('index'), td.attr('col'), isSummary) + .then(() => { + query(event.delegate) + .off('.tooltip') + .on('mouseleave.tooltip', () => { w2tooltip.hide(this.name + '-bubble') }) + }) + } else if (event.type == 'click') { + w2tooltip.hide(this.name + '-bubble') + this.showBubble(tr.attr('index'), td.attr('col'), isSummary) + } + }) + // clipborad copy icon + .on('mouseover.body-global', { delegate: '.w2ui-clipboard-copy' }, event => { + if (event.delegate._tooltipShow) return + let td = query(event.delegate).parent() + let tr = td.parent() + let col = this.columns[td.attr('col')] + let isSummary = tr.parents('.w2ui-grid-body').hasClass('w2ui-grid-summary') + w2tooltip.show({ + name: this.name + '-bubble', + anchor: event.delegate, + html: w2utils.lang(typeof col.clipboardCopy == 'string' ? col.clipboardCopy : 'Copy to clipboard'), + position: 'top|bottom', + offsetY: -2 + }) + .hide(evt => { + event.delegate._tooltipShow = false + query(event.delegate).off('.tooltip') + }) + query(event.delegate) + .off('.tooltip') + .on('mouseleave.tooltip', evt => { + w2tooltip.hide(this.name + '-bubble') + }) + .on('click.tooltip', evt => { + evt.stopPropagation() + w2tooltip.update(this.name + '-bubble', w2utils.lang('Copied')) + this.clipboardCopy(tr.attr('index'), td.attr('col'), isSummary) + }) + event.delegate._tooltipShow = true + }) + .on('click.body-global', { delegate: '.w2ui-editable-checkbox' }, event => { + let dt = query(event.delegate).data() + this.editChange.call(this, event.delegate, dt.changeind, dt.colind, event) + this.updateToolbar() + }) + // show empty message + if (this.records.length === 0 && this.msgEmpty) { + query(this.box).find(`#grid_${this.name}_body`) + .append(`
    ${w2utils.lang(this.msgEmpty)}
    `) + } else if (query(this.box).find(`#grid_${this.name}_empty_msg`).length > 0) { + query(this.box).find(`#grid_${this.name}_empty_msg`).remove() + } + // show summary records + if (this.summary.length > 0) { + let sumHTML = this.getSummaryHTML() + query(this.box).find(`#grid_${this.name}_fsummary`).html(sumHTML[0]).show() + query(this.box).find(`#grid_${this.name}_summary`).html(sumHTML[1]).show() + } else { + query(this.box).find(`#grid_${this.name}_fsummary`).hide() + query(this.box).find(`#grid_${this.name}_summary`).hide() + } + } + render(box) { + let time = Date.now() + let obj = this + if (typeof box == 'string') box = query(box).get(0) + // event before + let edata = this.trigger('render', { target: this.name, box: box ?? this.box }) + if (edata.isCancelled === true) return + // default action + if (box != null) { + // clean previous box + if (query(this.box).find(`#grid_${this.name}_body`).length > 0) { + query(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-grid w2ui-inactive') + .html('') + } + this.box = box + } + if (!this.box) return + let url = (typeof this.url != 'object' ? this.url : this.url.get) + // reset needed if grid existed + this.reset(true) + // --- default search field + if (!this.last.field) { + if (!this.multiSearch || !this.show.searchAll) { + let tmp = 0 + while (tmp < this.searches.length && (this.searches[tmp].hidden || this.searches[tmp].simple === false)) tmp++ + if (tmp >= this.searches.length) { + // all searches are hidden + this.last.field = '' + this.last.label = '' + } else { + this.last.field = this.searches[tmp].field + this.last.label = this.searches[tmp].label + } + } else { + this.last.field = 'all' + this.last.label = 'All Fields' + } + } + // insert elements + query(this.box) + .attr('name', this.name) + .addClass('w2ui-reset w2ui-grid w2ui-inactive') + .html('
    '+ + '
    '+ + '
    '+ + '
    '+ + '
    '+ + '
    '+ + ' '+ + ' '+ // readonly needed on android not to open keyboard + '
    ') + if (this.selectType != 'row') query(this.box).addClass('w2ui-ss') + if (query(this.box).length > 0) query(this.box)[0].style.cssText += this.style + // init toolbar + this.initToolbar() + if (this.toolbar != null) this.toolbar.render(query(this.box).find('#grid_'+ this.name +'_toolbar')[0]) + this.last.toolbar_height = query(this.box).find(`#grid_${this.name}_toolbar`).prop('offsetHeight') + // re-init search_all + if (this.last.field && this.last.field != 'all') { + let sd = this.searchData + setTimeout(() => { this.searchInitInput(this.last.field, (sd.length == 1 ? sd[0].value : null)) }, 1) + } + // init footer + query(this.box).find(`#grid_${this.name}_footer`).html(this.getFooterHTML()) + // refresh + if (!this.last.state) this.last.state = this.stateSave(true) // initial default state + this.stateRestore() + if (url) { this.clear(); this.refresh() } // show empty grid (need it) - should it be only for remote data source + // if hidden searches - apply it + let hasHiddenSearches = false + for (let i = 0; i < this.searches.length; i++) { + if (this.searches[i].hidden) { hasHiddenSearches = true; break } + } + if (hasHiddenSearches) { + this.searchReset(false) // will call reload + if (!url) setTimeout(() => { this.searchReset() }, 1) + } else { + this.reload() + } + // focus + query(this.box).find(`#grid_${this.name}_focus`) + .on('focus', (event) => { + clearTimeout(this.last.kbd_timer) + if (!this.hasFocus) this.focus() + }) + .on('blur', (event) => { + clearTimeout(this.last.kbd_timer) + this.last.kbd_timer = setTimeout(() => { + if (this.hasFocus) { this.blur() } + }, 100) // need this timer to be 100 ms + }) + .on('paste', (event) => { + let cd = (event.clipboardData ? event.clipboardData : null) + if (cd) { + let items = cd.items + if (items.length == 2) { + if (items.length == 2 && items[1].kind == 'file') { + items = [items[1]] + } + if (items.length == 2 && items[0].type == 'text/plain' && items[1].type == 'text/html') { + items = [items[1]] + } + } + let items2send = [] + // might contain data in different formats, but it is a single paste + for (let index in items) { + let item = items[index] + if (item.kind === 'file') { + let file = item.getAsFile() + items2send.push({ kind: 'file', data: file }) + } else if (item.kind === 'string' && (item.type === 'text/plain' || item.type === 'text/html')) { + event.preventDefault() + let text = cd.getData('text/plain') + if (text.indexOf('\r') != -1 && text.indexOf('\n') == -1) { + text = text.replace(/\r/g, '\n') + } + items2send.push({ kind: (item.type == 'text/html' ? 'html' : 'text'), data: text }) + } + } + if (items2send.length === 1 && items2send[0].kind != 'file') { + items2send = items2send[0].data + } + w2ui[this.name].paste(items2send, event) + event.preventDefault() + } + }) + .on('keydown', function (event) { + w2ui[obj.name].keydown.call(w2ui[obj.name], event) + }) + // init mouse events for mouse selection + let edataCol // event for column select + query(this.box).off('mousedown.mouseStart').on('mousedown.mouseStart', mouseStart) + this.updateToolbar() + // event after + edata.finish() + // observe div resize + this.last.observeResize = new ResizeObserver(() => { this.resize() }) + this.last.observeResize.observe(this.box) + return Date.now() - time + function mouseStart (event) { + if (event.which != 1) return // if not left mouse button + // restore css user-select + if (obj.last.userSelect == 'text') { + obj.last.userSelect = '' + query(obj.box).find('.w2ui-grid-body').css('user-select', 'none') + } + // regular record select + if (obj.selectType == 'row' && (query(event.target).parents().hasClass('w2ui-head') || query(event.target).hasClass('w2ui-head'))) return + if (obj.last.move && obj.last.move.type == 'expand') return + // if altKey - alow text selection + if (event.altKey) { + query(obj.box).find('.w2ui-grid-body').css('user-select', 'text') + obj.selectNone() + obj.last.move = { type: 'text-select' } + obj.last.userSelect = 'text' + } else { + let tmp = event.target + let pos = { + x: event.offsetX - 10, + y: event.offsetY - 10 + } + let tmps = false + while (tmp) { + if (tmp.classList && tmp.classList.contains('w2ui-grid')) break + if (tmp.tagName && tmp.tagName.toUpperCase() == 'TD') tmps = true + if (tmp.tagName && tmp.tagName.toUpperCase() != 'TR' && tmps == true) { + pos.x += tmp.offsetLeft + pos.y += tmp.offsetTop + } + tmp = tmp.parentNode + } + obj.last.move = { + x : event.screenX, + y : event.screenY, + divX : 0, + divY : 0, + focusX : pos.x, + focusY : pos.y, + recid : query(event.target).parents('tr').attr('recid'), + column : parseInt(event.target.tagName.toUpperCase() == 'TD' ? query(event.target).attr('col') : query(event.target).parents('td').attr('col')), + type : 'select', + ghost : false, + start : true + } + if (obj.last.move.recid == null) obj.last.move.type = 'select-column' + // set focus to grid + let target = event.target + let $input = query(obj.box).find('#grid_'+ obj.name + '_focus') + // move input next to cursor so screen does not jump + if (obj.last.move) { + let sLeft = obj.last.move.focusX + let sTop = obj.last.move.focusY + let $owner = query(target).parents('table').parent() + if ($owner.hasClass('w2ui-grid-records') || $owner.hasClass('w2ui-grid-frecords') + || $owner.hasClass('w2ui-grid-columns') || $owner.hasClass('w2ui-grid-fcolumns') + || $owner.hasClass('w2ui-grid-summary')) { + sLeft = obj.last.move.focusX - query(obj.box).find('#grid_'+ obj.name +'_records').prop('scrollLeft') + sTop = obj.last.move.focusY - query(obj.box).find('#grid_'+ obj.name +'_records').prop('scrollTop') + } + if (query(target).hasClass('w2ui-grid-footer') || query(target).parents('div.w2ui-grid-footer').length > 0) { + sTop = query(obj.box).find('#grid_'+ obj.name +'_footer').get(0).offsetTop + } + // if clicked on toolbar + if ($owner.hasClass('w2ui-scroll-wrapper') && $owner.parent().hasClass('w2ui-toolbar')) { + sLeft = obj.last.move.focusX - $owner.prop('scrollLeft') + } + $input.css({ + left: sLeft - 10, + top : sTop + }) + } + // if toolbar input is clicked + setTimeout(() => { + if (!obj.last.inEditMode) { + if (['INPUT', 'TEXTAREA', 'SELECT'].includes(target.tagName)) { + target.focus() + } else { + if ($input.get(0) !== document.active) $input.get(0)?.focus({ preventScroll: true }) + } + } + }, 50) + // disable click select for this condition + if (!obj.multiSelect && !obj.reorderRows && obj.last.move.type == 'drag') { + delete obj.last.move + } + } + if (obj.reorderRows == true) { + let el = event.target + if (el.tagName.toUpperCase() != 'TD') el = query(el).parents('td')[0] + if (query(el).hasClass('w2ui-col-number') || query(el).hasClass('w2ui-col-order')) { + obj.selectNone() + obj.last.move.reorder = true + // suppress hover + let eColor = query(obj.box).find('.w2ui-even.w2ui-empty-record').css('background-color') + let oColor = query(obj.box).find('.w2ui-odd.w2ui-empty-record').css('background-color') + query(obj.box).find('.w2ui-even td').filter(':not(.w2ui-col-number)').css('background-color', eColor) + query(obj.box).find('.w2ui-odd td').filter(':not(.w2ui-col-number)').css('background-color', oColor) + // display empty record and ghost record + let mv = obj.last.move + let recs = query(obj.box).find('.w2ui-grid-records') + if (!mv.ghost) { + let row = query(obj.box).find(`#grid_${obj.name}_rec_${mv.recid}`) + let tmp = row.parents('table').find('tr:first-child').get(0).cloneNode(true) + mv.offsetY = event.offsetY + mv.from = mv.recid + mv.pos = { top: row.get(0).offsetTop-1, left: row.get(0).offsetLeft } + mv.ghost = query(row.get(0).cloneNode(true)) + mv.ghost.removeAttr('id') + mv.ghost.find('td').css({ + 'border-top': '1px solid silver', + 'border-bottom': '1px solid silver' + }) + row.find('td').remove() + row.append(`
    `) + recs.append('
    ') + recs.append('
    ') + query(obj.box).find('#grid_'+ obj.name + '_ghost').append(tmp).append(mv.ghost) + } + let ghost = query(obj.box).find('#grid_'+ obj.name + '_ghost') + ghost.css({ + top : mv.pos.top + 'px', + left : mv.pos.left + 'px' + }) + } else { + obj.last.move.reorder = false + } + } + query(document) + .on('mousemove.w2ui-' + obj.name, mouseMove) + .on('mouseup.w2ui-' + obj.name, mouseStop) + // needed when grid grids are nested, see issue #1275 + event.stopPropagation() + } + function mouseMove(event) { + if (!event.target.tagName) { + // element has no tagName - most likely the target is the #document itself + // this can happen is you click+drag and move the mouse out of the DOM area, + // e.g. into the browser's toolbar area + return + } + let mv = obj.last.move + if (!mv || ['select', 'select-column'].indexOf(mv.type) == -1) return + mv.divX = (event.screenX - mv.x) + mv.divY = (event.screenY - mv.y) + if (Math.abs(mv.divX) <= 1 && Math.abs(mv.divY) <= 1) return // only if moved more then 1px + obj.last.cancelClick = true + if (obj.reorderRows == true && obj.last.move.reorder) { + let tmp = query(event.target).parents('tr') + let recid = tmp.attr('recid') + if (recid == '-none-') recid = 'bottom' + if (recid != mv.from) { + // let row1 = query(obj.box).find('#grid_'+ obj.name + '_rec_'+ mv.recid) + let row2 = query(obj.box).find('#grid_'+ obj.name + '_rec_'+ recid) + query(obj.box).find('.insert-before') + row2.addClass('insert-before') + // MOVABLE GHOST + // if (event.screenY - mv.lastY < 0) row1.after(row2); else row2.after(row1); + mv.lastY = event.screenY + mv.to = recid + // line to insert before + let pos = { top: row2.get(0)?.offsetTop, left: row2.get(0)?.offsetLeft } + let ghost_line = query(obj.box).find('#grid_'+ obj.name + '_ghost_line') + if (pos) { + ghost_line.css({ + top : pos.top + 'px', + left : mv.pos.left + 'px', + 'border-top': '2px solid #769EFC' + }) + } else { + ghost_line.css({ + 'border-top': '2px solid transparent' + }) + } + } + let ghost = query(obj.box).find('#grid_'+ obj.name + '_ghost') + ghost.css({ + top : (mv.pos.top + mv.divY) + 'px', + left : mv.pos.left + 'px' + }) + return + } + if (mv.start && mv.recid) { + obj.selectNone() + mv.start = false + } + let newSel = [] + let recid = (event.target.tagName.toUpperCase() == 'TR' ? query(event.target).attr('recid') : query(event.target).parents('tr').attr('recid')) + if (recid == null) { + // select by dragging columns + if (obj.selectType == 'row') return + if (obj.last.move && obj.last.move.type == 'select') return + let col = parseInt(query(event.target).parents('td').attr('col')) + if (isNaN(col)) { + obj.removeRange('column-selection') + query(obj.box).find('.w2ui-grid-columns .w2ui-col-header, .w2ui-grid-fcolumns .w2ui-col-header').removeClass('w2ui-col-selected') + query(obj.box).find('.w2ui-col-number').removeClass('w2ui-row-selected') + delete mv.colRange + } else { + // add all columns in between + let newRange = col + '-' + col + if (mv.column < col) newRange = mv.column + '-' + col + if (mv.column > col) newRange = col + '-' + mv.column + // array of selected columns + let cols = [] + let tmp = newRange.split('-') + for (let ii = parseInt(tmp[0]); ii <= parseInt(tmp[1]); ii++) { + cols.push(ii) + } + if (mv.colRange != newRange) { + edataCol = obj.trigger('columnSelect', { target: obj.name, columns: cols }) + if (edataCol.isCancelled !== true) { + if (mv.colRange == null) obj.selectNone() + // highlight columns + let tmp = newRange.split('-') + query(obj.box).find('.w2ui-grid-columns .w2ui-col-header, .w2ui-grid-fcolumns .w2ui-col-header').removeClass('w2ui-col-selected') + for (let j = parseInt(tmp[0]); j <= parseInt(tmp[1]); j++) { + query(obj.box).find('#grid_'+ obj.name +'_column_' + j + ' .w2ui-col-header').addClass('w2ui-col-selected') + } + query(obj.box).find('.w2ui-col-number').not('.w2ui-head').addClass('w2ui-row-selected') + // show new range + mv.colRange = newRange + obj.removeRange('column-selection') + obj.addRange({ + name : 'column-selection', + range : [{ recid: obj.records[0].recid, column: tmp[0] }, { recid: obj.records[obj.records.length-1].recid, column: tmp[1] }], + style : 'background-color: rgba(90, 145, 234, 0.1)' + }) + } + } + } + } else { // regular selection + let ind1 = obj.get(mv.recid, true) + // this happens when selection is started on summary row + if (ind1 == null || (obj.records[ind1] && obj.records[ind1].recid != mv.recid)) return + let ind2 = obj.get(recid, true) + // this happens when selection is extended into summary row (a good place to implement scrolling) + if (ind2 == null) return + let col1 = parseInt(mv.column) + let col2 = parseInt(event.target.tagName.toUpperCase() == 'TD' ? query(event.target).attr('col') : query(event.target).parents('td').attr('col')) + if (isNaN(col1) && isNaN(col2)) { // line number select entire record + col1 = 0 + col2 = obj.columns.length-1 + } + if (ind1 > ind2) { let tmp = ind1; ind1 = ind2; ind2 = tmp } + // check if need to refresh + let tmp = 'ind1:'+ ind1 +',ind2;'+ ind2 +',col1:'+ col1 +',col2:'+ col2 + if (mv.range == tmp) return + mv.range = tmp + for (let i = ind1; i <= ind2; i++) { + if (obj.last.searchIds.length > 0 && obj.last.searchIds.indexOf(i) == -1) continue + if (obj.selectType != 'row') { + if (col1 > col2) { let tmp = col1; col1 = col2; col2 = tmp } + for (let c = col1; c <= col2; c++) { + if (obj.columns[c].hidden) continue + newSel.push({ recid: obj.records[i].recid, column: parseInt(c) }) + } + } else { + newSel.push(obj.records[i].recid) + } + } + if (obj.selectType != 'row') { + let sel = obj.getSelection() + // add more items + let tmp = [] + for (let ns = 0; ns < newSel.length; ns++) { + let flag = false + for (let s = 0; s < sel.length; s++) if (newSel[ns].recid == sel[s].recid && newSel[ns].column == sel[s].column) flag = true + if (!flag) tmp.push({ recid: newSel[ns].recid, column: newSel[ns].column }) + } + obj.select(tmp) + // remove items + tmp = [] + for (let s = 0; s < sel.length; s++) { + let flag = false + for (let ns = 0; ns < newSel.length; ns++) if (newSel[ns].recid == sel[s].recid && newSel[ns].column == sel[s].column) flag = true + if (!flag) tmp.push({ recid: sel[s].recid, column: sel[s].column }) + } + obj.unselect(tmp) + } else { + if (obj.multiSelect) { + let sel = obj.getSelection() + for (let ns = 0; ns < newSel.length; ns++) { + if (sel.indexOf(newSel[ns]) == -1) obj.select(newSel[ns]) // add more items + } + for (let s = 0; s < sel.length; s++) { + if (newSel.indexOf(sel[s]) == -1) obj.unselect(sel[s]) // remove items + } + } + } + } + } + function mouseStop (event) { + let mv = obj.last.move + setTimeout(() => { delete obj.last.cancelClick }, 1) + if (query(event.target).parents().hasClass('.w2ui-head') || query(event.target).hasClass('.w2ui-head')) return + if (mv && ['select', 'select-column'].indexOf(mv.type) != -1) { + if (mv.colRange != null && edataCol.isCancelled !== true) { + let tmp = mv.colRange.split('-') + let sel = [] + for (let i = 0; i < obj.records.length; i++) { + let cols = [] + for (let j = parseInt(tmp[0]); j <= parseInt(tmp[1]); j++) cols.push(j) + sel.push({ recid: obj.records[i].recid, column: cols }) + } + obj.removeRange('column-selection') + edataCol.finish() + obj.select(sel) + } + if (obj.reorderRows == true && obj.last.move.reorder) { + if (mv.to != null) { + // event + let edata = obj.trigger('reorderRow', { target: obj.name, recid: mv.from, moveBefore: mv.to }) + if (edata.isCancelled === true) { + resetRowReorder() + delete obj.last.move + return + } + // default behavior + let ind1 = obj.get(mv.from, true) + let ind2 = obj.get(mv.to, true) + if (mv.to == 'bottom') ind2 = obj.records.length // end of list + let tmp = obj.records[ind1] + // swap records + if (ind1 != null && ind2 != null) { + obj.records.splice(ind1, 1) + if (ind1 > ind2) { + obj.records.splice(ind2, 0, tmp) + } else { + obj.records.splice(ind2 - 1, 0, tmp) + } + } + // clear sortData + obj.sortData = [] + query(obj.box) + .find(`#grid_${obj.name}_columns .w2ui-col-header`) + .removeClass('w2ui-col-sorted') + resetRowReorder() + // event after + edata.finish() + } else { + resetRowReorder() + } + } + } + delete obj.last.move + query(document).off('.w2ui-' + obj.name) + } + function resetRowReorder() { + query(obj.box).find(`#grid_${obj.name}_ghost`).remove() + query(obj.box).find(`#grid_${obj.name}_ghost_line`).remove() + obj.refresh() + delete obj.last.move + } + } + destroy() { + // event before + let edata = this.trigger('destroy', { target: this.name }) + if (edata.isCancelled === true) return + // remove all events + query(this.box).off() + // clean up + if (typeof this.toolbar == 'object' && this.toolbar.destroy) this.toolbar.destroy() + if (query(this.box).find(`#grid_${this.name}_body`).length > 0) { + query(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-grid w2ui-inactive') + .html('') + } + this.last.observeResize?.disconnect() + delete w2ui[this.name] + // event after + edata.finish() + } + // =========================================== + // --- Internal Functions + initColumnOnOff() { + let items = [ + { id: 'line-numbers', text: 'Line #', checked: this.show.lineNumbers } + ] + // columns + for (let c = 0; c < this.columns.length; c++) { + let col = this.columns[c] + let text = this.columns[c].text + if (col.hideable === false) continue + if (!text && this.columns[c].tooltip) text = this.columns[c].tooltip + if (!text) text = '- column '+ (parseInt(c) + 1) +' -' + items.push({ id: col.field, text: w2utils.stripTags(text), checked: !col.hidden }) + } + let url = (typeof this.url != 'object' ? this.url : this.url.get) + if ((url && this.show.skipRecords) || this.show.saveRestoreState) { + items.push({ text: '--' }) + } + // skip records + if (this.show.skipRecords) { + let skip = w2utils.lang('Skip') + + `` + + w2utils.lang('records') + items.push({ id: 'w2ui-skip', text: skip, group: false, icon: 'w2ui-icon-empty' }) + } + // save/restore state + if (this.show.saveRestoreState) { + items.push( + { id: 'w2ui-stateSave', text: w2utils.lang('Save Grid State'), icon: 'w2ui-icon-empty', group: false }, + { id: 'w2ui-stateReset', text: w2utils.lang('Restore Default State'), icon: 'w2ui-icon-empty', group: false } + ) + } + let selected = [] + items.forEach(item => { + item.text = w2utils.lang(item.text) // translate + if (item.checked) selected.push(item.id) + }) + this.toolbar.set('w2ui-column-on-off', { selected, items }) + return items + } + initColumnDrag(box) { + // throw error if using column groups + if (this.columnGroups && this.columnGroups.length) { + throw 'Draggable columns are not currently supported with column groups.' + } + let self = this + let dragData = { + pressed: false, + targetPos: null, + columnHead: null + } + let hasInvalidClass = (target, lastColumn) => { + let iClass = ['w2ui-col-number', 'w2ui-col-expand', 'w2ui-col-select'] + if (lastColumn !== true) iClass.push('w2ui-head-last') + for (let i = 0; i < iClass.length; i++) { + if (query(target).closest('.w2ui-head').hasClass(iClass[i])) { + return true + } + } + return false + } + // attach original event listener + query(self.box) + .off('.colDrag') + .on('mousedown.colDrag', dragColStart) + function dragColStart(event) { + if (dragData.pressed || dragData.numberPreColumnsPresent === 0 || event.button !== 0) return + let edata, columns, origColumn, origColumnNumber + let preColHeadersSelector = '.w2ui-head.w2ui-col-number, .w2ui-head.w2ui-col-expand, .w2ui-head.w2ui-col-select' + // do nothing if it is not a header + if (!query(event.target).parents().hasClass('w2ui-head') || hasInvalidClass(event.target)) return + dragData.pressed = true + dragData.initialX = event.pageX + dragData.initialY = event.pageY + dragData.numberPreColumnsPresent = query(self.box).find(preColHeadersSelector).length + // start event for drag start + dragData.columnHead = origColumn = query(event.target).closest('.w2ui-head') + dragData.originalPos = origColumnNumber = parseInt(origColumn.attr('col'), 10) + edata = self.trigger('columnDragStart', { originalEvent: event, origColumnNumber, target: origColumn[0] }) + if (edata.isCancelled === true) return false + columns = dragData.columns = query(self.box).find('.w2ui-head:not(.w2ui-head-last)') + // add events + query(document).on('mouseup.colDrag', dragColEnd) + query(document).on('mousemove.colDrag', dragColOver) + let col = self.columns[dragData.originalPos] + let colText = w2utils.lang(typeof col.text == 'function' ? col.text(col) : col.text) + dragData.ghost = query.html(`${colText}`)[0] + query(document.body).append(dragData.ghost) + query(dragData.ghost) + .css({ + display: 'none', + left: event.pageX, + top: event.pageY, + opacity: 1, + margin: '3px 0 0 20px', + padding: '3px', + 'background-color': 'white', + position: 'fixed', + 'z-index': 999999, + }) + .addClass('.w2ui-grid-ghost') + + // establish current offsets + dragData.offsets = [] + for (let i = 0, l = columns.length; i < l; i++) { + let rect = columns[i].getBoundingClientRect() + dragData.offsets.push(rect.left) + } + // conclude event + edata.finish() + } + function dragColOver(event) { + if (!dragData.pressed || !dragData.columnHead) return + let cursorX = event.pageX + let cursorY = event.pageY + if (!hasInvalidClass(event.target, true)) { + markIntersection(event) + } + trackGhost(cursorX, cursorY) + } + function dragColEnd(event) { + if (!dragData.pressed || !dragData.columnHead) return + dragData.pressed = false + let edata, target, selected, columnConfig + let finish = () => { + let ghosts = query(self.box).find('.w2ui-grid-ghost') + query(self.box).find('.w2ui-intersection-marker').hide() + query(dragData.ghost).remove() + ghosts.remove() + // dragData.columns.css({ overflow: '' }).children('div').css({ overflow: '' }); + query(document).off('.colDrag') + dragData = {} + } + // if no move, then click event for sorting + if (event.pageX == dragData.initialX && event.pageY == dragData.initialY) { + self.columnClick(self.columns[dragData.originalPos].field, event) + finish() + return + } + // start event for drag start + edata = self.trigger('columnDragEnd', { originalEvent: event, target: dragData.columnHead[0], dragData }) + if (edata.isCancelled === true) return false + selected = self.columns[dragData.originalPos] + columnConfig = self.columns + if (dragData.originalPos != dragData.targetPos && dragData.targetPos != null) { + columnConfig.splice(dragData.targetPos, 0, w2utils.clone(selected)) + columnConfig.splice(columnConfig.indexOf(selected), 1) + } + finish() + self.refresh() + edata.finish({ targetColumn: target - 1 }) + } + function markIntersection(event) { + // if mouse over is not over table + if (query(event.target).closest('td').length == 0) { + return + } + // if mouse over invalid column + let rect1 = query(self.box).find('.w2ui-grid-body').get(0).getBoundingClientRect() + let rect2 = query(event.target).closest('td').get(0).getBoundingClientRect() + query(self.box).find('.w2ui-intersection-marker') + .show() + .css({ + left: (rect2.left - rect1.left) + 'px' + }) + let td = query(event.target).closest('td') + dragData.targetPos = td.hasClass('w2ui-head-last') ? self.columns.length : parseInt(td.attr('col')) + return + } + function trackGhost(cursorX, cursorY){ + query(dragData.ghost) + .css({ + left : (cursorX - 10) + 'px', + top : (cursorY - 10) + 'px' + }) + .show() + } + // return an object to remove drag if it has ever been enabled + return { + remove() { + query(self.box).off('.colDrag') + self.last.columnDrag = false + } + } + } + columnOnOff(event, field) { + // event before + let edata = this.trigger('columnOnOff', { target: this.name, field: field, originalEvent: event }) + if (edata.isCancelled === true) return + // collapse expanded rows + let rows = this.find({ 'w2ui.expanded': true }, true) + for (let r = 0; r < rows.length; r++) { + let tmp = this.records[r].w2ui + if (tmp && !Array.isArray(tmp.children)) { + this.records[r].w2ui.expanded = false + } + } + // show/hide + if (field == 'line-numbers') { + this.show.lineNumbers = !this.show.lineNumbers + this.refresh() + } else { + let col = this.getColumn(field) + if (col.hidden) { + this.showColumn(col.field) + } else { + this.hideColumn(col.field) + } + } + // event after + edata.finish() + } + initToolbar() { + // if it is already initiazlied + if (this.toolbar.render != null) { + return + } + let tb_items = this.toolbar.items || [] + this.toolbar.items = [] + this.toolbar = new w2toolbar(w2utils.extend({}, this.toolbar, { name: this.name +'_toolbar', owner: this })) + if (this.show.toolbarReload) { + this.toolbar.items.push(w2utils.extend({}, this.buttons.reload)) + } + if (this.show.toolbarColumns) { + this.toolbar.items.push(w2utils.extend({}, this.buttons.columns)) + } + if (this.show.toolbarSearch) { + let html =` +
    + ${this.buttons.search.html} +
    + + + x +
    + +
    + +
    +
    ` + this.toolbar.items.push({ + id: 'w2ui-search', + type: 'html', + html, + onRefresh: async (event) => { + await event.complete + let input = query(this.box).find(`#grid_${this.name}_search_all`) + w2utils.bindEvents(query(this.box).find(`#grid_${this.name}_search_all, .w2ui-action`), this) + // slow down live search calls + let slowSearch = w2utils.debounce((event) => { + let val = event.target.value + if (this.liveSearch && this.last.liveText != val) { + this.last.liveText = val + this.search(this.last.field, val) + } + if (event.keyCode == 40) { // arrow down + this.searchSuggest(true) + } + }, 250) + input + .on('change', event => { + if (!this.liveSearch) { + this.search(this.last.field, event.target.value) + this.searchSuggest(true, true, this) + } + }) + .on('blur', () => { this.last.liveText = '' }) + .on('keyup', slowSearch) + } + }) + } + if (Array.isArray(tb_items)) { + let ids = tb_items.map(item => item.id) + if (this.show.toolbarAdd && !ids.includes(this.buttons.add.id)) { + this.toolbar.items.push(w2utils.extend({}, this.buttons.add)) + } + if (this.show.toolbarEdit && !ids.includes(this.buttons.edit.id)) { + this.toolbar.items.push(w2utils.extend({}, this.buttons.edit)) + } + if (this.show.toolbarDelete && !ids.includes(this.buttons.delete.id)) { + this.toolbar.items.push(w2utils.extend({}, this.buttons.delete)) + } + if (this.show.toolbarSave && !ids.includes(this.buttons.save.id)) { + if (this.show.toolbarAdd || this.show.toolbarDelete || this.show.toolbarEdit) { + this.toolbar.items.push({ type: 'break', id: 'w2ui-break2' }) + } + this.toolbar.items.push(w2utils.extend({}, this.buttons.save)) + } + // fill in overwritten items with default buttons + // ids are w2ui-* but in this.buttons the map is just [add, edit, delete] + // must specify at least {id, name} in this.toolbar.items if you want to keep order + tb_items = tb_items.map(item => this.buttons[item.name] + ? w2utils.extend({}, this.buttons[item.name], item) : item) + } + // add original buttons + this.toolbar.items.push(...tb_items) + // ============================================= + // ------ Toolbar onClick processing + this.toolbar.on('click', (event) => { + let edata = this.trigger('toolbar', { target: event.target, originalEvent: event }) + if (edata.isCancelled === true) return + let edata2 + switch (event.detail.item.id) { + case 'w2ui-reload': + edata2 = this.trigger('reload', { target: this.name }) + if (edata2.isCancelled === true) return false + this.reload() + edata2.finish() + break + case 'w2ui-column-on-off': + // TODO: tap on columns will hide menu before opening, only in grid not in toolbar + if (event.detail.subItem) { + let id = event.detail.subItem.id + if (['w2ui-stateSave', 'w2ui-stateReset'].includes(id)) { + this[id.substring(5)]() + } else if (id == 'w2ui-skip') { + // empty + } else { + this.columnOnOff(event, event.detail.subItem.id) + } + } else { + this.initColumnOnOff() + // init input control with records to skip + setTimeout(() => { + query(`#w2overlay-${this.name}_toolbar-drop .w2ui-grid-skip`) + .off('.w2ui-grid') + .on('click.w2ui-grid', evt => { + evt.stopPropagation() + }) + .on('keypress', evt => { + if (evt.keyCode == 13) { + this.skip(evt.target.value) + this.toolbar.click('w2ui-column-on-off') // close menu + } + }) + }, 100) + } + break + case 'w2ui-add': + // events + edata2 = this.trigger('add', { target: this.name, recid: null }) + if (edata2.isCancelled === true) return false + edata2.finish() + break + case 'w2ui-edit': { + let sel = this.getSelection() + let recid = null + if (sel.length == 1) recid = sel[0] + // events + edata2 = this.trigger('edit', { target: this.name, recid: recid }) + if (edata2.isCancelled === true) return false + edata2.finish() + break + } + case 'w2ui-delete': + this.delete() + break + case 'w2ui-save': + this.save() + break + } + // no default action + edata.finish() + }) + this.toolbar.on('refresh', (event) => { + if (event.target == 'w2ui-search') { + let sd = this.searchData + setTimeout(() => { + this.searchInitInput(this.last.field, (sd.length == 1 ? sd[0].value : null)) + }, 1) + } + }) + } + initResize() { + let obj = this + query(this.box).find('.w2ui-resizer') + .off('.grid-col-resize') + .on('click.grid-col-resize', function(event) { + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true + if (event.preventDefault) event.preventDefault() + }) + .on('mousedown.grid-col-resize', function(event) { + if (!event) event = window.event + obj.last.colResizing = true + obj.last.tmp = { + x : event.screenX, + y : event.screenY, + gx : event.screenX, + gy : event.screenY, + col : parseInt(query(this).attr('name')) + } + // find tds that will be resized + obj.last.tmp.tds = query(obj.box).find('#grid_'+ obj.name +'_body table tr:first-child td[col="'+ obj.last.tmp.col +'"]') + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true + if (event.preventDefault) event.preventDefault() + // fix sizes + for (let c = 0; c < obj.columns.length; c++) { + if (obj.columns[c].hidden) continue + if (obj.columns[c].sizeOriginal == null) obj.columns[c].sizeOriginal = obj.columns[c].size + obj.columns[c].size = obj.columns[c].sizeCalculated + } + let edata = { phase: 'before', type: 'columnResize', target: obj.name, column: obj.last.tmp.col, field: obj.columns[obj.last.tmp.col].field } + edata = obj.trigger(w2utils.extend(edata, { resizeBy: 0, originalEvent: event })) + // set move event + let timer + let mouseMove = function(event) { + if (obj.last.colResizing != true) return + if (!event) event = window.event + // event before + edata = obj.trigger(w2utils.extend(edata, { resizeBy: (event.screenX - obj.last.tmp.gx), originalEvent: event })) + if (edata.isCancelled === true) { edata.isCancelled = false; return } + // default action + obj.last.tmp.x = (event.screenX - obj.last.tmp.x) + obj.last.tmp.y = (event.screenY - obj.last.tmp.y) + let newWidth = (parseInt(obj.columns[obj.last.tmp.col].size) + obj.last.tmp.x) + 'px' + obj.columns[obj.last.tmp.col].size = newWidth + if (timer) clearTimeout(timer) + timer = setTimeout(() => { + obj.resizeRecords() + obj.scroll() + }, 100) + // quick resize + obj.last.tmp.tds.css({ width: newWidth }) + // reset + obj.last.tmp.x = event.screenX + obj.last.tmp.y = event.screenY + } + let mouseUp = function(event) { + query(document).off('.grid-col-resize') + obj.resizeRecords() + obj.scroll() + // event after + edata.finish({ originalEvent: event }) + // need timeout to finish processing events + setTimeout(() => { obj.last.colResizing = false }, 1) + } + query(document) + .off('.grid-col-resize') + .on('mousemove.grid-col-resize', mouseMove) + .on('mouseup.grid-col-resize', mouseUp) + }) + .on('dblclick.grid-col-resize', function(event) { + let colId = parseInt(query(this).attr('name')), + col = obj.columns[colId], + maxDiff = 0 + if (col.autoResize === false) { + return true + } + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true + if (event.preventDefault) event.preventDefault() + query(obj.box).find('.w2ui-grid-records td[col="' + colId + '"] > div', obj.box).each(() => { + let thisDiff = this.offsetWidth - this.scrollWidth + if (thisDiff < maxDiff) { + maxDiff = thisDiff - 3 // 3px buffer needed for Firefox + } + }) + // event before + let edata = { phase: 'before', type: 'columnAutoResize', target: obj.name, column: col, field: col.field } + edata = obj.trigger(w2utils.extend(edata, { resizeBy: Math.abs(maxDiff), originalEvent: event })) + if (edata.isCancelled === true) { edata.isCancelled = false; return } + if (maxDiff < 0) { + col.size = Math.min(parseInt(col.size) + Math.abs(maxDiff), col.max || Infinity) + 'px' + obj.resizeRecords() + obj.resizeRecords() // Why do we have to call it twice in order to show the scrollbar? + obj.scroll() + } + // event after + edata.finish({ originalEvent: event }) + }) + .each(el => { + let td = query(el).get(0).parentNode + query(el).css({ + 'height' : td.clientHeight + 'px', + 'margin-left' : (td.clientWidth - 3) + 'px' + }) + }) + } + resizeBoxes() { + // elements + let header = query(this.box).find(`#grid_${this.name}_header`) + let toolbar = query(this.box).find(`#grid_${this.name}_toolbar`) + let fsummary = query(this.box).find(`#grid_${this.name}_fsummary`) + let summary = query(this.box).find(`#grid_${this.name}_summary`) + let footer = query(this.box).find(`#grid_${this.name}_footer`) + let body = query(this.box).find(`#grid_${this.name}_body`) + if (this.show.header) { + header.css({ + top: '0px', + left: '0px', + right: '0px' + }) + } + if (this.show.toolbar) { + toolbar.css({ + top: (0 + (this.show.header ? w2utils.getSize(header, 'height') : 0)) + 'px', + left: '0px', + right: '0px' + }) + } + if (this.summary.length > 0) { + fsummary.css({ + bottom: (0 + (this.show.footer ? w2utils.getSize(footer, 'height') : 0)) + 'px' + }) + summary.css({ + bottom: (0 + (this.show.footer ? w2utils.getSize(footer, 'height') : 0)) + 'px', + right: '0px' + }) + } + if (this.show.footer) { + footer.css({ + bottom: '0px', + left: '0px', + right: '0px' + }) + } + body.css({ + top: (0 + (this.show.header ? w2utils.getSize(header, 'height') : 0) + (this.show.toolbar ? w2utils.getSize(toolbar, 'height') : 0)) + 'px', + bottom: (0 + (this.show.footer ? w2utils.getSize(footer, 'height') : 0) + (this.summary.length > 0 ? w2utils.getSize(summary, 'height') : 0)) + 'px', + left: '0px', + right: '0px' + }) + } + resizeRecords() { + let obj = this + // remove empty records + query(this.box).find('.w2ui-empty-record').remove() + // -- Calculate Column size in PX + let box = query(this.box) + let grid = query(this.box).find(':scope > div.w2ui-grid-box') + let header = query(this.box).find(`#grid_${this.name}_header`) + let toolbar = query(this.box).find(`#grid_${this.name}_toolbar`) + let summary = query(this.box).find(`#grid_${this.name}_summary`) + let fsummary = query(this.box).find(`#grid_${this.name}_fsummary`) + let footer = query(this.box).find(`#grid_${this.name}_footer`) + let body = query(this.box).find(`#grid_${this.name}_body`) + let columns = query(this.box).find(`#grid_${this.name}_columns`) + let fcolumns = query(this.box).find(`#grid_${this.name}_fcolumns`) + let records = query(this.box).find(`#grid_${this.name}_records`) + let frecords = query(this.box).find(`#grid_${this.name}_frecords`) + let scroll1 = query(this.box).find(`#grid_${this.name}_scroll1`) + let lineNumberWidth = String(this.total).length * 8 + 10 + if (lineNumberWidth < 34) lineNumberWidth = 34 // 3 digit width + if (this.lineNumberWidth != null) lineNumberWidth = this.lineNumberWidth + let bodyOverflowX = false + let bodyOverflowY = false + let sWidth = 0 + for (let i = 0; i < this.columns.length; i++) { + if (this.columns[i].frozen || this.columns[i].hidden) continue + let cSize = parseInt(this.columns[i].sizeCalculated ? this.columns[i].sizeCalculated : this.columns[i].size) + sWidth += cSize + } + if (records[0]?.clientWidth < sWidth) bodyOverflowX = true + if (body[0]?.clientHeight - (columns[0]?.clientHeight ?? 0) + < (query(records).find(':scope > table')[0]?.clientHeight ?? 0) + (bodyOverflowX ? w2utils.scrollBarSize() : 0)) { + bodyOverflowY = true + } + // body might be expanded by data + if (!this.fixedBody) { + // allow it to render records, then resize + let bodyHeight = w2utils.getSize(columns, 'height') + + w2utils.getSize(query(this.box).find('#grid_'+ this.name +'_records table'), 'height') + + (bodyOverflowX ? w2utils.scrollBarSize() : 0) + let calculatedHeight = bodyHeight + + (this.show.header ? w2utils.getSize(header, 'height') : 0) + + (this.show.toolbar ? w2utils.getSize(toolbar, 'height') : 0) + + (summary.css('display') != 'none' ? w2utils.getSize(summary, 'height') : 0) + + (this.show.footer ? w2utils.getSize(footer, 'height') : 0) + grid.css('height', calculatedHeight + 'px') + body.css('height', bodyHeight + 'px') + box.css('height', w2utils.getSize(grid, 'height') + 'px') + } else { + // fixed body height + let calculatedHeight = grid[0]?.clientHeight + - (this.show.header ? w2utils.getSize(header, 'height') : 0) + - (this.show.toolbar ? w2utils.getSize(toolbar, 'height') : 0) + - (summary.css('display') != 'none' ? w2utils.getSize(summary, 'height') : 0) + - (this.show.footer ? w2utils.getSize(footer, 'height') : 0) + body.css('height', calculatedHeight + 'px') + } + let buffered = this.records.length + let url = (typeof this.url != 'object' ? this.url : this.url.get) + if (this.searchData.length != 0 && !url) buffered = this.last.searchIds.length + // apply overflow + if (!this.fixedBody) { bodyOverflowY = false } + if (bodyOverflowX || bodyOverflowY) { + columns.find(':scope > table > tbody > tr:nth-child(1) td.w2ui-head-last') + .css('width', w2utils.scrollBarSize() + 'px') + .show() + records.css({ + top: ((this.columnGroups.length > 0 && this.show.columns ? 1 : 0) + w2utils.getSize(columns, 'height')) +'px', + '-webkit-overflow-scrolling': 'touch', + 'overflow-x': (bodyOverflowX ? 'auto' : 'hidden'), + 'overflow-y': (bodyOverflowY ? 'auto' : 'hidden') + }) + } else { + columns.find(':scope > table > tbody > tr:nth-child(1) td.w2ui-head-last').hide() + records.css({ + top: ((this.columnGroups.length > 0 && this.show.columns ? 1 : 0) + w2utils.getSize(columns, 'height')) +'px', + overflow: 'hidden' + }) + if (records.length > 0) { this.last.scrollTop = 0; this.last.scrollLeft = 0 } // if no scrollbars, always show top + } + if (bodyOverflowX) { + frecords.css('margin-bottom', w2utils.scrollBarSize() + 'px') + scroll1.show() + } else { + frecords.css('margin-bottom', 0) + scroll1.hide() + } + frecords.css({ overflow: 'hidden', top: records.css('top') }) + if (this.show.emptyRecords && !bodyOverflowY) { + let max = Math.floor((records[0]?.clientHeight ?? 0) / this.recordHeight) - 1 + let leftover = 0 + if (records[0]) leftover = records[0].scrollHeight - max * this.recordHeight + if (leftover >= this.recordHeight) { + leftover -= this.recordHeight + max++ + } + if (this.fixedBody) { + for (let di = buffered; di < max; di++) { + addEmptyRow(di, this.recordHeight, this) + } + addEmptyRow(max, leftover, this) + } + } + function addEmptyRow(row, height, grid) { + let html1 = '' + let html2 = '' + let htmlp = '' + html1 += '' + html2 += '' + if (grid.show.lineNumbers) html1 += '' + if (grid.show.selectColumn) html1 += '' + if (grid.show.expandColumn) html1 += '' + html2 += '' + if (grid.reorderRows) html2 += '' + for (let j = 0; j < grid.columns.length; j++) { + let col = grid.columns[j] + if ((col.hidden || j < grid.last.colStart || j > grid.last.colEnd) && !col.frozen) continue + htmlp = '' + if (col.frozen) html1 += htmlp; else html2 += htmlp + } + html1 += ' ' + html2 += ' ' + query(grid.box).find('#grid_'+ grid.name +'_frecords > table').append(html1) + query(grid.box).find('#grid_'+ grid.name +'_records > table').append(html2) + } + let width_box, percent + if (body.length > 0) { + let width_max = parseInt(body[0].clientWidth) + - (bodyOverflowY ? w2utils.scrollBarSize() : 0) + - (this.show.lineNumbers ? lineNumberWidth : 0) + - (this.reorderRows ? 26 : 0) + - (this.show.selectColumn ? 26 : 0) + - (this.show.expandColumn ? 26 : 0) + - 1 // left is 1px due to border width + width_box = width_max + percent = 0 + // gridMinWidth processing + let restart = false + for (let i = 0; i < this.columns.length; i++) { + let col = this.columns[i] + if (col.gridMinWidth > 0) { + if (col.gridMinWidth > width_box && col.hidden !== true) { + col.hidden = true + restart = true + } + if (col.gridMinWidth < width_box && col.hidden === true) { + col.hidden = false + restart = true + } + } + } + if (restart === true) { + this.refresh() + return + } + // assign PX column s + for (let i = 0; i < this.columns.length; i++) { + let col = this.columns[i] + if (col.hidden) continue + if (String(col.size).substr(String(col.size).length-2).toLowerCase() == 'px') { + width_max -= parseFloat(col.size) + this.columns[i].sizeCalculated = col.size + this.columns[i].sizeType = 'px' + } else { + percent += parseFloat(col.size) + this.columns[i].sizeType = '%' + delete col.sizeCorrected + } + } + // if sum != 100% -- reassign proportionally + if (percent != 100 && percent > 0) { + for (let i = 0; i < this.columns.length; i++) { + let col = this.columns[i] + if (col.hidden) continue + if (col.sizeType == '%') { + col.sizeCorrected = Math.round(parseFloat(col.size) * 100 * 100 / percent) / 100 + '%' + } + } + } + // calculate % columns + for (let i = 0; i < this.columns.length; i++) { + let col = this.columns[i] + if (col.hidden) continue + if (col.sizeType == '%') { + if (this.columns[i].sizeCorrected != null) { + // make it 1px smaller, so margin of error can be calculated correctly + this.columns[i].sizeCalculated = Math.floor(width_max * parseFloat(col.sizeCorrected) / 100) - 1 + 'px' + } else { + // make it 1px smaller, so margin of error can be calculated correctly + this.columns[i].sizeCalculated = Math.floor(width_max * parseFloat(col.size) / 100) - 1 + 'px' + } + } + } + } + // fix margin of error that is due percentage calculations + let width_cols = 0 + for (let i = 0; i < this.columns.length; i++) { + let col = this.columns[i] + if (col.hidden) continue + if (col.min == null) col.min = 20 + if (parseInt(col.sizeCalculated) < parseInt(col.min)) col.sizeCalculated = col.min + 'px' + if (parseInt(col.sizeCalculated) > parseInt(col.max)) col.sizeCalculated = col.max + 'px' + width_cols += parseInt(col.sizeCalculated) + } + let width_diff = parseInt(width_box) - parseInt(width_cols) + if (width_diff > 0 && percent > 0) { + let i = 0 + while (true) { + let col = this.columns[i] + if (col == null) { i = 0; continue } + if (col.hidden || col.sizeType == 'px') { i++; continue } + col.sizeCalculated = (parseInt(col.sizeCalculated) + 1) + 'px' + width_diff-- + if (width_diff === 0) break + i++ + } + } else if (width_diff > 0) { + columns.find(':scope > table > tbody > tr:nth-child(1) td.w2ui-head-last') + .css('width', w2utils.scrollBarSize() + 'px') + .show() + } + // find width of frozen columns + let fwidth = 1 + if (this.show.lineNumbers) fwidth += lineNumberWidth + if (this.show.selectColumn) fwidth += 26 + // if (this.reorderRows) fwidth += 26; + if (this.show.expandColumn) fwidth += 26 + for (let i = 0; i < this.columns.length; i++) { + if (this.columns[i].hidden) continue + if (this.columns[i].frozen) fwidth += parseInt(this.columns[i].sizeCalculated) + } + fcolumns.css('width', fwidth + 'px') + frecords.css('width', fwidth + 'px') + fsummary.css('width', fwidth + 'px') + scroll1.css('width', fwidth + 'px') + columns.css('left', fwidth + 'px') + records.css('left', fwidth + 'px') + summary.css('left', fwidth + 'px') + // resize columns + columns.find(':scope > table > tbody > tr:nth-child(1) td') + .add(fcolumns.find(':scope > table > tbody > tr:nth-child(1) td')) + .each(el => { + // line numbers + if (query(el).hasClass('w2ui-col-number')) { + query(el).css('width', lineNumberWidth + 'px') + } + // records + let ind = query(el).attr('col') + if (ind != null) { + if (ind == 'start') { + let width = 0 + for (let i = 0; i < obj.last.colStart; i++) { + if (!obj.columns[i] || obj.columns[i].frozen || obj.columns[i].hidden) continue + width += parseInt(obj.columns[i].sizeCalculated) + } + query(el).css('width', width + 'px') + } + if (obj.columns[ind]) query(el).css('width', obj.columns[ind].sizeCalculated) // already has px + } + // last column + if (query(el).hasClass('w2ui-head-last')) { + if (obj.last.colEnd + 1 < obj.columns.length) { + let width = 0 + for (let i = obj.last.colEnd + 1; i < obj.columns.length; i++) { + if (!obj.columns[i] || obj.columns[i].frozen || obj.columns[i].hidden) continue + width += parseInt(obj.columns[i].sizeCalculated) + } + query(el).css('width', width + 'px') + } else { + query(el).css('width', w2utils.scrollBarSize() + (width_diff > 0 && percent === 0 ? width_diff : 0) + 'px') + } + } + }) + // if there are column groups - hide first row (needed for sizing) + if (columns.find(':scope > table > tbody > tr').length == 3) { + columns.find(':scope > table > tbody > tr:nth-child(1) td') + .add(fcolumns.find(':scope > table > tbody > tr:nth-child(1) td')) + .html('').css({ + 'height' : '0', + 'border' : '0', + 'padding': '0', + 'margin' : '0' + }) + } + // resize records + records.find(':scope > table > tbody > tr:nth-child(1) td') + .add(frecords.find(':scope > table > tbody > tr:nth-child(1) td')) + .each(el => { + // line numbers + if (query(el).hasClass('w2ui-col-number')) { + query(el).css('width', lineNumberWidth + 'px') + } + // records + let ind = query(el).attr('col') + if (ind != null) { + if (ind == 'start') { + let width = 0 + for (let i = 0; i < obj.last.colStart; i++) { + if (!obj.columns[i] || obj.columns[i].frozen || obj.columns[i].hidden) continue + width += parseInt(obj.columns[i].sizeCalculated) + } + query(el).css('width', width + 'px') + } + if (obj.columns[ind]) query(el).css('width', obj.columns[ind].sizeCalculated) + } + // last column + if (query(el).hasClass('w2ui-grid-data-last') && query(el).parents('.w2ui-grid-frecords').length === 0) { // not in frecords + if (obj.last.colEnd + 1 < obj.columns.length) { + let width = 0 + for (let i = obj.last.colEnd + 1; i < obj.columns.length; i++) { + if (!obj.columns[i] || obj.columns[i].frozen || obj.columns[i].hidden) continue + width += parseInt(obj.columns[i].sizeCalculated) + } + query(el).css('width', width + 'px') + } else { + query(el).css('width', (width_diff > 0 && percent === 0 ? width_diff : 0) + 'px') + } + } + }) + // resize summary + summary.find(':scope > table > tbody > tr:nth-child(1) td') + .add(fsummary.find(':scope > table > tbody > tr:nth-child(1) td')) + .each(el => { + // line numbers + if (query(el).hasClass('w2ui-col-number')) { + query(el).css('width', lineNumberWidth + 'px') + } + // records + let ind = query(el).attr('col') + if (ind != null) { + if (ind == 'start') { + let width = 0 + for (let i = 0; i < obj.last.colStart; i++) { + if (!obj.columns[i] || obj.columns[i].frozen || obj.columns[i].hidden) continue + width += parseInt(obj.columns[i].sizeCalculated) + } + query(el).css('width', width + 'px') + } + if (obj.columns[ind]) query(el).css('width', obj.columns[ind].sizeCalculated) + } + // last column + if (query(el).hasClass('w2ui-grid-data-last') && query(el).parents('.w2ui-grid-frecords').length === 0) { // not in frecords + query(el).css('width', w2utils.scrollBarSize() + (width_diff > 0 && percent === 0 ? width_diff : 0) + 'px') + } + }) + this.initResize() + this.refreshRanges() + // apply last scroll if any + if ((this.last.scrollTop || this.last.scrollLeft) && records.length > 0) { + columns.prop('scrollLeft', this.last.scrollLeft) + records.prop('scrollTop', this.last.scrollTop) + records.prop('scrollLeft', this.last.scrollLeft) + } + // Improved performance when scrolling through tables + columns.css('will-change', 'scroll-position') + } + getSearchesHTML() { + let html = ` +
    + ${w2utils.lang('Advanced Search')} + + + +
    + + ` + for (let i = 0; i < this.searches.length; i++) { + let s = this.searches[i] + s.type = String(s.type).toLowerCase() + if (s.hidden) continue + if (s.attr == null) s.attr = '' + if (s.text == null) s.text = '' + if (s.style == null) s.style = '' + if (s.type == null) s.type = 'text' + if (s.label == null && s.caption != null) { + console.log('NOTICE: grid search.caption property is deprecated, please use search.label. Search ->', s) + s.label = s.caption + } + let operator =`` + html += ` + + + ' + + '' + } + html += ` + + +
    ${(w2utils.lang(s.label) || '')}${operator}` + let tmpStyle + switch (s.type) { + case 'text': + case 'alphanumeric': + case 'hex': + case 'color': + case 'list': + case 'combo': + case 'enum': + tmpStyle = 'width: 250px;' + if (['hex', 'color'].indexOf(s.type) != -1) tmpStyle = 'width: 90px;' + html += `` + break + case 'int': + case 'float': + case 'money': + case 'currency': + case 'percent': + case 'date': + case 'time': + case 'datetime': + tmpStyle = 'width: 90px;' + if (s.type == 'datetime') tmpStyle = 'width: 140px;' + html += ` + ` + break + case 'select': + html += `` + break + } + html += s.text + + '
    + + + + +
    ` + return html + } + getOperators(type, opers) { + let operators = this.operators[this.operatorsMap[type]] || [] + if (opers != null && Array.isArray(opers)) { + operators = opers + } + let html = '' + operators.forEach(oper => { + let displayText = oper + let operValue = oper + if (Array.isArray(oper)) { + displayText = oper[1] + operValue = oper[0] + } else if (w2utils.isPlainObject(oper)) { + displayText = oper.text + operValue = oper.oper + } + if (displayText == null) displayText = oper + html += `\n` + }) + return html + } + initOperator(ind) { + let options + let search = this.searches[ind] + let sdata = this.getSearchData(search.field) + let overlay = query(`#w2overlay-${this.name}-search-overlay`) + let $rng = overlay.find(`#grid_${this.name}_range_${ind}`) + let $fld1 = overlay.find(`#grid_${this.name}_field_${ind}`) + let $fld2 = overlay.find(`#grid_${this.name}_field2_${ind}`) + let $oper = overlay.find(`#grid_${this.name}_operator_${ind}`) + let oper = $oper.val() + $fld1.show() + $rng.hide() + // init based on operator value + switch (oper) { + case 'between': + $rng.show() + break + case 'null': + case 'not null': + $fld1.hide() + $fld1.val(oper) // need to insert something for search to activate + $fld1.trigger('change') + break + } + // init based on search type + switch (search.type) { + case 'text': + case 'alphanumeric': + let fld = $fld1[0]._w2field + if (fld) { fld.reset() } + break + case 'int': + case 'float': + case 'hex': + case 'color': + case 'money': + case 'currency': + case 'percent': + case 'date': + case 'time': + case 'datetime': + if (!$fld1[0]._w2field) { + // init fields + new w2field(search.type, { el: $fld1[0], ...search.options }) + new w2field(search.type, { el: $fld2[0], ...search.options }) + setTimeout(() => { // convert to date if it is number + $fld1.trigger('keydown') + $fld2.trigger('keydown') + }, 1) + } + break + case 'list': + case 'combo': + case 'enum': + options = search.options + if (search.type == 'list') options.selected = {} + if (search.type == 'enum') options.selected = [] + if (sdata) options.selected = sdata.value + if (!$fld1[0]._w2field) { + let fld = new w2field(search.type, { el: $fld1[0], ...options }) + if (sdata && sdata.text != null) { + fld.set({ id: sdata.value, text: sdata.text }) + } + } + break + case 'select': + // build options + options = '' + for (let i = 0; i < search.options.items.length; i++) { + let si = search.options.items[i] + if (w2utils.isPlainObject(search.options.items[i])) { + let val = si.id + let txt = si.text + if (val == null && si.value != null) val = si.value + if (txt == null && si.text != null) txt = si.text + if (val == null) val = '' + options += '' + } else { + options += '' + } + } + $fld1.html(options) + break + } + } + initSearches() { + let overlay = query(`#w2overlay-${this.name}-search-overlay`) + // init searches + for (let ind = 0; ind < this.searches.length; ind++) { + let search = this.searches[ind] + let sdata = this.getSearchData(search.field) + search.type = String(search.type).toLowerCase() + if (typeof search.options != 'object') search.options = {} + // operators + let operator = search.operator + let operators = [...this.operators[this.operatorsMap[search.type]]] || [] // need a copy + if (search.operators) operators = search.operators + // normalize + if (w2utils.isPlainObject(operator)) operator = operator.oper + operators.forEach((oper, ind) => { + if (w2utils.isPlainObject(oper)) operators[ind] = oper.oper + }) + if (sdata && sdata.operator) { + operator = sdata.operator + } + // default operator + let def = this.defaultOperator[this.operatorsMap[search.type]] + if (operators.indexOf(operator) == -1) { + operator = def + } + overlay.find(`#grid_${this.name}_operator_${ind}`).val(operator) + this.initOperator(ind) + // populate field value + let $fld1 = overlay.find(`#grid_${this.name}_field_${ind}`) + let $fld2 = overlay.find(`#grid_${this.name}_field2_${ind}`) + if (sdata != null) { + if (!Array.isArray(sdata.value)) { + if (sdata.value != null) $fld1.val(sdata.value).trigger('change') + } else { + if (['in', 'not in'].includes(sdata.operator)) { + $fld1[0]._w2field.set(sdata.value) + } else { + $fld1.val(sdata.value[0]).trigger('change') + $fld2.val(sdata.value[1]).trigger('change') + } + } + } + } + // add on change event + overlay.find('.w2ui-grid-search-advanced *[rel=search]') + .on('keypress', evnt => { + if (evnt.keyCode == 13) { + this.search() + w2tooltip.hide(this.name + '-search-overlay') + } + }) + } + getColumnsHTML() { + let self = this + let html1 = '' + let html2 = '' + if (this.show.columnHeaders) { + if (this.columnGroups.length > 0) { + let tmp1 = getColumns(true) + let tmp2 = getGroups() + let tmp3 = getColumns(false) + html1 = tmp1[0] + tmp2[0] + tmp3[0] + html2 = tmp1[1] + tmp2[1] + tmp3[1] + } else { + let tmp = getColumns(true) + html1 = tmp[0] + html2 = tmp[1] + } + } + return [html1, html2] + function getGroups() { + let html1 = '' + let html2 = '' + let tmpf = '' + // add empty group at the end + let tmp = self.columnGroups.length - 1 + if (self.columnGroups[tmp].text == null && self.columnGroups[tmp].caption != null) { + console.log('NOTICE: grid columnGroup.caption property is deprecated, please use columnGroup.text. Group -> ', self.columnGroups[tmp]) + self.columnGroups[tmp].text = self.columnGroups[tmp].caption + } + if (self.columnGroups[self.columnGroups.length-1].text != '') self.columnGroups.push({ text: '' }) + if (self.show.lineNumbers) { + html1 += '' + + '
     
    ' + + '' + } + if (self.show.selectColumn) { + html1 += '' + + '
     
    ' + + '' + } + if (self.show.expandColumn) { + html1 += '' + + '
     
    ' + + '' + } + let ii = 0 + html2 += `` + if (self.reorderRows) { + html2 += '' + + '
     
    ' + + '' + } + for (let i = 0; i < self.columnGroups.length; i++) { + let colg = self.columnGroups[i] + let col = self.columns[ii] || {} + if (colg.colspan != null) colg.span = colg.colspan + if (colg.span == null || colg.span != parseInt(colg.span)) colg.span = 1 + if (col.text == null && col.caption != null) { + console.log('NOTICE: grid column.caption property is deprecated, please use column.text. Column ->', col) + col.text = col.caption + } + let colspan = 0 + for (let jj = ii; jj < ii + colg.span; jj++) { + if (self.columns[jj] && !self.columns[jj].hidden) { + colspan++ + } + } + if (i == self.columnGroups.length-1) { + colspan = 100 // last column + } + if (colspan <= 0) { + // do nothing here, all columns in the group are hidden. + } else if (colg.main === true) { + let sortStyle = '' + for (let si = 0; si < self.sortData.length; si++) { + if (self.sortData[si].field == col.field) { + if ((self.sortData[si].direction || '').toLowerCase() === 'asc') sortStyle = 'w2ui-sort-up' + if ((self.sortData[si].direction || '').toLowerCase() === 'desc') sortStyle = 'w2ui-sort-down' + } + } + let resizer = '' + if (col.resizable !== false) { + resizer = `
    ` + } + let text = w2utils.lang(typeof col.text == 'function' ? col.text(col) : col.text) + tmpf = ``+ resizer + + `
    ` + + `
    ` + (!text ? ' ' : text) + + '
    '+ + '' + if (col && col.frozen) html1 += tmpf; else html2 += tmpf + } else { + let gText = w2utils.lang(typeof colg.text == 'function' ? colg.text(colg) : colg.text) + tmpf = `` + + `
    ${!gText ? ' ' : gText}
    ` + + '' + if (col && col.frozen) html1 += tmpf; else html2 += tmpf + } + ii += colg.span + } + html1 += '' // need empty column for border-right + html2 += `` + return [html1, html2] + } + function getColumns(main) { + let html1 = '' + let html2 = '' + if (self.show.lineNumbers) { + html1 += '' + + '
    #
    ' + + '' + } + if (self.show.selectColumn) { + html1 += '' + + '
    ' + + ` ' + + '
    ' + + '' + } + if (self.show.expandColumn) { + html1 += '' + + '
     
    ' + + '' + } + let ii = 0 + let id = 0 + let colg + html2 += `` + if (self.reorderRows) { + html2 += ''+ + '
     
    '+ + '' + } + for (let i = 0; i < self.columns.length; i++) { + let col = self.columns[i] + if (col.text == null && col.caption != null) { + console.log('NOTICE: grid column.caption property is deprecated, please use column.text. Column -> ', col) + col.text = col.caption + } + if (col.size == null) col.size = '100%' + if (i == id) { // always true on first iteration + colg = self.columnGroups[ii++] || {} + id = id + colg.span + } + if ((i < self.last.colStart || i > self.last.colEnd) && !col.frozen) + continue + if (col.hidden) + continue + if (colg.main !== true || main) { // grouping of columns + let colCellHTML = self.getColumnCellHTML(i) + if (col && col.frozen) html1 += colCellHTML; else html2 += colCellHTML + } + } + html1 += '
     
    ' + html2 += '
     
    ' + html1 += '' + html2 += '' + return [html1, html2] + } + } + getColumnCellHTML(i) { + let col = this.columns[i] + if (col == null) return '' + // reorder style + let reorderCols = (this.reorderColumns && (!this.columnGroups || !this.columnGroups.length)) ? ' w2ui-col-reorderable ' : '' + // sort style + let sortStyle = '' + for (let si = 0; si < this.sortData.length; si++) { + if (this.sortData[si].field == col.field) { + if ((this.sortData[si].direction || '').toLowerCase() === 'asc') sortStyle = 'w2ui-sort-up' + if ((this.sortData[si].direction || '').toLowerCase() === 'desc') sortStyle = 'w2ui-sort-down' + } + } + // col selected + let tmp = this.last.selection.columns + let selected = false + for (let t in tmp) { + for (let si = 0; si < tmp[t].length; si++) { + if (tmp[t][si] == i) selected = true + } + } + let text = w2utils.lang(typeof col.text == 'function' ? col.text(col) : col.text) + let html = '' + + (col.resizable !== false ? '
    ' : '') + + '
    '+ + '
    '+ + (!text ? ' ' : text) + + '
    '+ + '' + return html + } + columnTooltipShow(ind, event) { + let $el = query(this.box).find('#grid_'+ this.name + '_column_'+ ind) + let item = this.columns[ind] + let pos = this.columnTooltip + w2tooltip.show({ + name: this.name + '-column-tooltip', + anchor: $el.get(0), + html: item?.tooltip, + position: pos, + }) + } + columnTooltipHide(ind, event) { + w2tooltip.hide(this.name + '-column-tooltip') + } + getRecordsHTML() { + let buffered = this.records.length + let url = (typeof this.url != 'object' ? this.url : this.url.get) + if (this.searchData.length != 0 && !url) buffered = this.last.searchIds.length + // larger number works better with chrome, smaller with FF. + if (buffered > this.vs_start) this.last.show_extra = this.vs_extra; else this.last.show_extra = this.vs_start + let records = query(this.box).find(`#grid_${this.name}_records`) + let limit = Math.floor((records.get(0)?.clientHeight || 0) / this.recordHeight) + this.last.show_extra + 1 + if (!this.fixedBody || limit > buffered) limit = buffered + // always need first record for resizing purposes + let rec_html = this.getRecordHTML(-1, 0) + let html1 = '' + rec_html[0] + let html2 = '
    ' + rec_html[1] + // first empty row with height + html1 += ''+ + ' '+ + '' + html2 += ''+ + ' '+ + '' + for (let i = 0; i < limit; i++) { + rec_html = this.getRecordHTML(i, i+1) + html1 += rec_html[0] + html2 += rec_html[1] + } + let h2 = (buffered - limit) * this.recordHeight + html1 += '' + + ' '+ + ''+ + ''+ + ' '+ + ''+ + '
    ' + html2 += '' + + ' '+ + ''+ + ''+ + ' '+ + ''+ + '' + this.last.range_start = 0 + this.last.range_end = limit + return [html1, html2] + } + getSummaryHTML() { + if (this.summary.length === 0) return + let rec_html = this.getRecordHTML(-1, 0) // need this in summary too for colspan to work properly + let html1 = '' + rec_html[0] + let html2 = '
    ' + rec_html[1] + for (let i = 0; i < this.summary.length; i++) { + rec_html = this.getRecordHTML(i, i+1, true) + html1 += rec_html[0] + html2 += rec_html[1] + } + html1 += '
    ' + html2 += '' + return [html1, html2] + } + scroll(event) { + let obj = this + let url = (typeof this.url != 'object' ? this.url : this.url.get) + let records = query(this.box).find(`#grid_${this.name}_records`) + let frecords = query(this.box).find(`#grid_${this.name}_frecords`) + // sync scroll positions + if (event) { + let sTop = event.target.scrollTop + let sLeft = event.target.scrollLeft + this.last.scrollTop = sTop + this.last.scrollLeft = sLeft + let cols = query(this.box).find(`#grid_${this.name}_columns`)[0] + let summary = query(this.box).find(`#grid_${this.name}_summary`)[0] + if (cols) cols.scrollLeft = sLeft + if (summary) summary.scrollLeft = sLeft + if (frecords[0]) frecords[0].scrollTop = sTop + } + // hide bubble + if (this.last.bubbleEl) { + w2tooltip.hide(this.name + '-bubble') + this.last.bubbleEl = null + } + // column virtual scroll + let colStart = null + let colEnd = null + if (this.disableCVS || this.columnGroups.length > 0) { + // disable virtual scroll + colStart = 0 + colEnd = this.columns.length - 1 + } else { + let sWidth = records.prop('clientWidth') + let cLeft = 0 + for (let i = 0; i < this.columns.length; i++) { + if (this.columns[i].frozen || this.columns[i].hidden) continue + let cSize = parseInt(this.columns[i].sizeCalculated ? this.columns[i].sizeCalculated : this.columns[i].size) + if (cLeft + cSize + 30 > this.last.scrollLeft && colStart == null) colStart = i + if (cLeft + cSize - 30 > this.last.scrollLeft + sWidth && colEnd == null) colEnd = i + cLeft += cSize + } + if (colEnd == null) colEnd = this.columns.length - 1 + } + if (colStart != null) { + if (colStart < 0) colStart = 0 + if (colEnd < 0) colEnd = 0 + if (colStart == colEnd) { + if (colStart > 0) colStart--; else colEnd++ // show at least one column + } + // --------- + if (colStart != this.last.colStart || colEnd != this.last.colEnd) { + let $box = query(this.box) + let deltaStart = Math.abs(colStart - this.last.colStart) + let deltaEnd = Math.abs(colEnd - this.last.colEnd) + // add/remove columns for small jumps + if (deltaStart < 5 && deltaEnd < 5) { + let $cfirst = $box.find(`.w2ui-grid-columns #grid_${this.name}_column_start`) + let $clast = $box.find('.w2ui-grid-columns .w2ui-head-last') + let $rfirst = $box.find(`#grid_${this.name}_records .w2ui-grid-data-spacer`) + let $rlast = $box.find(`#grid_${this.name}_records .w2ui-grid-data-last`) + let $sfirst = $box.find(`#grid_${this.name}_summary .w2ui-grid-data-spacer`) + let $slast = $box.find(`#grid_${this.name}_summary .w2ui-grid-data-last`) + // remove on left + if (colStart > this.last.colStart) { + for (let i = this.last.colStart; i < colStart; i++) { + $box.find('#grid_'+ this.name +'_columns #grid_'+ this.name +'_column_'+ i).remove() // column + $box.find('#grid_'+ this.name +'_records td[col="'+ i +'"]').remove() // record + $box.find('#grid_'+ this.name +'_summary td[col="'+ i +'"]').remove() // summary + } + } + // remove on right + if (colEnd < this.last.colEnd) { + for (let i = this.last.colEnd; i > colEnd; i--) { + $box.find('#grid_'+ this.name +'_columns #grid_'+ this.name +'_column_'+ i).remove() // column + $box.find('#grid_'+ this.name +'_records td[col="'+ i +'"]').remove() // record + $box.find('#grid_'+ this.name +'_summary td[col="'+ i +'"]').remove() // summary + } + } + // add on left + if (colStart < this.last.colStart) { + for (let i = this.last.colStart - 1; i >= colStart; i--) { + if (this.columns[i] && (this.columns[i].frozen || this.columns[i].hidden)) continue + $cfirst.after(this.getColumnCellHTML(i)) // column + // record + $rfirst.each(el => { + let index = query(el).parent().attr('index') + let td = '' // width column + if (index != null) td = this.getCellHTML(parseInt(index), i, false) + query(el).after(td) + }) + // summary + $sfirst.each(el => { + let index = query(el).parent().attr('index') + let td = '' // width column + if (index != null) td = this.getCellHTML(parseInt(index), i, true) + query(el).after(td) + }) + } + } + // add on right + if (colEnd > this.last.colEnd) { + for (let i = this.last.colEnd + 1; i <= colEnd; i++) { + if (this.columns[i] && (this.columns[i].frozen || this.columns[i].hidden)) continue + $clast.before(this.getColumnCellHTML(i)) // column + // record + $rlast.each(el => { + let index = query(el).parent().attr('index') + let td = '' // width column + if (index != null) td = this.getCellHTML(parseInt(index), i, false) + query(el).before(td) + }) + // summary + $slast.each(el => { + let index = query(el).parent().attr('index') || -1 + let td = this.getCellHTML(parseInt(index), i, true) + query(el).before(td) + }) + } + } + this.last.colStart = colStart + this.last.colEnd = colEnd + this.resizeRecords() + } else { + this.last.colStart = colStart + this.last.colEnd = colEnd + // dot not just call this.refresh(); + let colHTML = this.getColumnsHTML() + let recHTML = this.getRecordsHTML() + let sumHTML = this.getSummaryHTML() + let $columns = $box.find(`#grid_${this.name}_columns`) + let $records = $box.find(`#grid_${this.name}_records`) + let $frecords = $box.find(`#grid_${this.name}_frecords`) + let $summary = $box.find(`#grid_${this.name}_summary`) + $columns.find('tbody').html(colHTML[1]) + $frecords.html(recHTML[0]) + $records.prepend(recHTML[1]) + if (sumHTML != null) $summary.html(sumHTML[1]) + // need timeout to clean up (otherwise scroll problem) + setTimeout(() => { + $records.find(':scope > table').filter(':not(table:first-child)').remove() + if ($summary[0]) $summary[0].scrollLeft = this.last.scrollLeft + }, 1) + this.resizeRecords() + } + } + } + // perform virtual scroll + let buffered = this.records.length + if (buffered > this.total && this.total !== -1) buffered = this.total + if (this.searchData.length != 0 && !url) buffered = this.last.searchIds.length + if (buffered === 0 || records.length === 0 || records.prop('clientHeight') === 0) return + if (buffered > this.vs_start) this.last.show_extra = this.vs_extra; else this.last.show_extra = this.vs_start + // update footer + let t1 = Math.round(records.prop('scrollTop') / this.recordHeight + 1) + let t2 = t1 + (Math.round(records.prop('clientHeight') / this.recordHeight) - 1) + if (t1 > buffered) t1 = buffered + if (t2 >= buffered - 1) t2 = buffered + query(this.box).find('#grid_'+ this.name + '_footer .w2ui-footer-right').html( + (this.show.statusRange + ? w2utils.formatNumber(this.offset + t1) + '-' + w2utils.formatNumber(this.offset + t2) + + (this.total != -1 ? ' ' + w2utils.lang('of') + ' ' + w2utils.formatNumber(this.total) : '') + : '') + + (url && this.show.statusBuffered ? ' ('+ w2utils.lang('buffered') + ' '+ w2utils.formatNumber(buffered) + + (this.offset > 0 ? ', skip ' + w2utils.formatNumber(this.offset) : '') + ')' : '') + ) + // only for local data source, else no extra records loaded + if (!url && (!this.fixedBody || (this.total != -1 && this.total <= this.vs_start))) return + // regular processing + let start = Math.floor(records.prop('scrollTop') / this.recordHeight) - this.last.show_extra + let end = start + Math.floor(records.prop('clientHeight') / this.recordHeight) + this.last.show_extra * 2 + 1 + // let div = start - this.last.range_start; + if (start < 1) start = 1 + if (end > this.total && this.total != -1) end = this.total + let tr1 = records.find('#grid_'+ this.name +'_rec_top') + let tr2 = records.find('#grid_'+ this.name +'_rec_bottom') + let tr1f = frecords.find('#grid_'+ this.name +'_frec_top') + let tr2f = frecords.find('#grid_'+ this.name +'_frec_bottom') + // if row is expanded + if (String(tr1.next().prop('id')).indexOf('_expanded_row') != -1) { + tr1.next().remove() + tr1f.next().remove() + } + if (this.total > end && String(tr2.prev().prop('id')).indexOf('_expanded_row') != -1) { + tr2.prev().remove() + tr2f.prev().remove() + } + let first = parseInt(tr1.next().attr('line')) + let last = parseInt(tr2.prev().attr('line')) + let tmp, tmp1, tmp2, rec_start, rec_html + if (first < start || first == 1 || this.last.pull_refresh) { // scroll down + if (end <= last + this.last.show_extra - 2 && end != this.total) return + this.last.pull_refresh = false + // remove from top + while (true) { + tmp1 = frecords.find('#grid_'+ this.name +'_frec_top').next() + tmp2 = records.find('#grid_'+ this.name +'_rec_top').next() + if (tmp2.attr('line') == 'bottom') break + if (parseInt(tmp2.attr('line')) < start) { + tmp1.remove() + tmp2.remove() + } else { + break + } + } + // add at bottom + tmp = records.find('#grid_'+ this.name +'_rec_bottom').prev() + rec_start = tmp.attr('line') + if (rec_start == 'top') rec_start = start + for (let i = parseInt(rec_start) + 1; i <= end; i++) { + if (!this.records[i-1]) continue + tmp2 = this.records[i-1].w2ui + if (tmp2 && !Array.isArray(tmp2.children)) { + tmp2.expanded = false + } + rec_html = this.getRecordHTML(i-1, i) + tr2.before(rec_html[1]) + tr2f.before(rec_html[0]) + } + markSearch() + setTimeout(() => { this.refreshRanges() }, 0) + } else { // scroll up + if (start >= first - this.last.show_extra + 2 && start > 1) return + // remove from bottom + while (true) { + tmp1 = frecords.find('#grid_'+ this.name +'_frec_bottom').prev() + tmp2 = records.find('#grid_'+ this.name +'_rec_bottom').prev() + if (tmp2.attr('line') == 'top') break + if (parseInt(tmp2.attr('line')) > end) { + tmp1.remove() + tmp2.remove() + } else { + break + } + } + // add at top + tmp = records.find('#grid_'+ this.name +'_rec_top').next() + rec_start = tmp.attr('line') + if (rec_start == 'bottom') rec_start = end + for (let i = parseInt(rec_start) - 1; i >= start; i--) { + if (!this.records[i-1]) continue + tmp2 = this.records[i-1].w2ui + if (tmp2 && !Array.isArray(tmp2.children)) { + tmp2.expanded = false + } + rec_html = this.getRecordHTML(i-1, i) + tr1.after(rec_html[1]) + tr1f.after(rec_html[0]) + } + markSearch() + setTimeout(() => { this.refreshRanges() }, 0) + } + // first/last row size + let h1 = (start - 1) * this.recordHeight + let h2 = (buffered - end) * this.recordHeight + if (h2 < 0) h2 = 0 + tr1.css('height', h1 + 'px') + tr1f.css('height', h1 + 'px') + tr2.css('height', h2 + 'px') + tr2f.css('height', h2 + 'px') + this.last.range_start = start + this.last.range_end = end + // load more if needed + let s = Math.floor(records.prop('scrollTop') / this.recordHeight) + let e = s + Math.floor(records.prop('clientHeight') / this.recordHeight) + if (e + 10 > buffered && this.last.pull_more !== true && (buffered < this.total - this.offset || (this.total == -1 && this.last.fetch.hasMore))) { + if (this.autoLoad === true) { + this.last.pull_more = true + this.last.fetch.offset += this.limit + this.request('load') + } + // scroll function + let more = query(this.box).find('#grid_'+ this.name +'_rec_more, #grid_'+ this.name +'_frec_more') + more.show() + .eq(1) // only main table + .off('.load-more') + .on('click.load-more', function() { + // show spinner + query(this).find('td').html('
    ') + // load more + obj.last.pull_more = true + obj.last.fetch.offset += obj.limit + obj.request('load') + }) + .find('td') + .html(obj.autoLoad + ? '
    ' + : '
    '+ w2utils.lang('Load ${count} more...', { count: obj.limit }) + '
    ' + ) + } + function markSearch() { + // mark search + if (!obj.markSearch) return + clearTimeout(obj.last.marker_timer) + obj.last.marker_timer = setTimeout(() => { + // mark all search strings + let search = [] + for (let s = 0; s < obj.searchData.length; s++) { + let sdata = obj.searchData[s] + let fld = obj.getSearch(sdata.field) + if (!fld || fld.hidden) continue + let ind = obj.getColumn(sdata.field, true) + search.push({ field: sdata.field, search: sdata.value, col: ind }) + } + if (search.length > 0) { + search.forEach((item) => { + let el = query(obj.box).find('td[col="'+ item.col +'"]:not(.w2ui-head)') + w2utils.marker(el, item.search) + }) + } + }, 50) + } + } + getRecordHTML(ind, lineNum, summary) { + let tmph = '' + let rec_html1 = '' + let rec_html2 = '' + let sel = this.last.selection + let record + // first record needs for resize purposes + if (ind == -1) { + rec_html1 += '' + rec_html2 += '' + if (this.show.lineNumbers) rec_html1 += '' + if (this.show.selectColumn) rec_html1 += '' + if (this.show.expandColumn) rec_html1 += '' + rec_html2 += '' + if (this.reorderRows) rec_html2 += '' + for (let i = 0; i < this.columns.length; i++) { + let col = this.columns[i] + tmph = '' + if (col.frozen && !col.hidden) { + rec_html1 += tmph + } else { + if (col.hidden || i < this.last.colStart || i > this.last.colEnd) continue + rec_html2 += tmph + } + } + rec_html1 += '' + rec_html2 += '' + rec_html1 += '' + rec_html2 += '' + return [rec_html1, rec_html2] + } + // regular record + let url = (typeof this.url != 'object' ? this.url : this.url.get) + if (summary !== true) { + if (this.searchData.length > 0 && !url) { + if (ind >= this.last.searchIds.length) return '' + ind = this.last.searchIds[ind] + record = this.records[ind] + } else { + if (ind >= this.records.length) return '' + record = this.records[ind] + } + } else { + if (ind >= this.summary.length) return '' + record = this.summary[ind] + } + if (!record) return '' + if (record.recid == null && this.recid != null) { + let rid = this.parseField(record, this.recid) + if (rid != null) record.recid = rid + } + let isRowSelected = false + if (sel.indexes.indexOf(ind) != -1) isRowSelected = true + let rec_style = (record.w2ui ? record.w2ui.style : '') + if (rec_style == null || typeof rec_style != 'string') rec_style = '' + let rec_class = (record.w2ui ? record.w2ui.class : '') + if (rec_class == null || typeof rec_class != 'string') rec_class = '' + // render TR + rec_html1 += '' + rec_html2 += '' + if (this.show.lineNumbers) { + rec_html1 += ''+ + (summary !== true ? this.getLineHTML(lineNum, record) : '') + + '' + } + if (this.show.selectColumn) { + rec_html1 += + ''+ + (summary !== true && !(record.w2ui && record.w2ui.hideCheckBox === true) ? + '
    '+ + ' '+ + '
    ' + : + '' ) + + '' + } + if (this.show.expandColumn) { + let tmp_img = '' + if (record.w2ui?.expanded === true) tmp_img = '-'; else tmp_img = '+' + if ((record.w2ui?.expanded == 'none' || !Array.isArray(record.w2ui?.children) || !record.w2ui?.children.length)) tmp_img = '+' + if (record.w2ui?.expanded == 'spinner') tmp_img = '
    ' + rec_html1 += + ''+ + (summary !== true ? `
    ${tmp_img}
    ` : '' ) + + '' + } + // insert empty first column + rec_html2 += '' + if (this.reorderRows) { + rec_html2 += + ''+ + (summary !== true ? '
     
    ' : '' ) + + '' + } + let col_ind = 0 + let col_skip = 0 + while (true) { + let col_span = 1 + let col = this.columns[col_ind] + if (col == null) break + if (col.hidden) { + col_ind++ + if (col_skip > 0) col_skip-- + continue + } + if (col_skip > 0) { + col_ind++ + if (this.columns[col_ind] == null) break + record.w2ui.colspan[this.columns[col_ind-1].field] = 0 // need it for other methods + col_skip-- + continue + } else if (record.w2ui) { + let tmp1 = record.w2ui.colspan + let tmp2 = this.columns[col_ind].field + if (tmp1 && tmp1[tmp2] === 0) { + delete tmp1[tmp2] // if no longer colspan then remove 0 + } + } + // column virtual scroll + if ((col_ind < this.last.colStart || col_ind > this.last.colEnd) && !col.frozen) { + col_ind++ + continue + } + if (record.w2ui) { + if (typeof record.w2ui.colspan == 'object') { + let span = parseInt(record.w2ui.colspan[col.field]) || null + if (span > 1) { + // if there are hidden columns, then no colspan on them + let hcnt = 0 + for (let i = col_ind; i < col_ind + span; i++) { + if (i >= this.columns.length) break + if (this.columns[i].hidden) hcnt++ + } + col_span = span - hcnt + col_skip = span - 1 + } + } + } + let rec_cell = this.getCellHTML(ind, col_ind, summary, col_span) + if (col.frozen) rec_html1 += rec_cell; else rec_html2 += rec_cell + col_ind++ + } + rec_html1 += '' + rec_html2 += '' + rec_html1 += '' + rec_html2 += '' + return [rec_html1, rec_html2] + } + getLineHTML(lineNum) { + return '
    ' + lineNum + '
    ' + } + getCellHTML(ind, col_ind, summary, col_span) { + let obj = this + let col = this.columns[col_ind] + if (col == null) return '' + let record = (summary !== true ? this.records[ind] : this.summary[ind]) + // value, attr, style, className, divAttr + let { value, style, className, attr, divAttr } = this.getCellValue(ind, col_ind, summary, true) + let edit = (ind !== -1 ? this.getCellEditable(ind, col_ind) : '') + let divStyle = 'max-height: '+ parseInt(this.recordHeight) +'px;' + (col.clipboardCopy ? 'margin-right: 20px' : '') + let isChanged = !summary && record?.w2ui?.changes && record.w2ui.changes[col.field] != null + let sel = this.last.selection + let isRowSelected = false + let infoBubble = '' + if (sel.indexes.indexOf(ind) != -1) isRowSelected = true + if (col_span == null) { + if (record?.w2ui?.colspan && record.w2ui.colspan[col.field]) { + col_span = record.w2ui.colspan[col.field] + } else { + col_span = 1 + } + } + // expand icon + if (col_ind === 0 && Array.isArray(record?.w2ui?.children)) { + let level = 0 + let subrec = this.get(record.w2ui.parent_recid, true) + while (true) { + if (subrec != null) { + level++ + let tmp = this.records[subrec].w2ui + if (tmp != null && tmp.parent_recid != null) { + subrec = this.get(tmp.parent_recid, true) + } else { + break + } + } else { + break + } + } + if (record.w2ui.parent_recid) { + for (let i = 0; i < level; i++) { + infoBubble += '' + } + } + let className = record.w2ui.children.length > 0 + ? (record.w2ui.expanded ? 'w2ui-icon-collapse' : 'w2ui-icon-expand') + : 'w2ui-icon-empty' + infoBubble += `` + } + // info bubble + if (col.info === true) col.info = {} + if (col.info != null) { + let infoIcon = 'w2ui-icon-info' + if (typeof col.info.icon == 'function') { + infoIcon = col.info.icon(record, { self: this, index: ind, colIndex: col_ind, summary: !!summary }) + } else if (typeof col.info.icon == 'object') { + infoIcon = col.info.icon[this.parseField(record, col.field)] || '' + } else if (typeof col.info.icon == 'string') { + infoIcon = col.info.icon + } + let infoStyle = col.info.style || '' + if (typeof col.info.style == 'function') { + infoStyle = col.info.style(record, { self: this, index: ind, colIndex: col_ind, summary: !!summary }) + } else if (typeof col.info.style == 'object') { + infoStyle = col.info.style[this.parseField(record, col.field)] || '' + } else if (typeof col.info.style == 'string') { + infoStyle = col.info.style + } + infoBubble += `` + } + let data = value + // if editable checkbox + if (edit && ['checkbox', 'check'].indexOf(edit.type) != -1) { + let changeInd = summary ? -(ind + 1) : ind + divStyle += 'text-align: center;' + data = `` + infoBubble = '' + } + data = `
    ${infoBubble}${String(data)}
    ` + if (data == null) data = '' + // --> cell TD + if (typeof col.render == 'string') { + let tmp = col.render.toLowerCase().split(':') + if (['number', 'int', 'float', 'money', 'currency', 'percent', 'size'].indexOf(tmp[0]) != -1) { + style += 'text-align: right;' + } + } + if (record?.w2ui) { + if (typeof record.w2ui.style == 'object') { + if (typeof record.w2ui.style[col_ind] == 'string') style += record.w2ui.style[col_ind] + ';' + if (typeof record.w2ui.style[col.field] == 'string') style += record.w2ui.style[col.field] + ';' + } + if (typeof record.w2ui.class == 'object') { + if (typeof record.w2ui.class[col_ind] == 'string') className += record.w2ui.class[col_ind] + ' ' + if (typeof record.w2ui.class[col.field] == 'string') className += record.w2ui.class[col.field] + ' ' + } + } + let isCellSelected = false + if (isRowSelected && sel.columns[ind]?.includes(col_ind)) isCellSelected = true + // clipboardCopy + let clipboardIcon + if (col.clipboardCopy){ + clipboardIcon = '' + } + // data + data = ' 1 ? 'colspan="'+ col_span + '"' : '') + + '>' + data + (clipboardIcon && w2utils.stripTags(data) ? clipboardIcon : '') +'' + // summary top row + if (ind === -1 && summary === true) { + data = ' 1 ? 'colspan="'+ col_span + '"' : '') + + '>' + } + return data + function getTitle(cellData){ + let title + if (obj.show.recordTitles) { + if (col.title != null) { + if (typeof col.title == 'function') { + title = col.title.call(obj, record, { self: this, index: ind, colIndex: col_ind, summary: !!summary }) + } + if (typeof col.title == 'string') title = col.title + } else { + title = w2utils.stripTags(String(cellData).replace(/"/g, '\'\'')) + } + } + return (title != null) ? 'title="' + String(title) + '"' : '' + } + } + clipboardCopy(ind, col_ind, summary) { + let rec = summary ? this.summary[ind] : this.records[ind] + let col = this.columns[col_ind] + let txt = (col ? this.parseField(rec, col.field) : '') + if (typeof col.clipboardCopy == 'function') { + txt = col.clipboardCopy(rec, { self: this, index: ind, colIndex: col_ind, summary: !!summary }) + } + query(this.box).find('#grid_' + this.name + '_focus').text(txt).get(0).select() + document.execCommand('copy') + } + showBubble(ind, col_ind, summary) { + let info = this.columns[col_ind].info + if (!info) return + let html = '' + let rec = this.records[ind] + let el = query(this.box).find(`${summary ? '.w2ui-grid-summary' : ''} #grid_${this.name}_data_${ind}_${col_ind} .w2ui-info`) + if (this.last.bubbleEl) { + w2tooltip.hide(this.name + '-bubble') + } + this.last.bubbleEl = el + // if no fields defined - show all + if (info.fields == null) { + info.fields = [] + for (let i = 0; i < this.columns.length; i++) { + let col = this.columns[i] + info.fields.push(col.field + (typeof col.render == 'string' ? ':' + col.render : '')) + } + } + let fields = info.fields + if (typeof fields == 'function') { + fields = fields(rec, { self: this, index: ind, colIndex: col_ind, summary: !!summary }) // custom renderer + } + // generate html + if (typeof info.render == 'function') { + html = info.render(rec, { self: this, index: ind, colIndex: col_ind, summary: !!summary }) + } else if (Array.isArray(fields)) { + // display mentioned fields + html = '' + for (let i = 0; i < fields.length; i++) { + let tmp = String(fields[i]).split(':') + if (tmp[0] == '' || tmp[0] == '-' || tmp[0] == '--' || tmp[0] == '---') { + html += '' + continue + } + let col = this.getColumn(tmp[0]) + if (col == null) col = { field: tmp[0], caption: tmp[0] } // if not found in columns + let val = (col ? this.parseField(rec, col.field) : '') + if (tmp.length > 1) { + if (w2utils.formatters[tmp[1]]) { + val = w2utils.formatters[tmp[1]](val, tmp[2] || null, rec) + } else { + console.log('ERROR: w2utils.formatters["'+ tmp[1] + '"] does not exists.') + } + } + if (info.showEmpty !== true && (val == null || val == '')) continue + if (info.maxLength != null && typeof val == 'string' && val.length > info.maxLength) val = val.substr(0, info.maxLength) + '...' + html += '' + } + html += '
    ' + col.text + '' + ((val === 0 ? '0' : val) || '') + '
    ' + } else if (w2utils.isPlainObject(fields)) { + // display some fields + html = '' + for (let caption in fields) { + let fld = fields[caption] + if (fld == '' || fld == '-' || fld == '--' || fld == '---') { + html += '' + continue + } + let tmp = String(fld).split(':') + let col = this.getColumn(tmp[0]) + if (col == null) col = { field: tmp[0], caption: tmp[0] } // if not found in columns + let val = (col ? this.parseField(rec, col.field) : '') + if (tmp.length > 1) { + if (w2utils.formatters[tmp[1]]) { + val = w2utils.formatters[tmp[1]](val, tmp[2] || null, rec) + } else { + console.log('ERROR: w2utils.formatters["'+ tmp[1] + '"] does not exists.') + } + } + if (typeof fld == 'function') { + val = fld(rec, { self: this, index: ind, colIndex: col_ind, summary: !!summary }) + } + if (info.showEmpty !== true && (val == null || val == '')) continue + if (info.maxLength != null && typeof val == 'string' && val.length > info.maxLength) val = val.substr(0, info.maxLength) + '...' + html += '' + } + html += '
    ' + caption + '' + ((val === 0 ? '0' : val) || '') + '
    ' + } + return w2tooltip.show(w2utils.extend({ + name: this.name + '-bubble', + html, + anchor: el.get(0), + position: 'top|bottom', + class: 'w2ui-info-bubble', + style: '', + hideOn: ['doc-click'] + }, info.options ?? {})) + .hide(() => [ + this.last.bubbleEl = null + ]) + } + // return null or the editable object if the given cell is editable + getCellEditable(ind, col_ind) { + let col = this.columns[col_ind] + let rec = this.records[ind] + if (!rec || !col) return null + let edit = (rec.w2ui ? rec.w2ui.editable : null) + if (edit === false) return null + if (edit == null || edit === true) { + edit = (Object.keys(col.editable ?? {}).length > 0 ? col.editable : null) + if (typeof edit === 'function') { + let value = this.getCellValue(ind, col_ind, false) + // same arguments as col.render() + edit = edit.call(this, rec, { self: this, value, index: ind, colIndex: col_ind }) + } + } + return edit + } + getCellValue(ind, col_ind, summary, extra) { + let col = this.columns[col_ind] + let record = (summary !== true ? this.records[ind] : this.summary[ind]) + let value = this.parseField(record, col.field) + let className = '', style = '', attr = '', divAttr = '' + // if change by inline editing + if (record?.w2ui?.changes?.[col.field] != null) { + value = record.w2ui.changes[col.field] + } + // if there is a cell renderer + if (col.render != null && ind !== -1) { + if (typeof col.render == 'function' && record != null) { + let html + try { + html = col.render(record, { self: this, value, index: ind, colIndex: col_ind, summary: !!summary }) + } catch (e) { + throw new Error(`Render function for column "${col.field}" in grid "${this.name}": -- ` + e.message) + } + if (html != null && typeof html == 'object' && typeof html != 'function') { + if (html.id != null && html.text != null) { + // normalized menu kind of return + value = html.text + } else if (typeof html.html == 'string') { + value = (html.html || '').trim() + } else { + value = '' + console.log('ERROR: render function should return a primitive or an object of the following structure.', + { html: '', attr: '', style: '', class: '', divAttr: '' }) + } + attr = html.attr ?? '' + style = html.style ?? '' + className = html.class ?? '' + divAttr = html.divAttr ?? '' + } else { + value = String(html || '').trim() + } + } + // if it is an object + if (typeof col.render == 'object') { + let tmp = col.render[value] + if (tmp != null && tmp !== '') { + value = tmp + } + } + // formatters + if (typeof col.render == 'string') { + let strInd = col.render.toLowerCase().indexOf(':') + let tmp = [] + if (strInd == -1) { + tmp[0] = col.render.toLowerCase() + tmp[1] = '' + } else { + tmp[0] = col.render.toLowerCase().substr(0, strInd) + tmp[1] = col.render.toLowerCase().substr(strInd + 1) + } + // formatters + let func = w2utils.formatters[tmp[0]] + if (col.options && col.options.autoFormat === false) { + func = null + } + value = (typeof func == 'function' ? func(value, tmp[1], record) : '') + } + } + if (value == null) value = '' + return !extra ? value : { value, attr, style, className, divAttr } + } + getFooterHTML() { + return '
    '+ + ' '+ + ' '+ + ' '+ + '
    ' + } + status(msg) { + if (msg != null) { + query(this.box).find(`#grid_${this.name}_footer`).find('.w2ui-footer-left').html(msg) + } else { + // show number of selected + let msgLeft = '' + let sel = this.getSelection() + if (sel.length > 0) { + if (this.show.statusSelection && sel.length > 1) { + msgLeft = String(sel.length).replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1' + w2utils.settings.groupSymbol) + ' ' + w2utils.lang('selected') + } + if (this.show.statusRecordID && sel.length == 1) { + let tmp = sel[0] + if (typeof tmp == 'object') tmp = tmp.recid + ', '+ w2utils.lang('Column') +': '+ tmp.column + msgLeft = w2utils.lang('Record ID') + ': '+ tmp + ' ' + } + } + query(this.box).find('#grid_'+ this.name +'_footer .w2ui-footer-left').html(msgLeft) + } + } + lock(msg, showSpinner) { + let args = Array.from(arguments) + args.unshift(this.box) + setTimeout(() => { + // hide empty msg if any + query(this.box).find('#grid_'+ this.name +'_empty_msg').remove() + w2utils.lock(...args) + }, 10) + } + unlock(speed) { + setTimeout(() => { + // do not unlock if there is a message + if (query(this.box).find('.w2ui-message').hasClass('w2ui-closing')) return + w2utils.unlock(this.box, speed) + }, 25) // needed timer so if server fast, it will not flash + } + stateSave(returnOnly) { + let state = { + columns: [], + show: w2utils.clone(this.show), + last: { + search: this.last.search, + multi : this.last.multi, + logic : this.last.logic, + label : this.last.label, + field : this.last.field, + scrollTop : this.last.scrollTop, + scrollLeft: this.last.scrollLeft + }, + sortData : [], + searchData: [] + } + let prop_val + for (let i = 0; i < this.columns.length; i++) { + let col = this.columns[i] + let col_save_obj = {} + // iterate properties to save + Object.keys(this.stateColProps).forEach((prop, idx) => { + if (this.stateColProps[prop]){ + // check if the property is defined on the column + if (col[prop] !== undefined){ + prop_val = col[prop] + } else { + // use fallback or null + prop_val = this.colTemplate[prop] || null + } + col_save_obj[prop] = prop_val + } + }) + state.columns.push(col_save_obj) + } + for (let i = 0; i < this.sortData.length; i++) state.sortData.push(w2utils.clone(this.sortData[i])) + for (let i = 0; i < this.searchData.length; i++) state.searchData.push(w2utils.clone(this.searchData[i])) + // event before + let edata = this.trigger('stateSave', { target: this.name, state: state }) + if (edata.isCancelled === true) { + return + } + // save into local storage + if (returnOnly !== true) { + this.cacheSave('state', state) + } + // event after + edata.finish() + return state + } + stateRestore(newState) { + let url = (typeof this.url != 'object' ? this.url : this.url.get) + if (!newState) { + newState = this.cache('state') + } + // event before + let edata = this.trigger('stateRestore', { target: this.name, state: newState }) + if (edata.isCancelled === true) { + return + } + // default behavior + if (w2utils.isPlainObject(newState)) { + w2utils.extend(this.show, newState.show ?? {}) + w2utils.extend(this.last, newState.last ?? {}) + let sTop = this.last.scrollTop + let sLeft = this.last.scrollLeft + for (let c = 0; c < newState.columns?.length; c++) { + let tmp = newState.columns[c] + let col_index = this.getColumn(tmp.field, true) + if (col_index !== null) { + w2utils.extend(this.columns[col_index], tmp) + // restore column order from saved state + if (c !== col_index) this.columns.splice(c, 0, this.columns.splice(col_index, 1)[0]) + } + } + this.sortData.splice(0, this.sortData.length) + for (let c = 0; c < newState.sortData?.length; c++) { + this.sortData.push(newState.sortData[c]) + } + this.searchData.splice(0, this.searchData.length) + for (let c = 0; c < newState.searchData?.length; c++) { + this.searchData.push(newState.searchData[c]) + } + // apply sort and search + setTimeout(() => { + // needs timeout as records need to be populated + // ez 10.09.2014 this --> + if (!url) { + if (this.sortData.length > 0) this.localSort() + if (this.searchData.length > 0) this.localSearch() + } + this.last.scrollTop = sTop + this.last.scrollLeft = sLeft + this.refresh() + }, 1) + console.log(`INFO (w2ui): state restored for "${this.name}"`) + } + // event after + edata.finish() + return true + } + stateReset() { + this.stateRestore(this.last.state) + this.cacheSave('state', null) + } + parseField(obj, field) { + if (this.nestedFields) { + let val = '' + try { // need this to make sure no error in fields + val = obj + let tmp = String(field).split('.') + for (let i = 0; i < tmp.length; i++) { + val = val[tmp[i]] + } + } catch (event) { + val = '' + } + return val + } else { + return obj ? obj[field] : '' + } + } + prepareData() { + let obj = this + // loops thru records and prepares date and time objects + for (let r = 0; r < this.records.length; r++) { + let rec = this.records[r] + prepareRecord(rec) + } + // prepare date and time objects for the 'rec' record and its closed children + function prepareRecord(rec) { + for (let c = 0; c < obj.columns.length; c++) { + let column = obj.columns[c] + if (rec[column.field] == null || typeof column.render != 'string') continue + // number + if (['number', 'int', 'float', 'money', 'currency', 'percent'].indexOf(column.render.split(':')[0]) != -1) { + if (typeof rec[column.field] != 'number') rec[column.field] = parseFloat(rec[column.field]) + } + // date + if (['date', 'age'].indexOf(column.render.split(':')[0]) != -1) { + if (!rec[column.field + '_']) { + let dt = rec[column.field] + if (w2utils.isInt(dt)) dt = parseInt(dt) + rec[column.field + '_'] = new Date(dt) + } + } + // time + if (['time'].indexOf(column.render) != -1) { + if (w2utils.isTime(rec[column.field])) { // if string + let tmp = w2utils.isTime(rec[column.field], true) + let dt = new Date() + dt.setHours(tmp.hours, tmp.minutes, (tmp.seconds ? tmp.seconds : 0), 0) // sets hours, min, sec, mills + if (!rec[column.field + '_']) rec[column.field + '_'] = dt + } else { // if date object + let tmp = rec[column.field] + if (w2utils.isInt(tmp)) tmp = parseInt(tmp) + tmp = (tmp != null ? new Date(tmp) : new Date()) + let dt = new Date() + dt.setHours(tmp.getHours(), tmp.getMinutes(), tmp.getSeconds(), 0) // sets hours, min, sec, mills + if (!rec[column.field + '_']) rec[column.field + '_'] = dt + } + } + } + if (rec.w2ui?.children && rec.w2ui?.expanded !== true) { + // there are closed children, prepare them too. + for (let r = 0; r < rec.w2ui.children.length; r++) { + let subRec = rec.w2ui.children[r] + prepareRecord(subRec) + } + } + } + } + nextCell(index, col_ind, editable) { + let check = col_ind + 1 + if (check >= this.columns.length) { + index = this.nextRow(index) + return index == null ? index : this.nextCell(index, -1, editable) + } + let tmp = this.records[index].w2ui + let col = this.columns[check] + let span = (tmp && tmp.colspan && !isNaN(tmp.colspan[col.field]) ? parseInt(tmp.colspan[col.field]) : 1) + if (col == null) return null + if (col && col.hidden || span === 0) return this.nextCell(index, check, editable) + if (editable) { + let edit = this.getCellEditable(index, check) + if (edit == null || ['checkbox', 'check'].indexOf(edit.type) != -1) { + return this.nextCell(index, check, editable) + } + } + return { index, colIndex: check } + } + prevCell(index, col_ind, editable) { + let check = col_ind - 1 + if (check < 0) { + index = this.prevRow(index) + return index == null ? index : this.prevCell(index, this.columns.length, editable) + } + if (check < 0) return null + let tmp = this.records[index].w2ui + let col = this.columns[check] + let span = (tmp && tmp.colspan && !isNaN(tmp.colspan[col.field]) ? parseInt(tmp.colspan[col.field]) : 1) + if (col == null) return null + if (col && col.hidden || span === 0) return this.prevCell(index, check, editable) + if (editable) { + let edit = this.getCellEditable(index, check) + if (edit == null || ['checkbox', 'check'].indexOf(edit.type) != -1) { + return this.prevCell(index, check, editable) + } + } + return { index, colIndex: check } + } + nextRow(ind, col_ind, numRows) { + let sids = this.last.searchIds + let ret = null + if (numRows == null) numRows = 1 + if (numRows == -1) { + return this.records.length-1 + } + if ((ind + numRows < this.records.length && sids.length === 0) // if there are more records + || (sids.length > 0 && ind < sids[sids.length-numRows])) { + ind += numRows + if (sids.length > 0) while (true) { + if (sids.includes(ind) || ind > this.records.length) break + ind += numRows + } + // colspan + let tmp = this.records[ind].w2ui + let col = this.columns[col_ind] + let span = (tmp && tmp.colspan && col != null && !isNaN(tmp.colspan[col.field]) ? parseInt(tmp.colspan[col.field]) : 1) + if (span === 0) { + ret = this.nextRow(ind, col_ind, numRows) + } else { + ret = ind + } + } + return ret + } + prevRow(ind, col_ind, numRows) { + let sids = this.last.searchIds + let ret = null + if (numRows == null) numRows = 1 + if (numRows == -1) { + return 0 + } + if ((ind - numRows >= 0 && sids.length === 0) // if there are more records + || (sids.length > 0 && ind > sids[0])) { + ind -= numRows + if (sids.length > 0) while (true) { + if (sids.includes(ind) || ind < 0) break + ind -= numRows + } + // colspan + let tmp = this.records[ind].w2ui + let col = this.columns[col_ind] + let span = (tmp && tmp.colspan && col != null && !isNaN(tmp.colspan[col.field]) ? parseInt(tmp.colspan[col.field]) : 1) + if (span === 0) { + ret = this.prevRow(ind, col_ind, numRows) + } else { + ret = ind + } + } + return ret + } + selectionSave() { + this.last.saved_sel = this.getSelection() + return this.last.saved_sel + } + selectionRestore(noRefresh) { + let time = Date.now() + this.last.selection = { indexes: [], columns: {} } + let sel = this.last.selection + let lst = this.last.saved_sel + if (lst) for (let i = 0; i < lst.length; i++) { + if (w2utils.isPlainObject(lst[i])) { + // selectType: cell + let tmp = this.get(lst[i].recid, true) + if (tmp != null) { + if (sel.indexes.indexOf(tmp) == -1) sel.indexes.push(tmp) + if (!sel.columns[tmp]) sel.columns[tmp] = [] + sel.columns[tmp].push(lst[i].column) + } + } else { + // selectType: row + let tmp = this.get(lst[i], true) + if (tmp != null) sel.indexes.push(tmp) + } + } + delete this.last.saved_sel + if (noRefresh !== true) this.refresh() + return Date.now() - time + } + message(options) { + return w2utils.message({ + owner: this, + box : this.box, + after: '.w2ui-grid-header' + }, options) + } + confirm(options) { + return w2utils.confirm({ + owner: this, + box : this.box, + after: '.w2ui-grid-header' + }, options) + } +} + +/** + * Part of w2ui 2.0 library + * - Dependencies: mQuery, w2utils, w2base, w2tabs, w2toolbar, w2tooltip, w2field + * + * == TODO == + * - include delta on save + * - tabs below some fields (could already be implemented) + * - form with toolbar & tabs + * - promise for load, save, etc. + * + * == 2.0 changes + * - CSP - fixed inline events + * - removed jQuery dependency + * - better groups support tabs now + * - form.confirm - refactored + * - form.message - refactored + * - observeResize for the box + * - removed msgNotJSON, msgAJAXerror + * - applyFocus -> setFocus + * - getFieldValue(fieldName) = returns { curent, previous, original } + * - setFieldVallue(fieldName, value) + * - getValue(..., original) -- return original if any + * - added .hideErrors() + * - reuqest, save, submit - return promises + * - this.recid = null if no record needs to be pulled + * - remove form.multiplart + * - this.method - for saving only + */ + +class w2form extends w2base { + constructor(options) { + super(options.name) + this.name = null + this.header = '' + this.box = null // HTML element that hold this element + this.url = '' + this.method = null // if defined, it will be http method when saving + this.routeData = {} // data for dynamic routes + this.formURL = '' // url where to get form HTML + this.formHTML = '' // form HTML (might be loaded from the url) + this.page = 0 // current page + this.pageStyle = '' + this.recid = null // if not null, then load record + this.fields = [] + this.actions = {} + this.record = {} + this.original = null + this.dataType = null // only used when not null, otherwise from w2utils.settings.dataType + this.postData = {} + this.httpHeaders = {} + this.toolbar = {} // if not empty, then it is toolbar + this.tabs = {} // if not empty, then it is tabs object + this.style = '' + this.focus = 0 // focus first or other element + this.autosize = true // autosize, if false the container must have a height set + this.nestedFields = true // use field name containing dots as separator to look into object + this.tabindexBase = 0 // this will be added to the auto numbering + this.isGenerated = false + this.last = { + fetchCtrl: null, // last fetch AbortController + fetchOptions: null, // last fetch options + errors: [] + } + this.onRequest = null + this.onLoad = null + this.onValidate = null + this.onSubmit = null + this.onProgress = null + this.onSave = null + this.onChange = null + this.onInput = null + this.onRender = null + this.onRefresh = null + this.onResize = null + this.onDestroy = null + this.onAction = null + this.onToolbar = null + this.onError = null + this.msgRefresh = 'Loading...' + this.msgSaving = 'Saving...' + this.msgServerError = 'Server error' + this.ALL_TYPES = [ 'text', 'textarea', 'email', 'pass', 'password', 'int', 'float', 'money', 'currency', + 'percent', 'hex', 'alphanumeric', 'color', 'date', 'time', 'datetime', 'toggle', 'checkbox', 'radio', + 'check', 'checks', 'list', 'combo', 'enum', 'file', 'select', 'map', 'array', 'div', 'custom', 'html', + 'empty'] + this.LIST_TYPES = ['select', 'radio', 'check', 'checks', 'list', 'combo', 'enum'] + this.W2FIELD_TYPES = ['int', 'float', 'money', 'currency', 'percent', 'hex', 'alphanumeric', 'color', + 'date', 'time', 'datetime', 'list', 'combo', 'enum', 'file'] + // mix in options + w2utils.extend(this, options) + // remember items + let record = options.record + let original = options.original + let fields = options.fields + let toolbar = options.toolbar + let tabs = options.tabs + // extend items + Object.assign(this, { record: {}, original: null, fields: [], tabs: {}, toolbar: {}, handlers: [] }) + // preprocess fields + if (fields) { + let sub =_processFields(fields) + this.fields = sub.fields + if (!tabs && sub.tabs.length > 0) { + tabs = sub.tabs + } + } + // prepare tabs + if (Array.isArray(tabs)) { + w2utils.extend(this.tabs, { tabs: [] }) + for (let t = 0; t < tabs.length; t++) { + let tmp = tabs[t] + if (typeof tmp === 'object') { + this.tabs.tabs.push(tmp) + if (tmp.active === true) { + this.tabs.active = tmp.id + } + } else { + this.tabs.tabs.push({ id: tmp, text: tmp }) + } + } + } else { + w2utils.extend(this.tabs, tabs) + } + w2utils.extend(this.toolbar, toolbar) + for (let p in record) { // it is an object + if (w2utils.isPlainObject(record[p])) { + this.record[p] = w2utils.clone(record[p]) + } else { + this.record[p] = record[p] + } + } + for (let p in original) { // it is an object + if (w2utils.isPlainObject(original[p])) { + this.original[p] = w2utils.clone(original[p]) + } else { + this.original[p] = original[p] + } + } + // generate html if necessary + if (this.formURL !== '') { + fetch(this.formURL) + .then(resp => resp.text()) + .then(text => { + this.formHTML = text + this.isGenerated = true + if (this.box) this.render(this.box) + }) + } else if (!this.formURL && !this.formHTML) { + this.formHTML = this.generateHTML() + this.isGenerated = true + } else if (this.formHTML) { + this.isGenerated = true + } + // render if box specified + if (typeof this.box == 'string') this.box = query(this.box).get(0) + if (this.box) this.render(this.box) + function _processFields(fields) { + let newFields = [] + let tabs = [] + // if it is an object + if (w2utils.isPlainObject(fields)) { + let tmp = fields + fields = [] + Object.keys(tmp).forEach((key) => { + let fld = tmp[key] + if (fld.type == 'group') { + fld.text = key + if (w2utils.isPlainObject(fld.fields)) { + let tmp2 = fld.fields + fld.fields = [] + Object.keys(tmp2).forEach((key2) => { + let fld2 = tmp2[key2] + fld2.field = key2 + fld.fields.push(_process(fld2)) + }) + } + fields.push(fld) + } else if (fld.type == 'tab') { + // add tab + let tab = { id: key, text: key } + if (fld.style) { + tab.style = fld.style + } + tabs.push(tab) + // add page to fields + let sub = _processFields(fld.fields).fields + sub.forEach(fld2 => { + fld2.html = fld2.html || {} + fld2.html.page = tabs.length -1 + _process2(fld, fld2) + }) + fields.push(...sub) + } else { + fld.field = key + fields.push(_process(fld)) + } + }) + function _process(fld) { + let ignore = ['html'] + if (fld.html == null) fld.html = {} + Object.keys(fld).forEach((key => { + if (ignore.indexOf(key) != -1) return + if (['label', 'attr', 'style', 'text', 'span', 'page', 'column', 'anchor', + 'group', 'groupStyle', 'groupTitleStyle', 'groupCollapsible'].indexOf(key) != -1) { + fld.html[key] = fld[key] + delete fld[key] + } + })) + return fld + } + function _process2(fld, fld2) { + let ignore = ['style', 'html'] + Object.keys(fld).forEach((key => { + if (ignore.indexOf(key) != -1) return + if (['span', 'column', 'attr', 'text', 'label'].indexOf(key) != -1) { + if (fld[key] && !fld2.html[key]) { + fld2.html[key] = fld[key] + } + } + })) + } + } + // process groups + fields.forEach(field => { + if (field.type == 'group') { + // group properties + let group = { + group: field.text || '', + groupStyle: field.style || '', + groupTitleStyle: field.titleStyle || '', + groupCollapsible: field.collapsible === true ? true : false, + } + // loop through fields + if (Array.isArray(field.fields)) { + field.fields.forEach(gfield => { + let fld = w2utils.clone(gfield) + if (fld.html == null) fld.html = {} + w2utils.extend(fld.html, group) + Array('span', 'column', 'attr', 'label', 'page').forEach(key => { + if (fld.html[key] == null && field[key] != null) { + fld.html[key] = field[key] + } + }) + if (fld.field == null && fld.name != null) { + console.log('NOTICE: form field.name property is deprecated, please use field.field. Field ->', field) + fld.field = fld.name + } + newFields.push(fld) + }) + } + } else { + let fld = w2utils.clone(field) + if (fld.field == null && fld.name != null) { + console.log('NOTICE: form field.name property is deprecated, please use field.field. Field ->', field) + fld.field = fld.name + } + newFields.push(fld) + } + }) + return { fields: newFields, tabs } + } + } + get(field, returnIndex) { + if (arguments.length === 0) { + let all = [] + for (let f1 = 0; f1 < this.fields.length; f1++) { + if (this.fields[f1].field != null) all.push(this.fields[f1].field) + } + return all + } else { + for (let f2 = 0; f2 < this.fields.length; f2++) { + if (this.fields[f2].field == field) { + if (returnIndex === true) return f2; else return this.fields[f2] + } + } + return null + } + } + set(field, obj) { + for (let f = 0; f < this.fields.length; f++) { + if (this.fields[f].field == field) { + w2utils.extend(this.fields[f] , obj) + this.refresh(field) + return true + } + } + return false + } + getValue(field, original) { + if (this.nestedFields) { + let val = undefined + try { // need this to make sure no error in fields + let rec = original === true ? this.original : this.record + val = String(field).split('.').reduce((rec, i) => { return rec[i] }, rec) + } catch (event) { + } + return val + } else { + return this.record[field] + } + } + setValue(field, value) { + // will not refresh the form! + if (value === '' || value == null + || (Array.isArray(value) && value.length === 0) + || (w2utils.isPlainObject(value) && Object.keys(value).length == 0)) { + value = null + } + if (this.nestedFields) { + try { // need this to make sure no error in fields + let rec = this.record + String(field).split('.').map((fld, i, arr) => { + if (arr.length - 1 !== i) { + if (rec[fld]) rec = rec[fld]; else { rec[fld] = {}; rec = rec[fld] } + } else { + rec[fld] = value + } + }) + return true + } catch (event) { + return false + } + } else { + this.record[field] = value + return true + } + } + getFieldValue(name) { + let field = this.get(name) + if (field == null) return + let el = field.el + let previous = this.getValue(name) + let original = this.getValue(name, true) + // orginary input control + let current = el.value + // should not be set to '', incosistent logic + // if (previous == null) previous = '' + // clean extra chars + if (['int', 'float', 'percent', 'money', 'currency'].includes(field.type)) { + current = field.w2field.clean(current) + } + // radio list + if (['radio'].includes(field.type)) { + let selected = query(el).closest('div').find('input:checked').get(0) + if (selected) { + let item = field.options.items[query(selected).data('index')] + current = item.id + } else { + current = null + } + } + // single checkbox + if (['toggle', 'checkbox'].includes(field.type)) { + current = el.checked + } + // check list + if (['check', 'checks'].indexOf(field.type) !== -1) { + current = [] + let selected = query(el).closest('div').find('input:checked') + if (selected.length > 0) { + selected.each(el => { + let item = field.options.items[query(el).data('index')] + current.push(item.id) + }) + } + if (!Array.isArray(previous)) previous = [] + } + // lists + let selected = el._w2field?.selected // drop downs and other w2field objects + if (['list', 'enum', 'file'].includes(field.type) && selected) { + // TODO: check when w2field is refactored + let nv = selected + let cv = previous + if (Array.isArray(nv)) { + current = [] + for (let i = 0; i < nv.length; i++) current[i] = w2utils.clone(nv[i]) // clone array + } + if (Array.isArray(cv)) { + previous = [] + for (let i = 0; i < cv.length; i++) previous[i] = w2utils.clone(cv[i]) // clone array + } + if (w2utils.isPlainObject(nv)) { + current = w2utils.clone(nv) // clone object + } + if (w2utils.isPlainObject(cv)) { + previous = w2utils.clone(cv) // clone object + } + } + // map, array + if (['map', 'array'].includes(field.type)) { + current = (field.type == 'map' ? {} : []) + field.$el.parent().find('.w2ui-map-field').each(div => { + let key = query(div).find('.w2ui-map.key').val() + let value = query(div).find('.w2ui-map.value').val() + if (field.type == 'map') { + current[key] = value + } else { + current.push(value) + } + }) + } + return { current, previous, original } // current - in input, previous - in form.record, original - before form change + } + setFieldValue(name, value) { + let field = this.get(name) + if (field == null) return + let el = field.el + switch (field.type) { + case 'toggle': + case 'checkbox': + el.checked = value ? true : false + break + case 'radio': { + value = value?.id ?? value + let inputs = query(el).closest('div').find('input') + let items = field.options.items + items.forEach((it, ind) => { + if (it.id === value) { // need exact match so to match empty string and 0 + inputs.filter(`[data-index="${ind}"]`).prop('checked', true) + } + }) + break + } + case 'check': + case 'checks': { + if (!Array.isArray(value)) { + if (value != null) { + value = [value] + } else { + value = [] + } + } + value = value.map(val => val?.id ?? val) // convert if array of objects + let inputs = query(el).closest('div').find('input') + let items = field.options.items + items.forEach((it, ind) => { + inputs.filter(`[data-index="${ind}"]`).prop('checked', value.includes(it.id) ? true : false) + }) + break + } + case 'list': + case 'combo': + let item = value + // find item in options.items, if any + if (item?.id == null && Array.isArray(field.options?.items)) { + field.options.items.forEach(it => { + if (it.id === value) item = it + }) + } + // if item is found in field.options, update it in the this.records + if (item != value) { + this.setValue(field.name, item) + } + if (field.type == 'list') { + field.w2field.selected = item + field.w2field.refresh() + } else { + field.el.value = item?.text ?? value + } + break + case 'enum': + case 'file': { + if (!Array.isArray(value)) { + value = value != null ? [value] : [] + } + let items = [...value] + // find item in options.items, if any + let updated = false + items.forEach((item, ind) => { + if (item?.id == null && Array.isArray(field.options.items)) { + field.options.items.forEach(it => { + if (it.id == item) { + items[ind] = it + updated = true + } + }) + } + }) + if (updated) { + this.setValue(field.name, items) + } + field.w2field.selected = items + field.w2field.refresh() + break + } + case 'map': + case 'array': { + // init map + if (field.type == 'map' && (value == null || !w2utils.isPlainObject(value))) { + this.setValue(field.field, {}) + value = this.getValue(field.field) + } + if (field.type == 'array' && (value == null || !Array.isArray(value))) { + this.setValue(field.field, []) + value = this.getValue(field.field) + } + let container = query(field.el).parent().find('.w2ui-map-container') + field.el.mapRefresh(value, container) + break + } + case 'div': + case 'custom': + query(el).html(value) + break + case 'html': + case 'empty': + break + default: + // regular text fields + el.value = value ?? '' + break + } + } + show() { + let effected = [] + for (let a = 0; a < arguments.length; a++) { + let fld = this.get(arguments[a]) + if (fld && fld.hidden) { + fld.hidden = false + effected.push(fld.field) + } + } + if (effected.length > 0) this.refresh.apply(this, effected) + this.updateEmptyGroups() + return effected + } + hide() { + let effected = [] + for (let a = 0; a < arguments.length; a++) { + let fld = this.get(arguments[a]) + if (fld && !fld.hidden) { + fld.hidden = true + effected.push(fld.field) + } + } + if (effected.length > 0) this.refresh.apply(this, effected) + this.updateEmptyGroups() + return effected + } + enable() { + let effected = [] + for (let a = 0; a < arguments.length; a++) { + let fld = this.get(arguments[a]) + if (fld && fld.disabled) { + fld.disabled = false + effected.push(fld.field) + } + } + if (effected.length > 0) this.refresh.apply(this, effected) + return effected + } + disable() { + let effected = [] + for (let a = 0; a < arguments.length; a++) { + let fld = this.get(arguments[a]) + if (fld && !fld.disabled) { + fld.disabled = true + effected.push(fld.field) + } + } + if (effected.length > 0) this.refresh.apply(this, effected) + return effected + } + updateEmptyGroups() { + // hide empty groups + query(this.box).find('.w2ui-group').each((group) =>{ + if (isHidden(query(group).find('.w2ui-field'))) { + query(group).hide() + } else { + query(group).show() + } + }) + function isHidden($els) { + let flag = true + $els.each((el) => { + if (el.style.display != 'none') flag = false + }) + return flag + } + } + change() { + Array.from(arguments).forEach((field) => { + let tmp = this.get(field) + if (tmp.$el) tmp.$el.change() + }) + } + reload(callBack) { + let url = (typeof this.url !== 'object' ? this.url : this.url.get) + if (url && this.recid != null) { + // this.clear(); + return this.request(callBack) // returns promise + } else { + // this.refresh(); // no need to refresh + if (typeof callBack === 'function') callBack() + return new Promise(resolve => { resolve() }) // resolved promise + } + } + clear() { + if (arguments.length != 0) { + Array.from(arguments).forEach((field) => { + let rec = this.record + String(field).split('.').map((fld, i, arr) => { + if (arr.length - 1 !== i) rec = rec[fld]; else delete rec[fld] + }) + this.refresh(field) + }) + } else { + this.recid = null + this.record = {} + this.original = null + this.refresh() + this.hideErrors() + } + } + error(msg) { + // let the management of the error outside of the form + let edata = this.trigger('error', { + target: this.name, + message: msg, + fetchCtrl: this.last.fetchCtrl, + fetchOptions: this.last.fetchOptions + }) + if (edata.isCancelled === true) return + // need a time out because message might be already up) + setTimeout(() => { this.message(msg) }, 1) + // event after + edata.finish() + } + message(options) { + return w2utils.message({ + owner: this, + box : this.box, + after: '.w2ui-form-header' + }, options) + } + confirm(options) { + return w2utils.confirm({ + owner: this, + box : this.box, + after: '.w2ui-form-header' + }, options) + } + validate(showErrors) { + if (showErrors == null) showErrors = true + // validate before saving + let errors = [] + for (let f = 0; f < this.fields.length; f++) { + let field = this.fields[f] + if (this.getValue(field.field) == null) this.setValue(field.field, '') + if (['int', 'float', 'currency', 'money'].indexOf(field.type) != -1) { + let val = this.getValue(field.field) + let min = field.options.min + let max = field.options.max + if (min != null && val < min) { + errors.push({ field: field, error: w2utils.lang('Should be more than ${min}', { min }) }) + } + if (max != null && val > max) { + errors.push({ field: field, error: w2utils.lang('Should be less than ${max}', { max }) }) + } + } + switch (field.type) { + case 'alphanumeric': + if (this.getValue(field.field) && !w2utils.isAlphaNumeric(this.getValue(field.field))) { + errors.push({ field: field, error: w2utils.lang('Not alpha-numeric') }) + } + break + case 'int': + if (this.getValue(field.field) && !w2utils.isInt(this.getValue(field.field))) { + errors.push({ field: field, error: w2utils.lang('Not an integer') }) + } + break + case 'percent': + case 'float': + if (this.getValue(field.field) && !w2utils.isFloat(this.getValue(field.field))) { + errors.push({ field: field, error: w2utils.lang('Not a float') }) + } + break + case 'currency': + case 'money': + if (this.getValue(field.field) && !w2utils.isMoney(this.getValue(field.field))) { + errors.push({ field: field, error: w2utils.lang('Not in money format') }) + } + break + case 'color': + case 'hex': + if (this.getValue(field.field) && !w2utils.isHex(this.getValue(field.field))) { + errors.push({ field: field, error: w2utils.lang('Not a hex number') }) + } + break + case 'email': + if (this.getValue(field.field) && !w2utils.isEmail(this.getValue(field.field))) { + errors.push({ field: field, error: w2utils.lang('Not a valid email') }) + } + break + case 'checkbox': + // convert true/false + if (this.getValue(field.field) == true) { + this.setValue(field.field, true) + } else { + this.setValue(field.field, false) + } + break + case 'date': + // format date before submit + if (!field.options.format) field.options.format = w2utils.settings.dateFormat + if (this.getValue(field.field) && !w2utils.isDate(this.getValue(field.field), field.options.format)) { + errors.push({ field: field, error: w2utils.lang('Not a valid date') + ': ' + field.options.format }) + } + break + case 'list': + case 'combo': + break + case 'enum': + break + } + // === check required - if field is '0' it should be considered not empty + let val = this.getValue(field.field) + if (field.hidden !== true && field.required + && !['div', 'custom', 'html', 'empty'].includes(field.type) + && (val == null || val === '' || (Array.isArray(val) && val.length === 0) + || (w2utils.isPlainObject(val) && Object.keys(val).length == 0))) { + errors.push({ field: field, error: w2utils.lang('Required field') }) + } + if (field.hidden !== true && field.options?.minLength > 0 + && !['enum', 'list', 'combo'].includes(field.type) // since minLength is used there for other purpose + && (val == null || val.length < field.options.minLength)) { + errors.push({ field: field, error: w2utils.lang('Field should be at least ${count} characters.', + { count: field.options.minLength })}) + } + } + // event before + let edata = this.trigger('validate', { target: this.name, errors: errors }) + if (edata.isCancelled === true) return + // show error + this.last.errors = errors + if (showErrors) this.showErrors() + // event after + edata.finish() + return errors + } + showErrors() { + // TODO: check edge cases + // -- scroll + // -- invisible pages + // -- form refresh + let errors = this.last.errors + if (errors.length <= 0) return + // show errors + this.goto(errors[0].field.page) + query(errors[0].field.$el).parents('.w2ui-field')[0].scrollIntoView({ block: 'nearest', inline: 'nearest' }) + // show errors + // show only for visible controls + errors.forEach(error => { + let opt = w2utils.extend({ + anchorClass: 'w2ui-error', + class: 'w2ui-light', + position: 'right|left', + hideOn: ['input'] + }, error.options) + if (error.field == null) return + let anchor = error.field.el + if (error.field.type === 'radio') { // for radio and checkboxes + anchor = query(error.field.el).closest('div').get(0) + } else if (['enum', 'file'].includes(error.field.type)) { + // TODO: check + // anchor = (error.field.el).data('w2field').helpers.multi + // $(fld).addClass('w2ui-error') + } + w2tooltip.show(w2utils.extend({ + anchor, + name: `${this.name}-${error.field.field}-error`, + html: error.error + }, opt)) + }) + // hide errors on scroll + query(errors[0].field.$el).parents('.w2ui-page') + .off('.hideErrors') + .on('scroll.hideErrors', (evt) => { this.hideErrors() }) + } + hideErrors() { + this.fields.forEach(field => { + w2tooltip.hide(`${this.name}-${field.field}-error`) + }) + } + getChanges() { + // TODO: not working on nested structures + let diff = {} + if (this.original != null && typeof this.original == 'object' && Object.keys(this.record).length !== 0) { + diff = doDiff(this.record, this.original, {}) + } + return diff + function doDiff(record, original, result) { + if (Array.isArray(record) && Array.isArray(original)) { + while (record.length < original.length) { + record.push(null) + } + } + for (let i in record) { + if (record[i] != null && typeof record[i] === 'object') { + result[i] = doDiff(record[i], original[i] || {}, {}) + if (!result[i] || (Object.keys(result[i]).length == 0 && Object.keys(original[i].length == 0))) delete result[i] + } else if (record[i] != original[i] || (record[i] == null && original[i] != null)) { // also catch field clear + result[i] = record[i] + } + } + return Object.keys(result).length != 0 ? result : null + } + } + getCleanRecord(strict) { + let data = w2utils.clone(this.record) + this.fields.forEach((fld) => { + if (['list', 'combo', 'enum'].indexOf(fld.type) != -1) { + let tmp = { nestedFields: true, record: data } + let val = this.getValue.call(tmp, fld.field) + if (w2utils.isPlainObject(val) && val.id != null) { // should be true if val.id === '' + this.setValue.call(tmp, fld.field, val.id) + } + if (Array.isArray(val)) { + val.forEach((item, ind) => { + if (w2utils.isPlainObject(item) && item.id) { + val[ind] = item.id + } + }) + } + } + if (fld.type == 'map') { + let tmp = { nestedFields: true, record: data } + let val = this.getValue.call(tmp, fld.field) + if (val._order) delete val._order + } + if (fld.type == 'file') { + let tmp = { nestedFields: true, record: data } + let val = this.getValue.call(tmp, fld.field) ?? [] + val.forEach(v => { + delete v.file + delete v.modified + }) + this.setValue.call(tmp, fld.field, val) + } + }) + // return only records present in description + if (strict === true) { + Object.keys(data).forEach((key) => { + if (!this.get(key)) delete data[key] + }) + } + return data + } + request(postData, callBack) { // if (1) param then it is call back if (2) then postData and callBack + let self = this + let resolve, reject + let responseProm = new Promise((res, rej) => { resolve = res; reject = rej }) + // check for multiple params + if (typeof postData === 'function') { + callBack = postData + postData = null + } + if (postData == null) postData = {} + if (!this.url || (typeof this.url === 'object' && !this.url.get)) return + // build parameters list + let params = {} + // add list params + params.action = 'get' + params.recid = this.recid + params.name = this.name + // append other params + w2utils.extend(params, this.postData) + w2utils.extend(params, postData) + // event before + let edata = this.trigger('request', { target: this.name, url: this.url, httpMethod: 'GET', + postData: params, httpHeaders: this.httpHeaders }) + if (edata.isCancelled === true) return + // default action + this.record = {} + this.original = null + // call server to get data + this.lock(w2utils.lang(this.msgRefresh)) + let url = edata.detail.url + if (typeof url === 'object' && url.get) url = url.get + if (this.last.fetchCtrl) try { this.last.fetchCtrl.abort() } catch (e) {} + // process url with routeData + if (Object.keys(this.routeData).length != 0) { + let info = w2utils.parseRoute(url) + if (info.keys.length > 0) { + for (let k = 0; k < info.keys.length; k++) { + if (this.routeData[info.keys[k].name] == null) continue + url = url.replace((new RegExp(':'+ info.keys[k].name, 'g')), this.routeData[info.keys[k].name]) + } + } + } + url = new URL(url, location) + let fetchOptions = w2utils.prepareParams(url, { + method: edata.detail.httpMethod, + headers: edata.detail.httpHeaders, + body: edata.detail.postData + }, this.dataType) + this.last.fetchCtrl = new AbortController() + fetchOptions.signal = this.last.fetchCtrl.signal + this.last.fetchOptions = fetchOptions + fetch(url, fetchOptions) + .catch(processError) + .then((resp) => { + if (resp?.status != 200) { + // if resp is undefined, it means request was aborted + if (resp) processError(resp) + return + } + resp.json() + .catch(processError) + .then(data => { + // event before + let edata = self.trigger('load', { + target: self.name, + fetchCtrl: this.last.fetchCtrl, + fetchOptions: this.last.fetchOptions, + data + }) + if (edata.isCancelled === true) return + // for backward compatibility + if (data.error == null && data.status === 'error') { + data.error = true + } + // if data.record is not present, then assume that entire response is the record + if (!data.record) { + Object.assign(data, { record: w2utils.clone(data) }) + } + // server response error, not due to network issues + if (data.error === true) { + self.error(w2utils.lang(data.message ?? this.msgServerError)) + } else { + self.record = w2utils.clone(data.record) + } + // event after + self.unlock() + edata.finish() + self.refresh() + self.setFocus() + // call back + if (typeof callBack === 'function') callBack(data) + resolve(data) + }) + }) + // event after + edata.finish() + return responseProm + function processError(response) { + if (response.name === 'AbortError') { + // request was aborted by the form + return + } + self.unlock() + // trigger event + let edata2 = self.trigger('error', { response, fetchCtrl: self.last.fetchCtrl, fetchOptions: self.last.fetchOptions }) + if (edata2.isCancelled === true) return + // default behavior + if (response.status && response.status != 200) { + self.error(response.status + ': ' + response.statusText) + } else { + console.log('ERROR: Server request failed.', response, '. ', + 'Expected Response:', { error: false, record: { field1: 1, field2: 'item' }}, + 'OR:', { error: true, message: 'Error description' }) + self.error(String(response)) + } + // event after + edata2.finish() + reject(response) + } + } + submit(postData, callBack) { + return this.save(postData, callBack) + } + save(postData, callBack) { + let self = this + let resolve, reject + let saveProm = new Promise((res, rej) => { resolve = res; reject = rej }) + // check for multiple params + if (typeof postData === 'function') { + callBack = postData + postData = null + } + // validation + let errors = self.validate(true) + if (errors.length !== 0) return + // submit save + if (postData == null) postData = {} + if (!self.url || (typeof self.url === 'object' && !self.url.save)) { + console.log('ERROR: Form cannot be saved because no url is defined.') + return + } + self.lock(w2utils.lang(self.msgSaving) + ' ') + // build parameters list + let params = {} + // add list params + params.action = 'save' + params.recid = self.recid + params.name = self.name + // append other params + w2utils.extend(params, self.postData) + w2utils.extend(params, postData) + params.record = w2utils.clone(self.record) + // event before + let edata = self.trigger('submit', { target: self.name, url: self.url, httpMethod: this.method ?? 'POST', + postData: params, httpHeaders: self.httpHeaders }) + if (edata.isCancelled === true) return + // default action + let url = edata.detail.url + if (typeof url === 'object' && url.save) url = url.save + if (self.last.fetchCtrl) self.last.fetchCtrl.abort() + // process url with routeData + if (Object.keys(self.routeData).length > 0) { + let info = w2utils.parseRoute(url) + if (info.keys.length > 0) { + for (let k = 0; k < info.keys.length; k++) { + if (self.routeData[info.keys[k].name] == null) continue + url = url.replace((new RegExp(':'+ info.keys[k].name, 'g')), self.routeData[info.keys[k].name]) + } + } + } + url = new URL(url, location) + let fetchOptions = w2utils.prepareParams(url, { + method: edata.detail.httpMethod, + headers: edata.detail.httpHeaders, + body: edata.detail.postData + }, this.dataType) + this.last.fetchCtrl = new AbortController() + fetchOptions.signal = this.last.fetchCtrl.signal + this.last.fetchOptions = fetchOptions + fetch(url, fetchOptions) + .catch(processError) + .then(resp => { + self.unlock() + if (resp?.status != 200) { + processError(resp ?? {}) + return + } + // parse server response + resp.json() + .catch(processError) + .then(data => { + // event before + let edata = self.trigger('save', { + target: self.name, + fetchCtrl: this.last.fetchCtrl, + fetchOptions: this.last.fetchOptions, + data + }) + if (edata.isCancelled === true) return + // server error, not due to network issues + if (data.error === true) { + self.error(w2utils.lang(data.message ?? this.msgServerError)) + } else { + self.original = null + } + // event after + edata.finish() + self.refresh() + // call back + if (typeof callBack === 'function') callBack(data) + resolve(data) + }) + }) + // event after + edata.finish() + return saveProm + function processError(response) { + if (response?.name === 'AbortError') { + // request was aborted by the form + return + } + self.unlock() + // trigger event + let edata2 = self.trigger('error', { response, fetchCtrl: self.last.fetchCtrl, fetchOptions: self.last.fetchOptions }) + if (edata2.isCancelled === true) return + // default behavior + if (response.status && response.status != 200) { + self.error(response.status + ': ' + response.statusText) + } else { + console.log('ERROR: Server request failed.', response, '. ', + 'Expected Response:', { error: false, record: { field1: 1, field2: 'item' }}, + 'OR:', { error: true, message: 'Error description' }) + self.error(String(response)) + } + // event after + edata2.finish() + reject() + } + } + lock(msg, showSpinner) { + let args = Array.from(arguments) + args.unshift(this.box) + w2utils.lock(...args) + } + unlock(speed) { + let box = this.box + w2utils.unlock(box, speed) + } + lockPage(page, msg, spinner) { + let $page = query(this.box).find('.page-' + page) + if ($page.length){ + // page found + w2utils.lock($page, msg, spinner) + return true + } + // page with this id not found! + return false + } + unlockPage(page, speed) { + let $page = query(this.box).find('.page-' + page) + if ($page.length) { + // page found + w2utils.unlock($page, speed) + return true + } + // page with this id not found! + return false + } + goto(page) { + if (this.page === page) return // already on this page + if (page != null) this.page = page + // if it was auto size, resize it + if (query(this.box).data('autoSize') === true) { + query(this.box).get(0).clientHeight = 0 + } + this.refresh() + } + generateHTML() { + let pages = [] // array for each page + let group = '' + let page + let column + let html + let tabindex + let tabindex_str + for (let f = 0; f < this.fields.length; f++) { + html = '' + tabindex = this.tabindexBase + f + 1 + tabindex_str = ' tabindex="'+ tabindex +'"' + let field = this.fields[f] + if (field.html == null) field.html = {} + if (field.options == null) field.options = {} + if (field.html.caption != null && field.html.label == null) { + console.log('NOTICE: form field.html.caption property is deprecated, please use field.html.label. Field ->', field) + field.html.label = field.html.caption + } + if (field.html.label == null) field.html.label = field.field + field.html = w2utils.extend({ label: '', span: 6, attr: '', text: '', style: '', page: 0, column: 0 }, field.html) + if (page == null) page = field.html.page + if (column == null) column = field.html.column + // input control + let input = `` + switch (field.type) { + case 'pass': + case 'password': + input = input.replace('type="text"', 'type="password"') + break + case 'checkbox': { + input = ` + ` + break + } + case 'check': + case 'checks': { + if (field.options.items == null && field.html.items != null) field.options.items = field.html.items + let items = field.options.items + input = '' + // normalized options + if (!Array.isArray(items)) items = [] + if (items.length > 0) { + items = w2utils.normMenu.call(this, items, field) + } + // generate + for (let i = 0; i < items.length; i++) { + input += ` + +
    ` + } + break + } + case 'radio': { + input = '' + // normalized options + if (field.options.items == null && field.html.items != null) field.options.items = field.html.items + let items = field.options.items + if (!Array.isArray(items)) items = [] + if (items.length > 0) { + items = w2utils.normMenu.call(this, items, field) + } + // generate + for (let i = 0; i < items.length; i++) { + input += ` + +
    ` + } + break + } + case 'select': { + input = `' + break + } + case 'textarea': + input = `` + break + case 'toggle': + input = ` +
    ` + break + case 'map': + case 'array': + field.html.key = field.html.key || {} + field.html.value = field.html.value || {} + field.html.tabindex_str = tabindex_str + input = '' + (field.html.text || '') + '' + + ''+ + '
    ' + break + case 'div': + case 'custom': + input = '
    '+ + (field && field.html && field.html.html ? field.html.html : '') + + '
    ' + break + case 'html': + case 'empty': + input = (field && field.html ? (field.html.html || '') + (field.html.text || '') : '') + break + } + if (group !== '') { + if (page != field.html.page || column != field.html.column || (field.html.group && (group != field.html.group))) { + pages[page][column] += '\n
    \n
    ' + group = '' + } + } + if (field.html.group && (group != field.html.group)) { + let collapsible = '' + if (field.html.groupCollapsible) { + collapsible = '' + } + html += '\n
    ' + + '\n
    ' + + collapsible + w2utils.lang(field.html.group) + '
    \n' + + '
    ' + group = field.html.group + } + if (field.html.anchor == null) { + let span = (field.html.span != null ? 'w2ui-span'+ field.html.span : '') + if (field.html.span == -1) span = 'w2ui-span-none' + let label = '' + w2utils.lang(field.type != 'checkbox' ? field.html.label : field.html.text) +'' + if (!field.html.label) label = '' + html += '\n
    '+ + '\n '+ label + + ((field.type === 'empty') ? input : '\n
    '+ input + (field.type != 'array' && field.type != 'map' ? w2utils.lang(field.type != 'checkbox' ? field.html.text : '') : '') + '
    ') + + '\n
    ' + } else { + pages[field.html.page].anchors = pages[field.html.page].anchors || {} + pages[field.html.page].anchors[field.html.anchor] = '
    '+ + ((field.type === 'empty') ? input : '
    '+ w2utils.lang(field.type != 'checkbox' ? field.html.label : field.html.text, true) + input + w2utils.lang(field.type != 'checkbox' ? field.html.text : '') + '
    ') + + '
    ' + } + if (pages[field.html.page] == null) pages[field.html.page] = {} + if (pages[field.html.page][field.html.column] == null) pages[field.html.page][field.html.column] = '' + pages[field.html.page][field.html.column] += html + page = field.html.page + column = field.html.column + } + if (group !== '') pages[page][column] += '\n
    \n
    ' + if (this.tabs.tabs) { + for (let i = 0; i < this.tabs.tabs.length; i++) if (pages[i] == null) pages[i] = [] + } + // buttons if any + let buttons = '' + if (Object.keys(this.actions).length > 0) { + buttons += '\n
    ' + tabindex = this.tabindexBase + this.fields.length + 1 + for (let a in this.actions) { // it is an object + let act = this.actions[a] + let info = { text: '', style: '', 'class': '' } + if (w2utils.isPlainObject(act)) { + if (act.text == null && act.caption != null) { + console.log('NOTICE: form action.caption property is deprecated, please use action.text. Action ->', act) + act.text = act.caption + } + if (act.text) info.text = act.text + if (act.style) info.style = act.style + if (act.class) info.class = act.class + } else { + info.text = a + if (['save', 'update', 'create'].indexOf(a.toLowerCase()) !== -1) info.class = 'w2ui-btn-blue'; else info.class = '' + } + buttons += '\n ' + tabindex++ + } + buttons += '\n
    ' + } + html = '' + for (let p = 0; p < pages.length; p++){ + html += '
    ' + if (!pages[p]) { + console.log(`ERROR: Page ${p} does not exist`) + return false + } + if (pages[p].before) { + html += pages[p].before + } + html += '
    ' + Object.keys(pages[p]).sort().forEach((c, ind) => { + if (c == parseInt(c)) { + html += '
    ' + (pages[p][c] || '') + '\n
    ' + } + }) + html += '\n
    ' + if (pages[p].after) { + html += pages[p].after + } + html += '\n
    ' + // process page anchors + if (pages[p].anchors) { + Object.keys(pages[p].anchors).forEach((key, ind) => { + html = html.replace(key, pages[p].anchors[key]) + }) + } + } + html += buttons + return html + } + toggleGroup(groupName, show) { + let el = query(this.box).find('.w2ui-group-title[data-group="' + w2utils.base64encode(groupName) + '"]') + if (el.length === 0) return + let el_next = query(el.prop('nextElementSibling')) + if (typeof show === 'undefined') { + show = (el_next.css('display') == 'none') + } + if (show) { + el_next.show() + el.find('span').addClass('w2ui-icon-collapse').removeClass('w2ui-icon-expand') + } else { + el_next.hide() + el.find('span').addClass('w2ui-icon-expand').removeClass('w2ui-icon-collapse') + } + } + action(action, event) { + let act = this.actions[action] + let click = act + if (w2utils.isPlainObject(act) && act.onClick) click = act.onClick + // event before + let edata = this.trigger('action', { target: action, action: act, originalEvent: event }) + if (edata.isCancelled === true) return + // default actions + if (typeof click === 'function') click.call(this, event) + // event after + edata.finish() + } + resize() { + let self = this + // event before + let edata = this.trigger('resize', { target: this.name }) + if (edata.isCancelled === true) return + // default behaviour + let header = query(this.box).find(':scope > div .w2ui-form-header') + let toolbar = query(this.box).find(':scope > div .w2ui-form-toolbar') + let tabs = query(this.box).find(':scope > div .w2ui-form-tabs') + let page = query(this.box).find(':scope > div .w2ui-page') + let dpage = query(this.box).find(':scope > div .w2ui-page.page-'+ this.page + ' > div') + let buttons = query(this.box).find(':scope > div .w2ui-buttons') + // if no height, calculate it + let { headerHeight, tbHeight, tabsHeight } = resizeElements() + if (this.autosize) { // we don't need autosize every time + let cHeight = query(this.box).get(0).clientHeight + if (cHeight === 0 || query(this.box).data('autosize') == 'yes') { + query(this.box).css({ + height: headerHeight + tbHeight + tabsHeight + 15 // 15 is extra height + + (page.length > 0 ? w2utils.getSize(dpage, 'height') : 0) + + (buttons.length > 0 ? w2utils.getSize(buttons, 'height') : 0) + + 'px' + }) + query(this.box).data('autosize', 'yes') + } + resizeElements() + } + // event after + edata.finish() + function resizeElements() { + let headerHeight = (self.header !== '' ? w2utils.getSize(header, 'height') : 0) + let tbHeight = (Array.isArray(self.toolbar?.items) && self.toolbar?.items?.length > 0) + ? w2utils.getSize(toolbar, 'height') + : 0 + let tabsHeight = (Array.isArray(self.tabs?.tabs) && self.tabs?.tabs?.length > 0) + ? w2utils.getSize(tabs, 'height') + : 0 + // resize elements + toolbar.css({ top: headerHeight + 'px' }) + tabs.css({ top: headerHeight + tbHeight + 'px' }) + page.css({ + top: headerHeight + tbHeight + tabsHeight + 'px', + bottom: (buttons.length > 0 ? w2utils.getSize(buttons, 'height') : 0) + 'px' + }) + // return some params + return { headerHeight, tbHeight, tabsHeight } + } + } + refresh() { + let time = Date.now() + let self = this + if (!this.box) return + if (!this.isGenerated || !query(this.box).html()) return + // event before + let edata = this.trigger('refresh', { target: this.name, page: this.page, field: arguments[0], fields: arguments }) + if (edata.isCancelled === true) return + let fields = Array.from(this.fields.keys()) + if (arguments.length > 0) { + fields = Array.from(arguments) + .map((fld, ind) => { + if (typeof fld != 'string') console.log('ERROR: Arguments in refresh functions should be field names') + return this.get(fld, true) // get index of field + }) + .filter((fld, ind) => { + if (fld != null) return true; else return false + }) + } else { + // update field.page with page it belongs too + query(this.box).find('input, textarea, select').each(el => { + let name = (query(el).attr('name') != null ? query(el).attr('name') : query(el).attr('id')) + let field = this.get(name) + if (field) { + // find page + let div = query(el).closest('.w2ui-page') + if (div.length > 0) { + for (let i = 0; i < 100; i++) { + if (div.hasClass('page-'+i)) { field.page = i; break } + } + } + } + }) + // default action + query(this.box).find('.w2ui-page').hide() + query(this.box).find('.w2ui-page.page-' + this.page).show() + query(this.box).find('.w2ui-form-header').html(w2utils.lang(this.header)) + // refresh tabs if needed + if (typeof this.tabs === 'object' && Array.isArray(this.tabs.tabs) && this.tabs.tabs.length > 0) { + query(this.box).find('#form_'+ this.name +'_tabs').show() + this.tabs.active = this.tabs.tabs[this.page].id + this.tabs.refresh() + } else { + query(this.box).find('#form_'+ this.name +'_tabs').hide() + } + // refresh tabs if needed + if (typeof this.toolbar === 'object' && Array.isArray(this.toolbar.items) && this.toolbar.items.length > 0) { + query(this.box).find('#form_'+ this.name +'_toolbar').show() + this.toolbar.refresh() + } else { + query(this.box).find('#form_'+ this.name +'_toolbar').hide() + } + } + // refresh values of fields + for (let f = 0; f < fields.length; f++) { + let field = this.fields[fields[f]] + if (field.name == null && field.field != null) field.name = field.field + if (field.field == null && field.name != null) field.field = field.name + field.$el = query(this.box).find(`[name='${String(field.name).replace(/\\/g, '\\\\')}']`) + field.el = field.$el.get(0) + if (field.el) field.el.id = field.name + // TODO: check + if (field.w2field) { + field.w2field.reset() + } + field.$el + .off('.w2form') + .on('change.w2form', function(event) { + let value = self.getFieldValue(field.field) + // clear error class + if (['enum', 'file'].includes(field.type)) { + let helper = field.el._w2field?.helpers?.multi + query(helper).removeClass('w2ui-error') + } + if (this._previous != null) { + value.previous = this._previous + delete this._previous + } + // event before + let edata2 = self.trigger('change', { target: this.name, field: this.name, value, originalEvent: event }) + if (edata2.isCancelled === true) return + // default behavior + self.setValue(this.name, value.current) + // event after + edata2.finish() + }) + .on('input.w2form', function(event) { + // remember original + if (self.original == null) { + if (Object.keys(self.record).length > 0) { + self.original = w2utils.clone(self.record) + } else { + self.original = {} + } + } + let value = self.getFieldValue(field.field) + // save previous for change event + if (this._previous == null) { + this._previous = value.previous + } + // event before + let edata2 = self.trigger('input', { target: self.name, value, originalEvent: event }) + if (edata2.isCancelled === true) return + // default action + self.setValue(this.name, value.current) + // event after + edata2.finish() + }) + // required + if (field.required) { + field.$el.closest('.w2ui-field').addClass('w2ui-required') + } else { + field.$el.closest('.w2ui-field').removeClass('w2ui-required') + } + // disabled + if (field.disabled != null) { + if (field.disabled) { + if (field.$el.data('tabIndex') == null) { + field.$el.data('tabIndex', field.$el.prop('tabIndex')) + } + field.$el + .prop('readOnly', true) + .prop('disabled', true) + .prop('tabIndex', -1) + .closest('.w2ui-field') + .addClass('w2ui-disabled') + } else { + field.$el + .prop('readOnly', false) + .prop('disabled', false) + .prop('tabIndex', field.$el.data('tabIndex') ?? field.$el.prop('tabIndex') ?? 0) + .closest('.w2ui-field') + .removeClass('w2ui-disabled') + } + } + // hidden + let tmp = field.el + if (!tmp) tmp = query(this.box).find('#' + field.field) + if (field.hidden) { + query(tmp).closest('.w2ui-field').hide() + } else { + query(tmp).closest('.w2ui-field').show() + } + } + // attach actions on buttons + query(this.box).find('button, input[type=button]').each(el => { + query(el).off('click').on('click', function(event) { + let action = this.value + if (this.id) action = this.id + if (this.name) action = this.name + self.action(action, event) + }) + }) + // init controls with record + for (let f = 0; f < fields.length; f++) { + let field = this.fields[fields[f]] + if (!field.el) continue + if (!field.$el.hasClass('w2ui-input')) field.$el.addClass('w2ui-input') + field.type = String(field.type).toLowerCase() + if (!field.options) field.options = {} + // list type + if (this.LIST_TYPES.includes(field.type)) { + let items = field.options.items + if (items == null) field.options.items = [] + field.options.items = w2utils.normMenu.call(this, items, field) + } + // HTML select + if (field.type == 'select') { + // generate options + let items = field.options.items + let options = '' + items.forEach(item => { + options += `` + }) + field.$el.html(options) + } + // w2fields + if (this.W2FIELD_TYPES.includes(field.type)) { + field.w2field = field.w2field + ?? new w2field(w2utils.extend({}, field.options, { type: field.type })) + field.w2field.render(field.el) + } + // map and arrays + if (['map', 'array'].includes(field.type)) { + // need closure + (function (obj, field) { + let keepFocus + field.el.mapAdd = function(field, div, cnt) { + let attr = (field.disabled ? ' readOnly ' : '') + (field.html.tabindex_str || '') + let html = ` +
    + ${field.type == 'map' + ? ` + ${field.html.key.text || ''} + ` + : '' + } + + ${field.html.value.text || ''} +
    ` + div.append(html) + } + field.el.mapRefresh = function(map, div) { + // generate options + let keys, $k, $v + if (field.type == 'map') { + if (!w2utils.isPlainObject(map)) map = {} + if (map._order == null) map._order = Object.keys(map) + keys = map._order + } + if (field.type == 'array') { + if (!Array.isArray(map)) map = [] + keys = map.map((item, ind) => { return ind }) + } + // delete extra fields (including empty one) + let all = div.find('.w2ui-map-field') + for (let i = all.length-1; i >= keys.length; i--) { + div.find(`div[data-index='${i}']`).remove() + } + for (let ind = 0; ind < keys.length; ind++) { + let key = keys[ind] + let fld = div.find(`div[data-index='${ind}']`) + // add if does not exists + if (fld.length == 0) { + field.el.mapAdd(field, div, ind) + fld = div.find(`div[data-index='${ind}']`) + } + fld.attr('data-key', key) + $k = fld.find('.w2ui-map.key') + $v = fld.find('.w2ui-map.value') + let val = map[key] + if (field.type == 'array') { + let tmp = map.filter((it) => { return it.key == key ? true : false}) + if (tmp.length > 0) val = tmp[0].value + } + $k.val(key) + $v.val(val) + if (field.disabled === true || field.disabled === false) { + $k.prop('readOnly', field.disabled ? true : false) + $v.prop('readOnly', field.disabled ? true : false) + } + } + let cnt = keys.length + let curr = div.find(`div[data-index='${cnt}']`) + // if not disabled - add next if needed + if (curr.length === 0 && (!$k || $k.val() != '' || $v.val() != '') + && !($k && ($k.prop('readOnly') === true || $k.prop('disabled') === true)) + ) { + field.el.mapAdd(field, div, cnt) + } + if (field.disabled === true || field.disabled === false) { + curr.find('.key').prop('readOnly', field.disabled ? true : false) + curr.find('.value').prop('readOnly', field.disabled ? true : false) + } + // attach events + let container = query(field.el).get(0)?.nextSibling // should be div + query(container).find('input.w2ui-map') + .off('.mapChange') + .on('keyup.mapChange', function(event) { + let $div = query(event.target).closest('.w2ui-map-field') + let next = $div.get(0).nextElementSibling + let prev = $div.get(0).previousElementSibling + if (event.keyCode == 13) { + let el = keepFocus ?? next + if (el instanceof HTMLElement) { + let inp = query(el).find('input') + if (inp.length > 0) { + inp.get(0).focus() + } + } + keepFocus = undefined + } + let className = query(event.target).hasClass('key') ? 'key' : 'value' + if (event.keyCode == 38 && prev) { // up key + query(prev).find(`input.${className}`).get(0).select() + event.preventDefault() + } + if (event.keyCode == 40 && next) { // down key + query(next).find(`input.${className}`).get(0).select() + event.preventDefault() + } + }) + .on('keydown.mapChange', function(event) { + if (event.keyCode == 38 || event.keyCode == 40) { + event.preventDefault() + } + }) + .on('input.mapChange', function(event) { + let fld = query(event.target).closest('div') + let cnt = fld.data('index') + let next = fld.get(0).nextElementSibling + // if last one, add new empty + if (fld.find('input').val() != '' && !next) { + field.el.mapAdd(field, div, parseInt(cnt) + 1) + } else if (fld.find('input').val() == '' && next) { + let isEmpty = true + query(next).find('input').each(el => { + if (el.value != '') isEmpty = false + }) + if (isEmpty) { + query(next).remove() + } + } + }) + .on('change.mapChange', function(event) { + // remember original + if (self.original == null) { + if (Object.keys(self.record).length > 0) { + self.original = w2utils.clone(self.record) + } else { + self.original = {} + } + } + // event before + let { current, previous, original } = self.getFieldValue(field.field) + let $cnt = query(event.target).closest('.w2ui-map-container') + if (field.type == 'map') current._order = [] + $cnt.find('.w2ui-map.key').each(el => { current._order.push(el.value) }) + let edata = self.trigger('change', { target: field.field, field: field.field, originalEvent: event, + value: { current, previous, original } + }) + if (edata.isCancelled === true) { + return + } + // delete empty + if (field.type == 'map') { + current._order = current._order.filter(k => k !== '') + delete current[''] + } + if (field.type == 'array') { + current = current.filter(k => k !== '') + } + if (query(event.target).parent().find('input').val() == '') { + keepFocus = event.target + } + self.setValue(field.field, current) + field.el.mapRefresh(current, div) + // event after + edata.finish() + }) + } + })(this, field) + } + // set value to HTML input field + this.setFieldValue(field.field, this.getValue(field.name)) + } + // event after + edata.finish() + this.resize() + return Date.now() - time + } + render(box) { + let time = Date.now() + let self = this + if (typeof box == 'string') box = query(box).get(0) + // event before + let edata = this.trigger('render', { target: this.name, box: box ?? this.box }) + if (edata.isCancelled === true) return + // default action + if (box != null) { + // clean previous box + if (query(this.box).find('#form_'+ this.name +'_form').length > 0) { + query(this.box).removeAttr('name') + .removeClass('w2ui-reset w2ui-form') + .html('') + } + this.box = box + } + if (!this.isGenerated && !this.formHTML) return + if (!this.box) return + // render form + let html = '
    ' + + (this.header !== '' ? '
    ' + w2utils.lang(this.header) + '
    ' : '') + + ' ' + + ' ' + + this.formHTML + + '
    ' + query(this.box).attr('name', this.name) + .addClass('w2ui-reset w2ui-form') + .html(html) + if (query(this.box).length > 0) query(this.box)[0].style.cssText += this.style + w2utils.bindEvents(query(this.box).find('.w2ui-eaction'), this) + // init toolbar regardless it is defined or not + if (typeof this.toolbar.render !== 'function') { + this.toolbar = new w2toolbar(w2utils.extend({}, this.toolbar, { name: this.name +'_toolbar', owner: this })) + this.toolbar.on('click', function(event) { + let edata = self.trigger('toolbar', { target: event.target, originalEvent: event }) + if (edata.isCancelled === true) return + // no default action + edata.finish() + }) + } + if (typeof this.toolbar === 'object' && typeof this.toolbar.render === 'function') { + this.toolbar.render(query(this.box).find('#form_'+ this.name +'_toolbar')[0]) + } + // init tabs regardless it is defined or not + if (typeof this.tabs.render !== 'function') { + this.tabs = new w2tabs(w2utils.extend({}, this.tabs, { name: this.name +'_tabs', owner: this, active: this.tabs.active })) + this.tabs.on('click', function(event) { + self.goto(this.get(event.target, true)) + }) + } + if (typeof this.tabs === 'object' && typeof this.tabs.render === 'function') { + this.tabs.render(query(this.box).find('#form_'+ this.name +'_tabs')[0]) + if (this.tabs.active) this.tabs.click(this.tabs.active) + } + // event after + edata.finish() + // after render actions + this.resize() + let url = (typeof this.url !== 'object' ? this.url : this.url.get) + if (url && this.recid != null) { + this.request().catch(error => this.refresh()) // even if there was error, still need refresh + } else { + this.refresh() + } + // observe div resize + this.last.observeResize = new ResizeObserver(() => { this.resize() }) + this.last.observeResize.observe(this.box) + // focus on load + if (this.focus != -1) { + let setCount = 0 + let setFocus = () => { + if (query(self.box).find('input, select, textarea').length > 0) { + self.setFocus() + } else { + setCount++ + if (setCount < 20) setTimeout(setFocus, 50) // 1 sec max + } + } + setFocus() + } + return Date.now() - time + } + setFocus(focus) { + if (typeof focus === 'undefined'){ + // no argument - use form's focus property + focus = this.focus + } + let $input + // focus field by index + if (w2utils.isInt(focus)){ + if (focus < 0) { + return + } + let inputs = query(this.box) + .find('div:not(.w2ui-field-helper) > input, select, textarea, div > label:nth-child(1) > [type=radio]') + .filter(':not(.file-input)') + // find visible (offsetParent == null for any element is not visible) + while (inputs[focus].offsetParent == null && inputs.length >= focus) { + focus++ + } + if (inputs[focus]) { + $input = query(inputs[focus]) + } + } else if (typeof focus === 'string') { + // focus field by name + $input = query(this.box).find(`[name='${focus}']`) + } + if ($input.length > 0){ + $input.get(0).focus() + } + return $input + } + destroy() { + // event before + let edata = this.trigger('destroy', { target: this.name }) + if (edata.isCancelled === true) return + // clean up + if (typeof this.toolbar === 'object' && this.toolbar.destroy) this.toolbar.destroy() + if (typeof this.tabs === 'object' && this.tabs.destroy) this.tabs.destroy() + if (query(this.box).find('#form_'+ this.name +'_tabs').length > 0) { + query(this.box) + .removeAttr('name') + .removeClass('w2ui-reset w2ui-form') + .html('') + } + this.last.observeResize?.disconnect() + delete w2ui[this.name] + // event after + edata.finish() + } +} +/** + * Part of w2ui 2.0 library + * - Dependencies: mQuery, w2utils, w2base, w2tooltip, w2color, w2menu, w2date + * + * == TODO == + * - upload (regular files) + * - BUG with prefix/postfix and arrows (test in different contexts) + * - multiple date selection + * - month selection, year selections + * - MultiSelect - Allow Copy/Paste for single and multi values + * - add routeData to list/enum + * - ENUM, LIST: should have same as grid (limit, offset, search, sort) + * - ENUM, LIST: should support wild chars + * - add selection of predefined times (used for appointments) + * - options.items - can be an array + * - options.msgNoItems - can be a function + * - REMOTE fields + * + * == 2.0 changes + * - removed jQuery dependency + * - enum options.autoAdd + * - [numeric, date] - options.autoCorrect to enforce range and validity + * - silent only left for files, removed form the rest + * - remote source response items => records or just an array + * - deprecated "success" field for remote source response + * - CSP - fixed inline events + * - remove clear, use reset instead + * - options.msgSearch + * - options.msgNoItems + */ + +class w2field extends w2base { + constructor(type, options) { + super() + // sanitization + if (typeof type == 'string' && options == null) { + options = { type: type } + } + if (typeof type == 'object' && options == null) { + options = w2utils.clone(type) + } + if (typeof type == 'string' && typeof options == 'object') { + options.type = type + } + options.type = String(options.type).toLowerCase() + this.el = options.el ?? null + this.selected = null + this.helpers = {} // object or helper elements + this.type = options.type ?? 'text' + this.options = w2utils.clone(options) + this.onClick = options.onClick ?? null + this.onAdd = options.onAdd ?? null + this.onNew = options.onNew ?? null + this.onRemove = options.onRemove ?? null + this.onMouseEnter= options.onMouseEnter ?? null + this.onMouseLeave= options.onMouseLeave ?? null + this.onScroll = options.onScroll ?? null + this.tmp = {} // temp object + // clean up some options + delete this.options.type + delete this.options.onClick + delete this.options.onMouseEnter + delete this.options.onMouseLeave + delete this.options.onScroll + if (this.el) { + this.render(this.el) + } + } + render(el) { + if (!(el instanceof HTMLElement)) { + console.log('ERROR: Cannot init w2field on empty subject') + return + } + if (el._w2field) { + el._w2field.reset() + } else { + el._w2field = this + } + this.el = el + this.init() + } + init() { + let options = this.options + let defaults + // only for INPUT or TEXTAREA + if (!['INPUT', 'TEXTAREA'].includes(this.el.tagName.toUpperCase())) { + console.log('ERROR: w2field could only be applied to INPUT or TEXTAREA.', this.el) + return + } + switch (this.type) { + case 'text': + case 'int': + case 'float': + case 'money': + case 'currency': + case 'percent': + case 'alphanumeric': + case 'bin': + case 'hex': + defaults = { + min: null, + max: null, + step: 1, + autoFormat: true, + autoCorrect: true, + currencyPrefix: w2utils.settings.currencyPrefix, + currencySuffix: w2utils.settings.currencySuffix, + currencyPrecision: w2utils.settings.currencyPrecision, + decimalSymbol: w2utils.settings.decimalSymbol, + groupSymbol: w2utils.settings.groupSymbol, + arrow: false, + keyboard: true, + precision: null, + prefix: '', + suffix: '' + } + this.options = w2utils.extend({}, defaults, options) + options = this.options // since object is re-created, need to re-assign + options.numberRE = new RegExp('['+ options.groupSymbol + ']', 'g') + options.moneyRE = new RegExp('['+ options.currencyPrefix + options.currencySuffix + options.groupSymbol +']', 'g') + options.percentRE = new RegExp('['+ options.groupSymbol + '%]', 'g') + // no keyboard support needed + if (['text', 'alphanumeric', 'hex', 'bin'].includes(this.type)) { + options.arrow = false + options.keyboard = false + } + break + case 'color': + defaults = { + prefix : '#', + suffix : `
     
    `, + arrow : false, + advanced : null, // open advanced by default + transparent : true + } + this.options = w2utils.extend({}, defaults, options) + options = this.options // since object is re-created, need to re-assign + break + case 'date': + defaults = { + format : w2utils.settings.dateFormat, // date format + keyboard : true, + autoCorrect : true, + start : null, + end : null, + blockDates : [], // array of blocked dates + blockWeekdays : [], // blocked weekdays 0 - sunday, 1 - monday, etc + colored : {}, // ex: { '3/13/2022': 'bg-color|text-color' } + btnNow : true + } + this.options = w2utils.extend({ type: 'date' }, defaults, options) + options = this.options // since object is re-created, need to re-assign + if (query(this.el).attr('placeholder') == null) { + query(this.el).attr('placeholder', options.format) + } + break + case 'time': + defaults = { + format : w2utils.settings.timeFormat, + keyboard : true, + autoCorrect : true, + start : null, + end : null, + btnNow : true, + noMinutes : false + } + this.options = w2utils.extend({ type: 'time' }, defaults, options) + options = this.options // since object is re-created, need to re-assign + if (query(this.el).attr('placeholder') == null) { + query(this.el).attr('placeholder', options.format) + } + break + case 'datetime': + defaults = { + format : w2utils.settings.dateFormat + '|' + w2utils.settings.timeFormat, + keyboard : true, + autoCorrect : true, + start : null, + end : null, + startTime : null, + endTime : null, + blockDates : [], // array of blocked dates + blockWeekdays : [], // blocked weekdays 0 - sunday, 1 - monday, etc + colored : {}, // ex: { '3/13/2022': 'bg-color|text-color' } + btnNow : true, + noMinutes : false + } + this.options = w2utils.extend({ type: 'datetime' }, defaults, options) + options = this.options // since object is re-created, need to re-assign + if (query(this.el).attr('placeholder') == null) { + query(this.el).attr('placeholder', options.placeholder || options.format) + } + break + case 'list': + case 'combo': + defaults = { + items : [], + selected : {}, + url : null, // url to pull data from // TODO: implement + recId : null, // map retrieved data from url to id, can be string or function + recText : null, // map retrieved data from url to text, can be string or function + method : null, // default httpMethod + debounce : 250, // number of ms to wait before sending server call on search + postData : {}, + minLength : 1, // min number of chars when trigger search + cacheMax : 250, + maxDropHeight : 350, // max height for drop down menu + maxDropWidth : null, // if null then auto set + minDropWidth : null, // if null then auto set + match : 'begins', // ['contains', 'is', 'begins', 'ends'] + icon : null, + iconStyle : '', + align : 'both', // same width as control + altRows : true, // alternate row color + renderDrop : null, // render function for drop down item + compare : null, // compare function for filtering + filter : true, // weather to filter at all + hideSelected : false, // hide selected item from drop down + prefix : '', + suffix : '', + msgNoItems : 'No matches', + msgSearch : 'Type to search...', + openOnFocus : false, // if to show overlay onclick or when typing + markSearch : false, + onSearch : null, // when search needs to be performed + onRequest : null, // when request is submitted + onLoad : null, // when data is received + onError : null // when data fails to load due to server error or other failure modes + } + if (typeof options.items == 'function') { + options._items_fun = options.items + } + // need to be first + options.items = w2utils.normMenu.call(this, options.items) + if (this.type === 'list') { + // defaults.search = (options.items && options.items.length >= 10 ? true : false); + query(this.el).addClass('w2ui-select') + // if simple value - look it up + if (!w2utils.isPlainObject(options.selected) && Array.isArray(options.items)) { + options.items.forEach(item => { + if (item && item.id === options.selected) { + options.selected = w2utils.clone(item) + } + }) + } + } + options = w2utils.extend({}, defaults, options) + this.options = options + if (!w2utils.isPlainObject(options.selected)) options.selected = {} + this.selected = options.selected + query(this.el) + .attr('autocapitalize', 'off') + .attr('autocomplete', 'off') + .attr('autocorrect', 'off') + .attr('spellcheck', 'false') + if (options.selected.text != null) { + query(this.el).val(options.selected.text) + } + break + case 'enum': + defaults = { + items : [], // id, text, tooltip, icon + selected : [], + max : 0, // max number of selected items, 0 - unlimited + url : null, // not implemented + recId : null, // map retrieved data from url to id, can be string or function + recText : null, // map retrieved data from url to text, can be string or function + debounce : 250, // number of ms to wait before sending server call on search + method : null, // default httpMethod + postData : {}, + minLength : 1, // min number of chars when trigger search + cacheMax : 250, + maxItemWidth : 250, // max width for a single item + maxDropHeight : 350, // max height for drop down menu + maxDropWidth : null, // if null then auto set + match : 'contains', // ['contains', 'is', 'begins', 'ends'] + align : '', // align drop down related to search field + altRows : true, // alternate row color + openOnFocus : false, // if to show overlay onclick or when typing + markSearch : false, + renderDrop : null, // render function for drop down item + renderItem : null, // render selected item + compare : null, // compare function for filtering + filter : true, // alias for compare + hideSelected : true, // hide selected item from drop down + style : '', // style for container div + msgNoItems : 'No matches', + msgSearch : 'Type to search...', + onSearch : null, // when search needs to be performed + onRequest : null, // when request is submitted + onLoad : null, // when data is received + onError : null, // when data fails to load due to server error or other failure modes + onClick : null, // when an item is clicked + onAdd : null, // when an item is added + onNew : null, // when new item should be added + onRemove : null, // when an item is removed + onMouseEnter : null, // when an item is mouse over + onMouseLeave : null, // when an item is mouse out + onScroll : null // when div with selected items is scrolled + } + options = w2utils.extend({}, defaults, options, { suffix: '' }) + if (typeof options.items == 'function') { + options._items_fun = options.items + } + options.items = w2utils.normMenu.call(this, options.items) + options.selected = w2utils.normMenu.call(this, options.selected) + this.options = options + if (!Array.isArray(options.selected)) options.selected = [] + this.selected = options.selected + break + case 'file': + defaults = { + selected : [], + max : 0, + maxSize : 0, // max size of all files, 0 - unlimited + maxFileSize : 0, // max size of a single file, 0 -unlimited + maxItemWidth : 250, // max width for a single item + maxDropHeight : 350, // max height for drop down menu + maxDropWidth : null, // if null then auto set + readContent : true, // if true, it will readAsDataURL content of the file + silent : true, + align : 'both', // same width as control + altRows : true, // alternate row color + renderItem : null, // render selected item + style : '', // style for container div + onClick : null, // when an item is clicked + onAdd : null, // when an item is added + onRemove : null, // when an item is removed + onMouseEnter : null, // when an item is mouse over + onMouseLeave : null // when an item is mouse out + } + options = w2utils.extend({}, defaults, options) + this.options = options + if (!Array.isArray(options.selected)) options.selected = [] + this.selected = options.selected + if (query(this.el).attr('placeholder') == null) { + query(this.el).attr('placeholder', w2utils.lang('Attach files by dragging and dropping or Click to Select')) + } + break + } + // attach events + query(this.el) + .css('box-sizing', 'border-box') + .addClass('w2field w2ui-input') + .off('.w2field') + .on('change.w2field', (event) => { this.change(event) }) + .on('click.w2field', (event) => { this.click(event) }) + .on('focus.w2field', (event) => { this.focus(event) }) + .on('blur.w2field', (event) => { if (this.type !== 'list') this.blur(event) }) + .on('keydown.w2field', (event) => { this.keyDown(event) }) + .on('keyup.w2field', (event) => { this.keyUp(event) }) + // suffix and prefix need to be after styles + this.addPrefix() // only will add if needed + this.addSuffix() // only will add if needed + this.addSearch() + this.addMultiSearch() + // this.refresh() // do not call refresh, on change will trigger refresh (for list at list) + // format initial value + this.change(new Event('change')) + } + get() { + let ret + if (['list', 'enum', 'file'].indexOf(this.type) !== -1) { + ret = this.selected + } else { + ret = query(this.el).val() + } + return ret + } + set(val, append) { + if (['list', 'enum', 'file'].indexOf(this.type) !== -1) { + if (this.type !== 'list' && append) { + if (!Array.isArray(this.selected)) this.selected = [] + this.selected.push(val) + // update selected array in overlay + let overlay = w2menu.get(this.el.id + '_menu') + if (overlay) overlay.options.selected = this.selected + query(this.el).trigger('input').trigger('change') + } else { + if (val == null) val = [] + let it = (this.type === 'enum' && !Array.isArray(val) ? [val] : val) + this.selected = it + query(this.el).trigger('input').trigger('change') + } + this.refresh() + } else { + query(this.el).val(val) + } + } + setIndex(ind, append) { + if (['list', 'enum'].indexOf(this.type) !== -1) { + let items = this.options.items + if (items && items[ind]) { + if (this.type == 'list') { + this.selected = items[ind] + } + if (this.type == 'enum') { + if (!append) this.selected = [] + this.selected.push(items[ind]) + } + let overlay = w2menu.get(this.el.id + '_menu') + if (overlay) overlay.options.selected = this.selected + query(this.el).trigger('input').trigger('change') + this.refresh() + return true + } + } + return false + } + refresh() { + let options = this.options + let time = Date.now() + let styles = getComputedStyle(this.el) + // enum + if (this.type == 'list') { + query(this.el).parent().css('white-space', 'nowrap') // needs this for arrow always to appear on the right side + // hide focus and show text + if (this.helpers.prefix) this.helpers.prefix.hide() + if (!this.helpers.search) return + // if empty show no icon + if (this.selected == null && options.icon) { + options.prefix = ` + + ` + this.addPrefix() + } else { + options.prefix = '' + this.addPrefix() + } + // focus helper + let focus = query(this.helpers.search_focus) + let icon = query(focus[0].previousElementSibling) + focus.css({ outline: 'none' }) + if (focus.val() === '') { + focus.css('opacity', 0) + icon.css('opacity', 0) + if (this.selected?.id) { + let text = this.selected.text + let ind = this.findItemIndex(options.items, this.selected.id) + if (text != null) { + query(this.el) + .val(w2utils.lang(text)) + .data({ + selected: text, + selectedIndex: ind[0] + }) + } + } else { + this.el.value = '' + query(this.el).removeData('selected selectedIndex') + } + } else { + focus.css('opacity', 1) + icon.css('opacity', 1) + query(this.el).val('') + setTimeout(() => { + if (this.helpers.prefix) this.helpers.prefix.hide() + if (options.icon) { + focus.css('margin-left', '17px') + query(this.helpers.search).find('.w2ui-icon-search') + .addClass('show-search') + } else { + focus.css('margin-left', '0px') + query(this.helpers.search).find('.w2ui-icon-search') + .removeClass('show-search') + } + }, 1) + } + // if readonly or disabled + if (query(this.el).prop('readOnly') || query(this.el).prop('disabled')) { + setTimeout(() => { + if (this.helpers.prefix) query(this.helpers.prefix).css('opacity', '0.6') + if (this.helpers.suffix) query(this.helpers.suffix).css('opacity', '0.6') + }, 1) + } else { + setTimeout(() => { + if (this.helpers.prefix) query(this.helpers.prefix).css('opacity', '1') + if (this.helpers.suffix) query(this.helpers.suffix).css('opacity', '1') + }, 1) + } + } + let div = this.helpers.multi + if (['enum', 'file'].includes(this.type) && div) { + let html = '' + if (Array.isArray(this.selected)) { + this.selected.forEach((it, ind) => { + if (it == null) return + html += ` +
    + ${ + typeof options.renderItem === 'function' + ? options.renderItem(it, ind, `
      
    `) + : ` + ${it.icon ? `` : ''} +
      
    + ${(this.type === 'enum' ? it.text : it.name) ?? it.id ?? it } + ${it.size ? ` - ${w2utils.formatSize(it.size)}` : ''} + ` + } +
    ` + }) + } + let ul = div.find('.w2ui-multi-items') + if (options.style) { + div.attr('style', div.attr('style') + ';' + options.style) + } + query(this.el).css('z-index', '-1') + if (query(this.el).prop('readOnly') || query(this.el).prop('disabled')) { + setTimeout(() => { + div[0].scrollTop = 0 // scroll to the top + div.addClass('w2ui-readonly') + .find('.li-item').css('opacity', '0.9') + .parent().find('.li-search').hide() + .find('input').prop('readOnly', true) + .closest('.w2ui-multi-items') + .find('.w2ui-list-remove').hide() + }, 1) + } else { + setTimeout(() => { + div.removeClass('w2ui-readonly') + .find('.li-item').css('opacity', '1') + .parent().find('.li-search').show() + .find('input').prop('readOnly', false) + .closest('.w2ui-multi-items') + .find('.w2ui-list-remove').show() + }, 1) + } + // clean + if (this.selected?.length > 0) { + query(this.el).attr('placeholder', '') + } + div.find('.w2ui-enum-placeholder').remove() + ul.find('.li-item').remove() + // add new list + if (html !== '') { + ul.prepend(html) + } else if (query(this.el).attr('placeholder') != null && div.find('input').val() === '') { + let style = w2utils.stripSpaces(` + padding-top: ${styles['padding-top']}; + padding-left: ${styles['padding-left']}; + box-sizing: ${styles['box-sizing']}; + line-height: ${styles['line-height']}; + font-size: ${styles['font-size']}; + font-family: ${styles['font-family']}; + `) + div.prepend(`
    ${query(this.el).attr('placeholder')}
    `) + } + // ITEMS events + div.off('.w2item') + .on('scroll.w2item', (event) => { + let edata = this.trigger('scroll', { target: this.el, originalEvent: event }) + if (edata.isCancelled === true) return + // hide tooltip if any + w2tooltip.hide(this.el.id + '_preview') + // event after + edata.finish() + }) + .find('.li-item') + .on('click.w2item', (event) => { + let target = query(event.target).closest('.li-item') + let index = target.attr('index') + let item = this.selected[index] + if (query(target).hasClass('li-search')) return + event.stopPropagation() + let edata + // default behavior + if (query(event.target).hasClass('w2ui-list-remove')) { + if (query(this.el).prop('readOnly') || query(this.el).prop('disabled')) return + // trigger event + edata = this.trigger('remove', { target: this.el, originalEvent: event, item }) + if (edata.isCancelled === true) return + // default behavior + this.selected.splice(index, 1) + query(this.el).trigger('input').trigger('change') + query(event.target).remove() + } else { + // trigger event + edata = this.trigger('click', { target: this.el, originalEvent: event.originalEvent, item }) + if (edata.isCancelled === true) return + // if file - show image preview + let preview = item.tooltip + if (this.type === 'file') { + if ((/image/i).test(item.type)) { // image + preview = ` +
    + +
    ` + } + preview += ` +
    +
    ${w2utils.lang('Name')}:
    +
    ${item.name}
    +
    ${w2utils.lang('Size')}:
    +
    ${w2utils.formatSize(item.size)}
    +
    ${w2utils.lang('Type')}:
    +
    ${item.type}
    +
    ${w2utils.lang('Modified')}:
    +
    ${w2utils.date(item.modified)}
    +
    ` + } + if (preview) { + let name = this.el.id + '_preview' + w2tooltip.show({ + name, + anchor: target.get(0), + html: preview, + hideOn: ['doc-click'], + class: '' + }) + .show((event) => { + let $img = query(`#w2overlay-${name} img`) + $img.on('load', function (event) { + let w = this.clientWidth + let h = this.clientHeight + if (w < 300 & h < 300) return + if (w >= h && w > 300) query(this).css('width', '300px') + if (w < h && h > 300) query(this).css('height', '300px') + }) + .on('error', function (event) { + this.style.display = 'none' + }) + }) + } + edata.finish() + } + }) + .on('mouseenter.w2item', (event) => { + let target = query(event.target).closest('.li-item') + if (query(target).hasClass('li-search')) return + let item = this.selected[query(event.target).attr('index')] + // trigger event + let edata = this.trigger('mouseEnter', { target: this.el, originalEvent: event, item }) + if (edata.isCancelled === true) return + // event after + edata.finish() + }) + .on('mouseleave.w2item', (event) => { + let target = query(event.target).closest('.li-item') + if (query(target).hasClass('li-search')) return + let item = this.selected[query(event.target).attr('index')] + // trigger event + let edata = this.trigger('mouseLeave', { target: this.el, originalEvent: event, item }) + if (edata.isCancelled === true) return + // event after + edata.finish() + }) + // update size for enum, hide for file + if (this.type === 'enum') { + let search = this.helpers.multi.find('input') + search.css({ width: '15px' }) + } else { + this.helpers.multi.find('.li-search').hide() + } + this.resize() + } + return Date.now() - time + } + // resizing width of list, enum, file controls + resize() { + let width = this.el.clientWidth + // let height = this.el.clientHeight + // if (this.tmp.current_width == width && height > 0) return + let styles = getComputedStyle(this.el) + let focus = this.helpers.search + let multi = this.helpers.multi + let suffix = this.helpers.suffix + let prefix = this.helpers.prefix + // resize helpers + if (focus) { + query(focus).css('width', width) + } + if (multi) { + query(multi).css('width', width - parseInt(styles['margin-left'], 10) - parseInt(styles['margin-right'], 10)) + } + if (suffix) { + this.addSuffix() + } + if (prefix) { + this.addPrefix() + } + // enum or file + let div = this.helpers.multi + if (['enum', 'file'].includes(this.type) && div) { + // adjust height + query(this.el).css('height', 'auto') + let cntHeight = query(div).find(':scope div.w2ui-multi-items').get(0).clientHeight + 5 + if (cntHeight < 20) cntHeight = 20 + // max height + if (cntHeight > this.tmp['max-height']) { + cntHeight = this.tmp['max-height'] + } + // min height + if (cntHeight < this.tmp['min-height']) { + cntHeight = this.tmp['min-height'] + } + let inpHeight = w2utils.getSize(this.el, 'height') - 2 + if (inpHeight > cntHeight) cntHeight = inpHeight + query(div).css({ + 'height': cntHeight + 'px', + overflow: (cntHeight == this.tmp['max-height'] ? 'auto' : 'hidden') + }) + query(div).css('height', cntHeight + 'px') + query(this.el).css({ 'height': cntHeight + 'px' }) + } + // remember width + this.tmp.current_width = width + } + reset() { + // restore paddings + if (this.tmp != null) { + query(this.el).css('height', 'auto') + Array('padding-left', 'padding-right', 'background-color', 'border-color').forEach(prop => { + if (this.tmp && this.tmp['old-'+ prop] != null) { + query(this.el).css(prop, this.tmp['old-' + prop]) + delete this.tmp['old-' + prop] + } + }) + // remove resize watcher + clearInterval(this.tmp.sizeTimer) + } + // remove events and (data) + query(this.el) + .val(this.clean(query(this.el).val())) + .removeClass('w2field') + .removeData('selected selectedIndex') + .off('.w2field') // remove only events added by w2field + // remove helpers + Object.keys(this.helpers).forEach(key => { + query(this.helpers[key]).remove() + }) + this.helpers = {} + } + clean(val) { + // issue #499 + if (typeof val === 'number'){ + return val + } + let options = this.options + val = String(val).trim() + // clean + if (['int', 'float', 'money', 'currency', 'percent'].includes(this.type)) { + if (typeof val === 'string') { + if (options.autoFormat) { + if (['money', 'currency'].includes(this.type)) { + val = String(val).replace(options.moneyRE, '') + } + if (this.type === 'percent') { + val = String(val).replace(options.percentRE, '') + } + if (['int', 'float'].includes(this.type)) { + val = String(val).replace(options.numberRE, '') + } + } + val = val.replace(/\s+/g, '') + .replace(new RegExp(options.groupSymbol, 'g'), '') + .replace(options.decimalSymbol, '.') + } + if (val !== '' && w2utils.isFloat(val)) val = Number(val); else val = '' + } + return val + } + format(val) { + let options = this.options + // auto format numbers or money + if (options.autoFormat && val !== '') { + switch (this.type) { + case 'money': + case 'currency': + val = w2utils.formatNumber(val, options.currencyPrecision, true) + if (val !== '') val = options.currencyPrefix + val + options.currencySuffix + break + case 'percent': + val = w2utils.formatNumber(val, options.precision, true) + if (val !== '') val += '%' + break + case 'float': + val = w2utils.formatNumber(val, options.precision, true) + break + case 'int': + val = w2utils.formatNumber(val, 0, true) + break + } + // if default group symbol does not match - replase it + let group = parseInt(1000).toLocaleString(w2utils.settings.locale, { useGrouping: true }).slice(1, 2) + if (group !== this.options.groupSymbol) { + val = val.replaceAll(group, this.options.groupSymbol) + } + } + return val + } + change(event) { + // numeric + if (['int', 'float', 'money', 'currency', 'percent'].indexOf(this.type) !== -1) { + // check max/min + let val = query(this.el).val() + let new_val = this.format(this.clean(query(this.el).val())) + // if was modified + if (val !== '' && val != new_val) { + query(this.el).val(new_val) + // cancel event + event.stopPropagation() + event.preventDefault() + return false + } + } + // color + if (this.type === 'color') { + let color = query(this.el).val() + if (color.substr(0, 3).toLowerCase() !== 'rgb') { + color = '#' + color + let len = query(this.el).val().length + if (len !== 8 && len !== 6 && len !== 3) color = '' + } + let next = query(this.el).get(0).nextElementSibling + query(next).find('div').css('background-color', color) + if (query(this.el).hasClass('has-focus')) { + this.updateOverlay() + } + } + // list, enum + if (['list', 'enum', 'file'].indexOf(this.type) !== -1) { + this.refresh() + } + // date, time + if (['date', 'time', 'datetime'].indexOf(this.type) !== -1) { + // convert linux timestamps + let tmp = parseInt(this.el.value) + if (w2utils.isInt(this.el.value) && tmp > 3000) { + if (this.type === 'time') tmp = w2utils.formatTime(new Date(tmp), this.options.format) + if (this.type === 'date') tmp = w2utils.formatDate(new Date(tmp), this.options.format) + if (this.type === 'datetime') tmp = w2utils.formatDateTime(new Date(tmp), this.options.format) + query(this.el).val(tmp).trigger('input').trigger('change') + } + } + } + click(event) { + // lists + if (['list', 'combo', 'enum'].includes(this.type)) { + if (!query(this.el).hasClass('has-focus')) { + this.focus(event) + } + if (this.type == 'combo') { + this.updateOverlay() + } + // since list has separate search input, in order to keep the overlay open, need to stop + if (this.type == 'list') { + this.updateOverlay() + event.stopPropagation() + } + } + // other fields with drops + if (['date', 'time', 'datetime', 'color'].includes(this.type)) { + this.updateOverlay() + } + } + focus(event) { + if (this.type == 'list' && document.activeElement == this.el) { + this.helpers.search_focus.focus() + return + } + // color, date, time + if (['color', 'date', 'time', 'datetime'].indexOf(this.type) !== -1) { + if (query(this.el).prop('readOnly') || query(this.el).prop('disabled')) return + this.updateOverlay() + } + // menu + if (['list', 'combo', 'enum'].indexOf(this.type) !== -1) { + if (query(this.el).prop('readOnly') || query(this.el).prop('disabled')) { + // still add focus + query(this.el).addClass('has-focus') + return + } + // regenerate items + if (typeof this.options._items_fun == 'function') { + this.options.items = w2utils.normMenu.call(this, this.options._items_fun) + } + if (this.helpers.search) { + let search = this.helpers.search_focus + search.value = '' + search.select() + } + if (this.type == 'enum') { + // file control in particular need to receive focus after file select + let search = query(this.el.previousElementSibling).find('.li-search input').get(0) + if (document.activeElement !== search) { + search.focus() + } + } + this.resize() + // update overlay if needed + if (event.showMenu !== false && (this.options.openOnFocus !== false || query(this.el).hasClass('has-focus'))) { + setTimeout(() => { this.updateOverlay() }, 100) // execute at the end of event loop + } + } + if (this.type == 'file') { + let prev = query(this.el).get(0).previousElementSibling + query(prev).addClass('has-focus') + } + query(this.el).addClass('has-focus') + } + blur(event) { + let val = query(this.el).val().trim() + query(this.el).removeClass('has-focus') + if (['int', 'float', 'money', 'currency', 'percent'].includes(this.type)) { + if (val !== '') { + let newVal = val + let error = '' + if (!this.isStrValid(val)) { // validity is also checked in blur + newVal = '' + } else { + let rVal = this.clean(val) + if (this.options.min != null && rVal < this.options.min) { + newVal = this.options.min + error = `Should be >= ${this.options.min}` + } + if (this.options.max != null && rVal > this.options.max) { + newVal = this.options.max + error = `Should be <= ${this.options.max}` + } + } + if (this.options.autoCorrect) { + query(this.el).val(newVal).trigger('input').trigger('change') + if (error) { + w2tooltip.show({ + name: this.el.id + '_error', + anchor: this.el, + html: error + }) + setTimeout(() => { w2tooltip.hide(this.el.id + '_error') }, 3000) + } + } + } + } + // date or time + if (['date', 'time', 'datetime'].includes(this.type) && this.options.autoCorrect) { + if (val !== '') { + let check = this.type == 'date' ? w2utils.isDate : + (this.type == 'time' ? w2utils.isTime : w2utils.isDateTime) + if (!w2date.inRange(this.el.value, this.options) + || !check.bind(w2utils)(this.el.value, this.options.format)) { + // if not in range or wrong value - clear it + query(this.el).val('').trigger('input').trigger('change') + } + } + } + // clear search input + if (this.type === 'enum') { + query(this.helpers.multi).find('input').val('').css('width', '15px') + } + if (this.type == 'file') { + let prev = this.el.previousElementSibling + query(prev).removeClass('has-focus') + } + if (this.type === 'list') { + this.el.value = this.selected?.text ?? '' + } + } + keyDown(event, extra) { + let options = this.options + let key = event.keyCode || (extra && extra.keyCode) + let cancel = false + let val, inc, daymil, dt, newValue, newDT + // ignore wrong pressed key + if (['int', 'float', 'money', 'currency', 'percent', 'hex', 'bin', 'color', 'alphanumeric'].includes(this.type)) { + if (!event.metaKey && !event.ctrlKey && !event.altKey) { + if (!this.isStrValid(event.key ?? '1', true) && // valid & is not arrows, dot, comma, etc keys + ![9, 8, 13, 27, 37, 38, 39, 40, 46].includes(event.keyCode)) { + event.preventDefault() + if (event.stopPropagation) event.stopPropagation(); else event.cancelBubble = true + return false + } + } + } + // numeric + if (['int', 'float', 'money', 'currency', 'percent'].includes(this.type)) { + if (!options.keyboard || query(this.el).prop('readOnly') || query(this.el).prop('disabled')) return + val = parseFloat(query(this.el).val().replace(options.moneyRE, '')) || 0 + inc = options.step + if (event.ctrlKey || event.metaKey) inc = options.step * 10 + switch (key) { + case 38: // up + if (event.shiftKey) break // no action if shift key is pressed + newValue = (val + inc <= options.max || options.max == null ? Number((val + inc).toFixed(12)) : options.max) + query(this.el).val(newValue).trigger('input').trigger('change') + cancel = true + break + case 40: // down + if (event.shiftKey) break // no action if shift key is pressed + newValue = (val - inc >= options.min || options.min == null ? Number((val - inc).toFixed(12)) : options.min) + query(this.el).val(newValue).trigger('input').trigger('change') + cancel = true + break + } + if (cancel) { + event.preventDefault() + this.moveCaret2end() + } + } + // date/datetime + if (['date', 'datetime'].includes(this.type)) { + if (!options.keyboard || query(this.el).prop('readOnly') || query(this.el).prop('disabled')) return + let is = (this.type == 'date' ? w2utils.isDate : w2utils.isDateTime).bind(w2utils) + let format = (this.type == 'date' ? w2utils.formatDate : w2utils.formatDateTime).bind(w2utils) + daymil = 24*60*60*1000 + inc = 1 + if (event.ctrlKey || event.metaKey) inc = 10 // by month + dt = is(query(this.el).val(), options.format, true) + if (!dt) { dt = new Date(); daymil = 0 } + switch (key) { + case 38: // up + if (event.shiftKey) break // no action if shift key is pressed + if (inc == 10) { + dt.setMonth(dt.getMonth() + 1) + } else { + dt.setTime(dt.getTime() + daymil) + } + newDT = format(dt.getTime(), options.format) + query(this.el).val(newDT).trigger('input').trigger('change') + cancel = true + break + case 40: // down + if (event.shiftKey) break // no action if shift key is pressed + if (inc == 10) { + dt.setMonth(dt.getMonth() - 1) + } else { + dt.setTime(dt.getTime() - daymil) + } + newDT = format(dt.getTime(), options.format) + query(this.el).val(newDT).trigger('input').trigger('change') + cancel = true + break + } + if (cancel) { + event.preventDefault() + this.moveCaret2end() + this.updateOverlay() + } + } + // time + if (this.type === 'time') { + if (!options.keyboard || query(this.el).prop('readOnly') || query(this.el).prop('disabled')) return + inc = (event.ctrlKey || event.metaKey ? 60 : 1) + val = query(this.el).val() + let time = w2date.str2min(val) || w2date.str2min((new Date()).getHours() + ':' + ((new Date()).getMinutes() - 1)) + switch (key) { + case 38: // up + if (event.shiftKey) break // no action if shift key is pressed + time += inc + cancel = true + break + case 40: // down + if (event.shiftKey) break // no action if shift key is pressed + time -= inc + cancel = true + break + } + if (cancel) { + event.preventDefault() + query(this.el).val(w2date.min2str(time)).trigger('input').trigger('change') + this.moveCaret2end() + } + } + // list/enum + if (['list', 'enum'].includes(this.type)) { + switch (key) { + case 8: // delete + case 46: // backspace + if (this.type == 'list') { + let search = query(this.helpers.search_focus) + if (search.val() == '') { + this.selected = null + w2menu.hide(this.el.id + '_menu') + query(this.el).val('').trigger('input').trigger('change') + } + } else { + let search = query(this.helpers.multi).find('input') + if (search.val() == '') { + w2menu.hide(this.el.id + '_menu') + this.selected.pop() + // update selected array in overlay + let overlay = w2menu.get(this.el.id + '_menu') + if (overlay) overlay.options.selected = this.selected + this.refresh() + } + } + break + case 9: // tab key + case 16: // shift key (when shift+tab) + break + case 27: // escape + w2menu.hide(this.el.id + '_menu') + this.refresh() + break + default: { + // intentionally blank + } + } + } + } + keyUp(event) { + if (this.type == 'list') { + let search = query(this.helpers.search_focus) + if (search.val() !== '') { + query(this.el).attr('placeholder', '') + } else { + query(this.el).attr('placeholder', this.tmp.pholder) + } + if (event.keyCode == 13) { + setTimeout(() => { + search.val('') + w2menu.hide(this.el.id + '_menu') + this.refresh() + }, 1) + } + // if arrows are clicked, it will show overlay + if ([38, 40].includes(event.keyCode) && !this.tmp.overlay.overlay.displayed) { + this.updateOverlay() + } + this.refresh() + } + if (this.type == 'combo') { + this.updateOverlay() + } + if (this.type == 'enum') { + let search = this.helpers.multi.find('input') + let styles = getComputedStyle(search.get(0)) + let width = w2utils.getStrWidth(search.val(), + `font-family: ${styles['font-family']}; font-size: ${styles['font-size']};`) + search.css({ width: (width + 15) + 'px' }) + this.resize() + // if arrows are clicked, it will show overlay + if ([38, 40].includes(event.keyCode) && !this.tmp.overlay?.overlay?.displayed) { + this.updateOverlay() + } + } + } + findItemIndex(items, id, parents) { + let inds = [] + if (!parents) parents = [] + if (['list', 'combo', 'enum'].includes(this.type) && this.options.url) { + // remove source, so get it from overlay + let overlay = w2menu.get(this.el.id + '_menu') + if (overlay) { + items = overlay.options.items + this.options.items = items + } + } + items.forEach((item, ind) => { + if (item.id === id) { + inds = parents.concat([ind]) + this.options.index = [ind] + } + if (inds.length == 0 && item.items && item.items.length > 0) { + parents.push(ind) + inds = this.findItemIndex(item.items, id, parents) + parents.pop() + } + }) + return inds + } + updateOverlay(indexOnly) { + let options = this.options + let params + // color + if (this.type === 'color') { + if (query(this.el).prop('readOnly') || query(this.el).prop('disabled')) return + w2color.show(w2utils.extend({ + name: this.el.id + '_color', + anchor: this.el, + transparent: options.transparent, + advanced: options.advanced, + color: this.el.value, + liveUpdate: true + }, this.options)) + .select(event => { + let color = event.detail.color + query(this.el).val(color).trigger('input').trigger('change') + }) + .liveUpdate(event => { + let color = event.detail.color + query(this.helpers.suffix).find(':scope > div').css('background-color', '#' + color) + }) + } + // list + if (['list', 'combo', 'enum'].includes(this.type)) { + let el = this.el + let input = this.el + if (this.type === 'enum') { + el = this.helpers.multi.get(0) + input = query(el).find('input').get(0) + } + if (this.type === 'list') { + let sel = this.selected + if (w2utils.isPlainObject(sel) && Object.keys(sel).length > 0) { + let ind = this.findItemIndex(options.items, sel.id) + if (ind.length > 0) { + options.index = ind + } + } + input = this.helpers.search_focus + } + if (query(this.el).hasClass('has-focus') && !this.el.readOnly && !this.el.disabled) { + params = w2utils.extend({}, options, { + name: this.el.id + '_menu', + anchor: input, + selected: this.selected, + search: false, + render: options.renderDrop, + anchorClass: '', + offsetY: 5, + maxHeight: options.maxDropHeight, // TODO: check + maxWidth: options.maxDropWidth, // TODO: check + minWidth: options.minDropWidth // TODO: check + }) + this.tmp.overlay = w2menu.show(params) + .select(event => { + if (['list', 'combo'].includes(this.type)) { + this.selected = event.detail.item + query(input).val('') + query(this.el).val(this.selected.text).trigger('input').trigger('change') + this.focus({ showMenu: false }) + } else { + let selected = this.selected + let newItem = event.detail?.item + if (newItem) { + // trigger event + let edata = this.trigger('add', { target: this.el, item: newItem, originalEvent: event }) + if (edata.isCancelled === true) return + // default behavior + if (selected.length >= options.max && options.max > 0) selected.pop() + delete newItem.hidden + selected.push(newItem) + query(this.el).trigger('input').trigger('change') + query(this.helpers.multi).find('input').val('') + // updaet selected array in overlays + let overlay = w2menu.get(this.el.id + '_menu') + if (overlay) overlay.options.selected = this.selected + // event after + edata.finish() + } + } + }) + } + } + // date + if (['date', 'time', 'datetime'].includes(this.type)) { + if (query(this.el).prop('readOnly') || query(this.el).prop('disabled')) return + w2date.show(w2utils.extend({ + name: this.el.id + '_date', + anchor: this.el, + value: this.el.value, + }, this.options)) + .select(event => { + let date = event.detail.date + if (date != null) { + query(this.el).val(date).trigger('input').trigger('change') + } + }) + } + } + /* + * INTERNAL FUNCTIONS + */ + isStrValid(ch, loose) { + let isValid = true + switch (this.type) { + case 'int': + if (loose && ['-', this.options.groupSymbol].includes(ch)) { + isValid = true + } else { + isValid = w2utils.isInt(ch.replace(this.options.numberRE, '')) + } + break + case 'percent': + ch = ch.replace(/%/g, '') + case 'float': + if (loose && ['-', '', this.options.decimalSymbol, this.options.groupSymbol].includes(ch)) { + isValid = true + } else { + isValid = w2utils.isFloat(ch.replace(this.options.numberRE, '')) + } + break + case 'money': + case 'currency': + if (loose && ['-', this.options.decimalSymbol, this.options.groupSymbol, this.options.currencyPrefix, + this.options.currencySuffix].includes(ch)) { + isValid = true + } else { + isValid = w2utils.isFloat(ch.replace(this.options.moneyRE, '')) + } + break + case 'bin': + isValid = w2utils.isBin(ch) + break + case 'color': + case 'hex': + isValid = w2utils.isHex(ch) + break + case 'alphanumeric': + isValid = w2utils.isAlphaNumeric(ch) + break + } + return isValid + } + addPrefix() { + if (!this.options.prefix) { + return + } + let helper + let styles = getComputedStyle(this.el) + if (this.tmp['old-padding-left'] == null) { + this.tmp['old-padding-left'] = styles['padding-left'] + } + // remove if already displayed + if (this.helpers.prefix) query(this.helpers.prefix).remove() + query(this.el).before(`
    ${this.options.prefix}
    `) + helper = query(this.el).get(0).previousElementSibling + query(helper) + .css({ + 'color' : styles.color, + 'font-family' : styles['font-family'], + 'font-size' : styles['font-size'], + 'height' : this.el.clientHeight + 'px', + 'padding-top' : styles['padding-top'], + 'padding-bottom' : styles['padding-bottom'], + 'padding-left' : this.tmp['old-padding-left'], + 'padding-right' : 0, + 'margin-top' : (parseInt(styles['margin-top'], 10) + 2) + 'px', + 'margin-bottom' : (parseInt(styles['margin-bottom'], 10) + 1) + 'px', + 'margin-left' : styles['margin-left'], + 'margin-right' : 0, + 'z-index' : 1, + }) + // only if visible + query(this.el).css('padding-left', helper.clientWidth + 'px !important') + // remember helper + this.helpers.prefix = helper + } + addSuffix() { + if (!this.options.suffix && !this.options.arrow) { + return + } + let helper + let self = this + let styles = getComputedStyle(this.el) + if (this.tmp['old-padding-right'] == null) { + this.tmp['old-padding-right'] = styles['padding-right'] + } + let pr = parseInt(styles['padding-right'] || 0) + if (this.options.arrow) { + // remove if already displayed + if (this.helpers.arrow) query(this.helpers.arrow).remove() + // add fresh + query(this.el).after( + '
     '+ + '
    '+ + '
    '+ + '
    '+ + '
    '+ + '
    '+ + '
    '+ + '
    ') + helper = query(this.el).get(0).nextElementSibling + query(helper).css({ + 'color' : styles.color, + 'font-family' : styles['font-family'], + 'font-size' : styles['font-size'], + 'height' : this.el.clientHeight + 'px', + 'padding' : 0, + 'margin-top' : (parseInt(styles['margin-top'], 10) + 1) + 'px', + 'margin-bottom' : 0, + 'border-left' : '1px solid silver', + 'width' : '16px', + 'transform' : 'translateX(-100%)' + }) + .on('mousedown', function(event) { + if (query(event.target).hasClass('arrow-up')) { + self.keyDown(event, { keyCode: 38 }) + } + if (query(event.target).hasClass('arrow-down')) { + self.keyDown(event, { keyCode: 40 }) + } + }) + pr += helper.clientWidth // width of the control + query(this.el).css('padding-right', pr + 'px !important') + this.helpers.arrow = helper + } + if (this.options.suffix !== '') { + // remove if already displayed + if (this.helpers.suffix) query(this.helpers.suffix).remove() + // add fresh + query(this.el).after(`
    ${this.options.suffix}
    `) + helper = query(this.el).get(0).nextElementSibling + query(helper) + .css({ + 'color' : styles.color, + 'font-family' : styles['font-family'], + 'font-size' : styles['font-size'], + 'height' : this.el.clientHeight + 'px', + 'padding-top' : styles['padding-top'], + 'padding-bottom' : styles['padding-bottom'], + 'padding-left' : 0, + 'padding-right' : styles['padding-right'], + 'margin-top' : (parseInt(styles['margin-top'], 10) + 2) + 'px', + 'margin-bottom' : (parseInt(styles['margin-bottom'], 10) + 1) + 'px', + 'transform' : 'translateX(-100%)' + }) + query(this.el).css('padding-right', helper.clientWidth + 'px !important') + this.helpers.suffix = helper + } + } + // Only used for list + addSearch() { + if (this.type !== 'list') return + // clean up & init + if (this.helpers.search) query(this.helpers.search).remove() + // remember original tabindex + let tabIndex = parseInt(query(this.el).attr('tabIndex')) + if (!isNaN(tabIndex) && tabIndex !== -1) this.tmp['old-tabIndex'] = tabIndex + if (this.tmp['old-tabIndex']) tabIndex = this.tmp['old-tabIndex'] + if (tabIndex == null || isNaN(tabIndex)) tabIndex = 0 + // if there is id, add to search with "_search" + let searchId = '' + if (query(this.el).attr('id') != null) { + searchId = 'id="' + query(this.el).attr('id') + '_search"' + } + // build helper + let html = ` +
    + + +
    ` + query(this.el).attr('tabindex', -1).before(html) + let helper = query(this.el).get(0).previousElementSibling + this.helpers.search = helper + this.helpers.search_focus = query(helper).find('input').get(0) + let styles = getComputedStyle(this.el) + query(helper).css({ + width : this.el.clientWidth + 'px', + 'margin-top' : styles['margin-top'], + 'margin-left' : styles['margin-left'], + 'margin-bottom' : styles['margin-bottom'], + 'margin-right' : styles['margin-right'] + }) + .find('input') + .css({ + cursor : 'default', + width : '100%', + opacity : 1, + padding : styles.padding, + margin : styles.margin, + border : '1px solid transparent', + 'background-color' : 'transparent' + }) + // INPUT events + query(helper).find('input') + .off('.helper') + .on('focus.helper', event => { + query(event.target).val('') + this.tmp.pholder = query(this.el).attr('placeholder') ?? '' + this.focus(event) + event.stopPropagation() + }) + .on('blur.helper', event => { + query(event.target).val('') + if (this.tmp.pholder != null) query(this.el).attr('placeholder', this.tmp.pholder) + this.blur(event) + event.stopPropagation() + }) + .on('keydown.helper', event => { this.keyDown(event) }) + .on('keyup.helper', event => { this.keyUp(event) }) + // MAIN div + query(helper).on('click', event => { + query(event.target).find('input').focus() + }) + } + // Used in enum/file + addMultiSearch() { + if (!['enum', 'file'].includes(this.type)) { + return + } + // clean up & init + query(this.helpers.multi).remove() + // build helper + let html = '' + let styles = getComputedStyle(this.el) + let margin = w2utils.stripSpaces(` + margin-top: 0px; + margin-bottom: 0px; + margin-left: ${styles['margin-left']}; + margin-right: ${styles['margin-right']}; + width: ${(w2utils.getSize(this.el, 'width') - parseInt(styles['margin-left'], 10) + - parseInt(styles['margin-right'], 10))}px; + `) + if (this.tmp['min-height'] == null) { + let min = this.tmp['min-height'] = parseInt((styles['min-height'] != 'none' ? styles['min-height'] : 0) || 0) + let current = parseInt(styles.height) + this.tmp['min-height'] = Math.max(min, current) + } + if (this.tmp['max-height'] == null && styles['max-height'] != 'none') { + this.tmp['max-height'] = parseInt(styles['max-height']) + } + // if there is id, add to search with "_search" + let searchId = '' + if (query(this.el).attr('id') != null) { + searchId = `id="${query(this.el).attr('id')}_search"` + } + // remember original tabindex + let tabIndex = parseInt(query(this.el).attr('tabIndex')) + if (!isNaN(tabIndex) && tabIndex !== -1) this.tmp['old-tabIndex'] = tabIndex + if (this.tmp['old-tabIndex']) tabIndex = this.tmp['old-tabIndex'] + if (tabIndex == null || isNaN(tabIndex)) tabIndex = 0 + if (this.type === 'enum') { + html = ` +
    +
    + +
    +
    ` + } + if (this.type === 'file') { + html = ` +
    +
    + +
    +
    + +
    +
    ` + } + // old bg and border + this.tmp['old-background-color'] = styles['background-color'] + this.tmp['old-border-color'] = styles['border-color'] + query(this.el) + .before(html) + .css({ + 'border-color': 'transparent', + 'background-color': 'transparent' + }) + let div = query(this.el.previousElementSibling) + this.helpers.multi = div + query(this.el).attr('tabindex', -1) + // click anywhere on the field + div.on('click', event => { this.focus(event) }) + // search field + div.find('input:not(.file-input)') + .on('click', event => { this.click(event) }) + .on('focus', event => { this.focus(event) }) + .on('blur', event => { this.blur(event) }) + .on('keydown', event => { this.keyDown(event) }) + .on('keyup', event => { this.keyUp(event) }) + // file input + if (this.type === 'file') { + div.find('input.file-input') + .off('.drag') + .on('click.drag', (event) => { + event.stopPropagation() + if (query(this.el).prop('readOnly') || query(this.el).prop('disabled')) return + this.focus(event) + }) + .on('dragenter.drag', (event) => { + if (query(this.el).prop('readOnly') || query(this.el).prop('disabled')) return + div.addClass('w2ui-file-dragover') + }) + .on('dragleave.drag', (event) => { + if (query(this.el).prop('readOnly') || query(this.el).prop('disabled')) return + div.removeClass('w2ui-file-dragover') + }) + .on('drop.drag', (event) => { + if (query(this.el).prop('readOnly') || query(this.el).prop('disabled')) return + div.removeClass('w2ui-file-dragover') + let files = Array.from(event.dataTransfer.files) + files.forEach(file => { this.addFile(file) }) + this.focus(event) + // cancel to stop browser behaviour + event.preventDefault() + event.stopPropagation() + }) + .on('dragover.drag', (event) => { + // cancel to stop browser behaviour + event.preventDefault() + event.stopPropagation() + }) + .on('change.drag', (event) => { + if (typeof event.target.files !== 'undefined') { + Array.from(event.target.files).forEach(file => { this.addFile(file) }) + } + this.focus(event) + }) + } + this.refresh() + } + addFile(file) { + let options = this.options + let selected = this.selected + let newItem = { + name : file.name, + type : file.type, + modified : file.lastModifiedDate, + size : file.size, + content : null, + file : file + } + let size = 0 + let cnt = 0 + let errors = [] + if (Array.isArray(selected)) { + selected.forEach(item => { + if (item.name == file.name && item.size == file.size) { + errors.push(w2utils.lang('The file "${name}" (${size}) is already added.', { + name: file.name, size: w2utils.formatSize(file.size) })) + } + size += item.size + cnt++ + }) + } + if (options.maxFileSize !== 0 && newItem.size > options.maxFileSize) { + errors.push(w2utils.lang('Maximum file size is ${size}', { size: w2utils.formatSize(options.maxFileSize) })) + } + if (options.maxSize !== 0 && size + newItem.size > options.maxSize) { + errors.push(w2utils.lang('Maximum total size is ${size}', { size: w2utils.formatSize(options.maxSize) })) + } + if (options.max !== 0 && cnt >= options.max) { + errors.push(w2utils.lang('Maximum number of files is ${count}', { count: options.max })) + } + // trigger event + let edata = this.trigger('add', { target: this.el, file: newItem, total: cnt, totalSize: size, errors }) + if (edata.isCancelled === true) return + // if errors and not silent + if (options.silent !== true && errors.length > 0) { + w2tooltip.show({ + anchor: this.el, + html: 'Errors: ' + errors.join('
    ') + }) + console.log('ERRORS (while adding files): ', errors) + return + } + // check params + selected.push(newItem) + // read file as base64 + if (typeof FileReader !== 'undefined' && options.readContent === true) { + let reader = new FileReader() + let self = this + // need a closure + reader.onload = (function onload() { + return function closure(event) { + let fl = event.target.result + let ind = fl.indexOf(',') + newItem.content = fl.substr(ind + 1) + self.refresh() + query(self.el).trigger('input').trigger('change') + // event after + edata.finish() + } + })() + reader.readAsDataURL(file) + } else { + this.refresh() + query(this.el).trigger('input').trigger('change') + edata.finish() + } + } + // move cursror to end + moveCaret2end() { + setTimeout(() => { + this.el.setSelectionRange(this.el.value.length, this.el.value.length) + }, 0) + } +} +/** + * Part of w2ui 2.0 library + * - Dependencies: jQuery, w2ui.* + * + * This file provided compatibility for projects that conntinue to use jQuery. It extends jQuery with + * w2ui support, such as fn.w2grid, fn.w2form, ... fn.w2render, fn.w2destroy, fn.w2tag, etc + * + * It is not needed for projects that use ES6 module loading. + * + * == 2.0 changes + * - CSP - fixed inline events + */ + +// Register jQuery plugins +(function($) { + // register globals if needed + let w2globals = function() { + (function (win, obj) { + Object.keys(obj).forEach(key => { + win[key] = obj[key] + }) + })(window, { + w2ui, w2utils, query, w2locale, w2event, w2base, + w2popup, w2alert, w2confirm, w2prompt, Dialog, + w2tooltip, w2menu, w2color, w2date, Tooltip, + w2toolbar, w2sidebar, w2tabs, w2layout, w2grid, w2form, w2field + }) + } + // if url has globals at the end, then register globals + let param = String(undefined).split('?')[1] || '' + if (param == 'globals' || param.substr(0, 8) == 'globals=') { + w2globals() + } + // if jQuery is not defined, then exit + if (!$) return + $.w2globals = w2globals + $.fn.w2render = function(name) { + if ($(this).length > 0) { + if (typeof name === 'string' && w2ui[name]) w2ui[name].render($(this)[0]) + if (typeof name === 'object') name.render($(this)[0]) + } + } + $.fn.w2destroy = function(name) { + if (!name && this.length > 0) name = this.attr('name') + if (typeof name === 'string' && w2ui[name]) w2ui[name].destroy() + if (typeof name === 'object') name.destroy() + } + $.fn.w2field = function(type, options) { + // if without arguments - return the object + if (arguments.length === 0) { + let obj = $(this).data('w2field') + return obj + } + return this.each((index, el) => { + let obj = $(el).data('w2field') + // if object is not defined, define it + if (obj == null) { + obj = new w2field(type, options) + obj.render(el) + return obj + } else { // fully re-init + obj = new w2field(type, options) + obj.render(el) + return obj + } + return null + }) + } + $.fn.w2form = function(options) { return proc.call(this, options, 'w2form') } + $.fn.w2grid = function(options) { return proc.call(this, options, 'w2grid') } + $.fn.w2layout = function(options) { return proc.call(this, options, 'w2layout') } + $.fn.w2sidebar = function(options) { return proc.call(this, options, 'w2sidebar') } + $.fn.w2tabs = function(options) { return proc.call(this, options, 'w2tabs') } + $.fn.w2toolbar = function(options) { return proc.call(this, options, 'w2toolbar') } + function proc(options, type) { + if ($.isPlainObject(options)) { + let obj + if (type == 'w2form') { + obj = new w2form(options) + if (this.find('.w2ui-field').length > 0) { + obj.formHTML = this.html() + } + } + if (type == 'w2grid') obj = new w2grid(options) + if (type == 'w2layout') obj = new w2layout(options) + if (type == 'w2sidebar') obj = new w2sidebar(options) + if (type == 'w2tabs') obj = new w2tabs(options) + if (type == 'w2toolbar') obj = new w2toolbar(options) + if ($(this).length !== 0) { + obj.render(this[0]) + } + return obj + } else { + let obj = w2ui[$(this).attr('name')] + if (!obj) return null + if (arguments.length > 0) { + if (obj[options]) obj[options].apply(obj, Array.prototype.slice.call(arguments, 1)) + return this + } else { + return obj + } + } + } + $.fn.w2popup = function(options) { + if (this.length > 0 ) { + w2popup.template(this[0], null, options) + } else if (options.url) { + w2popup.load(options) + } + } + $.fn.w2marker = function() { + let str = Array.from(arguments) + if (Array.isArray(str[0])) str = str[0] + return $(this).each((index, el) => { + w2utils.marker(el, str) + }) + } + $.fn.w2tag = function(text, options) { + return this.each((index, el) => { + if (text == null && options == null) { + w2tooltip.hide() + return + } + if (typeof text == 'object') { + options = text + } else { + options = options ?? {} + options.html = text + } + w2tooltip.show(el, options) + }) + } + $.fn.w2overlay = function(html, options) { + return this.each((index, el) => { + if (html == null && options == null) { + w2tooltip.hide() + return + } + if (typeof html == 'object') { + options = html + } else { + options.html = html + } + Object.assign(options, { + class: 'w2ui-white', + hideOn: ['doc-click'] + }) + w2tooltip.show(el, options) + }) + } + $.fn.w2menu = function(menu, options) { + return this.each((index, el) => { + if (typeof menu == 'object') { + options = menu + } + if (typeof menu == 'object') { + options = menu + } else { + options.items = menu + } + w2menu.show(el, options) + }) + } + $.fn.w2color = function(options, callBack) { + return this.each((index, el) => { + let tooltip = w2color.show(el, options) + if (typeof callBack == 'function') { + tooltip.select(callBack) + } + }) + } +})(window.jQuery) + +// Compatibility with CommonJS and AMD modules +!(function(global, w2ui) { +if (typeof define == 'function' && define.amd) { + return define(() => w2ui) +} +if (typeof exports != 'undefined') { + if (typeof module != 'undefined' && module.exports) { + return exports = module.exports = w2ui + } + global = exports +} +if (global) { + Object.keys(w2ui).forEach(key => { + global[key] = w2ui[key] + }) +} +})(self, { + w2ui, w2utils, query, w2locale, w2event, w2base, + w2popup, w2alert, w2confirm, w2prompt, Dialog, + w2tooltip, w2menu, w2color, w2date, Tooltip, + w2toolbar, w2sidebar, w2tabs, w2layout, w2grid, w2form, w2field +}) \ No newline at end of file diff --git a/src/resources/w2ui-2.0/w2ui-2.0.min.css b/src/resources/w2ui-2.0/w2ui-2.0.min.css new file mode 100644 index 0000000..dba6c5a --- /dev/null +++ b/src/resources/w2ui-2.0/w2ui-2.0.min.css @@ -0,0 +1,2 @@ +/* w2ui 2.0.0 (4/26/2023, 10:40:17 AM) (c) http://w2ui.com, vitmalina@gmail.com */ +@font-face{font-family:w2ui-font;src:url("data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAAnsAAsAAAAADpwAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADsAAABUIIslek9TLzIAAAFEAAAAQQAAAFZdKW6PY21hcAAAAYgAAACdAAACJimbHahnbHlmAAACKAAABYQAAAd0bnTEjmhlYWQAAAesAAAAMQAAADYiTbc3aGhlYQAAB+AAAAAYAAAAJA3eCBFobXR4AAAH+AAAABAAAAA8cA4AAGxvY2EAAAgIAAAAIAAAACALUg1CbWF4cAAACCgAAAAfAAAAIAEfAGBuYW1lAAAISAAAAS4AAAIibo8QqHBvc3QAAAl4AAAAdAAAAJs0xq68eJxjYGRgYOBiMGCwY2BycfMJYeDLSSzJY5BiYGGAAJA8MpsxJzM9kYEDxgPKsYBpDiBmg4gCACY7BUgAeJxjYGSvYJzAwMrAwCrCIsXAwHAJQjNdYPBkbAbSDKzMDFhBQJprCoMDgyODH+sdILedbRWDGZBmBMkBAGbXCH0AAAB4nL3RWQ6DMAwE0AkJISzhJD1Cf+i+cg6+er7ejo6juUGrWnqWcBYRG0ANwNOGAuBecLBYWHWl7tGVesC27AmlPq8r81Sys5PMFfcG3hjRIKHluR4DMkYuRnwfrvKhjk1qu37I4w8u/HMMJb/1ZQ+YxDq6k4r2YpM5iPX4KDa1k1hnz9LQRRJdpaWbcJq4S08Psb97SqZZxg9PnRB8AAAAeJyFVFtMFFcYPv/MzmypZmHYnb0IO8vMylJghdmdvbBZLmLBSkE0QXAbRV9AwMSUWKHBJpJYo9HSiBaaErEP0gdtYxOV2ESgadMHqW2qMX3woQhp0trYWBPS1JbdPfafWSpVm/Rkzjnf/Ldz/tshDMHBf8sdIDnERgj4vLLCi4LNrsnBSFgIsbIg8xMvxZKHYlu3xkyHY1v3JmtMX3INJS3x5PX4tm1xUyye7DG9jmZAt2Vu4V4jHCFZjDkL+PHUzfSjK8w0+wuXSH0Ii5+m600eXYwzZL1cA8kiVuIm60hEP53PBt7uyAKr2QIOsBaVARfxlSPdzEJhEW7I9oA9EoWIDyxQBtUgAXy/pk7sEfk1zBH69cyo5LTADuFlSw2zDsqVCSUAVmiDM6ek2pz0H9mihCCbeTFHTN/JWV8penCyi6h8yFVnT99nPoH+Ost6Kc0zv73ncXpQm4VyOTXFnGl9NdsmpXjUbkQr7F9SbcouGfqe9YQ14vgu14TITFahL5rgfTL75+eZvIUFJn9+nmta+oqrysx/Ysbv5V4hXvyx2zBodhsGQSnC6CnoeSiahUsNRIIYFlz4hCDQOFzJzW0R1FyaoAncWgQBLtNmQWjJVQU4D9eQZvoxF/k7aacQQHIujNEuXScgwBicy9DoNrgkCJlc8A+5ueW7e0kl3kUWZYc+NdGLcS7yFWBKzHyOQwKHvSBaDdFIDihFOidk/AUNjs2QYt5gC1IL7zCW9OKpBw/YwtjNY0P01tCxm7F4XMegDh29FYuncwcP9F5UAwH1Yu8BugLZ8+/sGuzcxYw+UXhaOfXoWY0MRDdMhDy+YVb41SSbuEiQNKInoUgcgnY32PhSUHxhkMOYk7AsaKzyvE+GR2zGsRyDVGCwcwxR9qzfE/T4jQX8tLejA/wdsxOjJ+9W1tRU3j05ChtHhjN4eGTiyEDfZEDTApN9A/DCCjapyxb8nnS7boD2mpqqq1CbXhsZnquqqamaGx6BjWi1qnqp7Tl9+qeBdV8xbyP8x8RB1qKvFXrWQmWgWEB8uot9hUEJbBZQyiBUDYCuixleFWhZEHWAg++kieD2PduDNGHNz7eaZnFNH3f5XS6/VupylTJbku9P59uY07a8mfQ+ervtDoy0cXPRXVH8JHHplihJIqeK0p78soryvLzyirL8pb2mG2N2SbKPJe/AW+2fwdvtJPPefMSdwttb8b5RKAIWY22NghfYQgiDmU1cYLa0pi/f9mzecPgCLKUpn2abYInyXUx9K9Pcmr5E/Rs2e6C7SyemJtO4Ue78ci+NcX3Eh5ZtZt7Me2VhOeuCrPiqsBQ0WcjUgyjIuPAf8Pxqp0IrVKXNq9KYoqoKXFe9bYoKs4rKfG61iquctMKgz6rKdqRf96qql8ZU5cmbZ+YGSSH+KPqZZm8WyFg41RCUGJuF8YrBf5WWqf/cyRM72u2L0ACb6EPLpljD9Hczp5ubT890HT3YdzWoacGrfQe5Q40Ng4fP0uPw5uYTFQ06W5caQmb/AKwe6EdB/WiM5+Mk/zv3Aykm1YQUYquaI9FIOGQclqlvm1HAWjAaieLjig9mNePD1vXpnRvRG9eu9y3enP+Cns2rcNUqa/2l453dP/V0jJf6EXb07O/avbMRnE4oW1NXr1nsqe7ORGsgFAq0Jr5BgHXZmliAMqeTadq5u2t/d2dGEW0YcK1S66rIo+P5dotWXwf7tGW9FQNG6pbfoUGs5zyikSjZQlowquGQD1PIu/UnCesWk4d1K4e5sCbCf7Pk/+OxE8XuX93F9B64DMA2Jc9MMadK3PfdxalJtqkYQQm46D368zQtfVY2NUnvTXGyw11c7HZMO9wlJbjhoDQDlxkrlCmnTnFO4SDkby6j4OB4nGNgZGBgAOJJO18HxPPbfGXgZr0DFGG4O23bVwT9/xQHI9sqIJeDgQkkCgCOwA3cAAAAeJxjYGRgYL3DAAQcjFASTCMBfgAdRwEFeJxjYGBg4GAkDwMADvIAfwAAAAAAJgA8AKQAwAECAWgBaAHeAjgCZgKgAuADRgO6eJxjYGRgYOBnCGFgYwABJiDmAkIGhv9gPgMAEp0BgAB4nG2PQU7CQBSG/0LBCIkhmpi4m7hwYyjQBQsOAHsW7AtMoaR0mukA4QKewDN4Bk/g0jN4FP+Wly6UaTr53vf+N+0A6OELHsrl4bbay9XADasLN0k9YZ/8JNxCF8/Cbfq+cAevGAt38YCIJ3h+edo9nHADd3gTbtK/C/vkD+EWHvEp3Kb/Fu5ggR/hLl688Sk8JP3YZG6uN4c0snVdw0LbIjGZGgXD2s10pm3k9Fotz6o4bkLnYhVbs1dTdnWaGpVbs9MrF2ydyyeDQSw+WJk9TghxQMJbxzDIeLM5NDZ0KW9sr/T/mwUnLAq6slYYIcDwSm7GXFZlI1Yaa2aXOHMvcOQ3Q1rHtOJrObMnTWVW839SskJe9XY0K/oA22oqxwQDPvGffMAUT/oFXxtfYgAAeJxtxcsOwiAQBVBuC7Q+6S/idLSNlCEMTfTvNXHr2RzTmZ9g/gvo0MPCwWPAiAOOOOGMC64ImEx/k5ejhenpSZJUHb7tW1ZHVVTtXKU43kp72zXfxZWojX3hTGuyJe3qKyeJs1eOlZZRubU1P9SYD+7xIE8=") format("woff");font-weight:400;font-style:normal}[class*=" w2ui-icon-"]:before,[class^=w2ui-icon-]:before{font-family:w2ui-font;display:block;vertical-align:middle;line-height:1;font-weight:400;font-style:normal;speak:none;text-decoration:inherit;text-transform:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.w2ui-icon-box:before{content:"A"}.w2ui-icon-check:before{content:"B"}.w2ui-icon-colors:before{content:"C"}.w2ui-icon-columns:before{content:"D"}.w2ui-icon-cross:before{content:"E"}.w2ui-icon-drop:before{content:"F"}.w2ui-icon-empty:before{content:"G"}.w2ui-icon-info:before{content:"H"}.w2ui-icon-paste:before{content:"I"}.w2ui-icon-pencil:before{content:"J"}.w2ui-icon-plus:before{content:"K"}.w2ui-icon-reload:before{content:"L"}.w2ui-icon-search:before{content:"M"}.w2ui-icon-settings:before{content:"N"}@font-face{font-family:OpenSans;src:url("data:application/x-font-ttf;charset=utf-8;base64,AAEAAAARAQAABAAQR0RFRgt8DNQAAXd0AAAALkdQT1MAGQAMAAF3pAAAABBHU1VC47MpuAABd7QAAALuT1MvMqE2nskAAUdAAAAAYGNtYXCuu/X7AAFHoAAAA4hjdnQgD00YpAABU+gAAACiZnBnbX5hthEAAUsoAAAHtGdhc3AAFQAjAAF3ZAAAABBnbHlmdDiZSwAAARwAAS+0aGVhZAK6Y3AAAThIAAAANmhoZWENzAlzAAFHHAAAACRobXR46DU83QABOIAAAA6abG9jYSkU3PEAATDwAAAHVm1heHAFQwIKAAEw0AAAACBuYW1lW5KAHwABVIwAAAPScG9zdH+4CW8AAVhgAAAfA3ByZXBDt5akAAFS3AAAAQkAAgDBAAAECgW2AAMABwAVtwQDBQIEAwcAAC8yLzMBLzMvMzEwEyERITchESHBA0n8t2gCef2HBbb6SmgE5gACAJj/4wGJBbYAAwAOACtAFAMJCQIEBA8QAQEMAgwGT1kMFgIDAD8/KxESADkYLxESATkRMzMRMzEwASMDMwM0MzIWFRQGIyImAUZpM8/heDo/QDk0RAGTBCP6tIhGQkBHPwAAAgCFA6YCsAW2AAMABwAfQA0AAwcEAwQICQYCBwMDAD8zzTIREgE5OREzETMxMAEDIwMhAyMDAT8oaSkCKyloKQW2/fACEP3wAhAAAAIAMwAABPYFtgAbAB8AmUBVCB8cFQQUCREMDAkSDw4LBAoTExQWHR4HBAYXBAEAGQQYBQUGFAYKIQMaFwMYChggIQgEDA0MTlkcAQ0fABAREE5ZGRURTw0BTxEBDRENEQUXEwMKBQAvMz8zEjk5Ly9dXREzMysRADMzETMzKxEAMzMREgE5OREXMxESOTkRMxESFzkREhc5ETMREhc5MjIRMxESFzkxMAEDIRUhAyMTIQMjEyE1IRMhNSETMwMhEzMDIRUBIRMhA9VCARv+zVSJVP7RUohQ/voBH0T+6wErUotSATFUhlQBCPzlAS9C/tEDg/6sgf5SAa7+UgGugQFUfwG0/kwBtP5Mf/6sAVQAAwCD/4kEDAYSACAAJgAtAGZANScRJR0XBAQqFA0FIQAAGQURCQUuLyUNBg1NWQMGJA4qDkxZHSorHBQcTVkXKhQGFAYUBRYFAC8vEjk5Ly8SOTIrEQAzETMrEQAzETMrEQAzERIBFzkRMxEzMzMzETMzMxEzMTABFAYHFSM1IiYnNRYWMxEmJjU0Njc1MxUWFwcmJxEeAgc0JicRNgEUFhcRBgYEDMy3gXDSQ1PZWc2ly6eBuKs0lZqdnEqqWYDZ/d1ab2NmAcGIsRfo3yMfnCUvAbhBrIiDqBK2tAVFgzsL/k4yX3tlSFks/nseAwdMXCkBgxBdAAAFAGj/7AYtBcsACQAVACEALQAxAEVAJAAQBQoWKBwiIi4oCjAQBjIzAw0fKw0rDSswMQYwGBklGQcTBwA/Mz8zPz8SOTkvLxEzETMREgEXOREzETMRMxEzMTATFBYzMhEQIyIGBRQGIyImNTQ2MzIWARQWMzI2NTQmIyIGBRQGIyImNTQ2MzIWAQEjAfJKU6SkU0oBypmUjJuVkpGcAaZKVFRQUFRUSgHLmZSOmZWSjp/+/vzVkwMrBAKqqgFUAVKoquTp7t/j5u7826upp62rpaWr4+nu3uPm6wMg+koFtgAAAwBx/+wF0wXNAAsAFQA1AFFAMBMWAB0GIyorListIw4mGR0WCTY3MwxJWTMTDyctDjAFLwMZJgMqKiAvEiAJSlkgBAA/KwAYPxI5Lxc5Ehc5PysREgEXOREzETMRMxEzMTABFBYXNjY1NCYjIgYTMjcBDgIVFBYlNDY3LgI1NDYzMhYVFAYHATY2NzMCBwEjJwYGIyImAZ5IV4FlZ1ZZb5vxn/5Lb1wsm/65i7RVPSTEr6K6iJ0BlzhDF6hEiQEr5bl29JbX7QSTRX1YS39TTWFg+52aAahEWWZBdYn6gshmX2JqOZaop5VrtV3+eT6nY/7ilP7dsmpc1AAAAQCFA6YBPwW2AAMAFLcAAwMEBQIDAwA/zRESATkRMzEwAQMjAwE/KGkpBbb98AIQAAABAFL+vAIhBbYADQAcQAwHAAoEAAQODwsnAwMAPz8REgE5OREzETMxMBMQEjczBgIVFBIXIyYCUpuSopCRlIugk5oCMQEJAc6uwf4y9PD+Nr2qAcYAAAEAPf68AgwFtgANABxADAQKBwAKAA4PCgMEJwA/PxESATk5ETMRMzEwARACByM2EjU0AiczFhICDJuSoIuUkZCik5oCMf75/jqovAHL8PQBzsGv/jEAAQBWAn8EDgYUAA4AMEAbAwUEAQcNCgkLCQ8QBAoBDQIMDA0KBwQGCA4AAD/EMhc5ETMRMxEzERIBFzkxMAEDJRcFEwcDAycTJTcFAwKRKwGOGv6D+KywoLDy/ocdAYcrBhT+dW+2H/66XgFq/pZeAUYftm8BiwAAAQBoAOMEKQTDAAsAKEATAAQECQUFDA0DBwgHUFkADwgBCAAvXTMrEQAzERIBOREzMxEzMTABIRUhESMRITUhETMCjQGc/mSL/mYBmosDF4r+VgGqigGsAAEAP/74AW0A7gAIABG1BQAJCgUAAC/NERIBOTkxMCUXBgIHIzYSNwFeDxpiNX0bQQ3uF2T+93JoATJcAAEAVAHZAj8CcQADABG1AgAFBAABAC8zERIBOTkxMBM1IRVUAesB2ZiYAAEAmP/jAYkA8gALABhACwYAAAwNCQNPWQkWAD8rERIBOREzMTA3NDYzMhYVFAYjIiaYPTk6QUI5M0NqQ0VFQ0FGPwAAAQAUAAAC2wW2AAMAE7cCAAQFAwMCEgA/PxESATk5MTABASMBAtv936YCIQW2+koFtgACAGb/7AQtBc0ACwAXAChAFBIADAYABhkYCRVLWQkHAw9LWQMZAD8rABg/KxESATk5ETMRMzEwARACIyICERASMzISARASMzISERACIyICBC3v9uz27vTu9/zhlqSmlZWmpJYC3f6F/ooBfwFyAX4Bcv5+/pL+wf7dAScBOwE7ASX+3wABALwAAALLBbYACgAkQBAJAAEIAQsMBAkHBwEJBgEYAD8/EjkvEjkREgE5OREzMzEwISMRNDcGBgcnATMCy6IIFTTUWAGDjAQSgnQVLqxyASsAAQBkAAAEJQXLABkAK0AXGAEHEwATDgEEGhsQCktZEAcBGExZARgAPysAGD8rERIBFzkRMxEzMTAhITUBPgI1NCYjIgYHJzYzMhYVFAIHARUhBCX8PwGBsHA4jn5bo2RYyu7O6pzW/sAC8I8Bg7KYkFN1iTxPcajTsov+8ND+xwgAAAEAXv/sBBsFywAnAENAJBsAEwcHAAMWIg0GKCkDFxYXFktZFxcKJSUeS1klBwoRS1kKGQA/KwAYPysREgA5GC8rERIAORESARc5ETMRMzEwARQGBxUWFhUUBCEiJic1FhYzIBEQISM1MzI2NTQmIyIGByc2NjMyFgPunZCwqv7e/vV0wVtf12ABe/5ekJKryJN+YKptVFrrgtXsBF6Msh4IFrSS0eEjLJ4vMQEpAQqPl4ZrejRGcEdRwwAAAgArAAAEagW+AAoAEgA8QB4SBQkCAgsHAwADBQMTFAEFEgVMWQkPBxISAwcGAxgAPz8SOS8SOTMrEQAzERIBFzkRMzMzETMRMzEwASMRIxEhNQEzETMhETQ3IwYHAQRq2Z/9OQK2sNn+iAoIMCr+NwFQ/rABUJED3fwpAeaPtGA//XYAAQCF/+wEHQW2ABoAOkAfDwMZFAgUFwMEHBsAEUtZAAAGFRUYTFkVBgYMS1kGGQA/KwAYPysREgA5GC8rERIBFzkRMxEzMTABMgQVFAAjIic1FhYzMjY1ECEiBycTIRUhAzYCLecBCf7f/veCRtBlsMP+iV+fVjcC1/23JXMDfeXH4/7+T6AtM6adATIdNwKsmf5JFwAAAgB1/+wELwXLABYAJABEQCMaEQshIQAABhEDJiUMCw4dTVkLDg4UAxQXS1kUGQMITVkDBwA/KwAYPysREgA5GC85KxEAMxESARc5ETMRMxEzMTATEAAhMhcVJiMiAgMzNjMyFhUUAiMiAAUyNjU0JiMiBgYVFBYWdQFPAUhxQU1j6/gMDG7uxeP51OP+9gHrjp2SkVqWWVCTAnEBrwGrE48Z/tv+xqzuzOT++wFVyLOpkaZKgkZnsmgAAQBeAAAEKwW2AAYAH0AQAQUFAAIDBwgDAkxZAwYAGAA/PysREgEXOREzMTAhASE1IRUBAR0CXvzjA839qgUdmYX6zwADAGj/7AQpBcsAFgAiAC4ATUApFw8mFCwDHQkJAwYRFA8GLzAGESkgKSBLWSkpDAAMGk1ZDBkAI01ZAAcAPysAGD8rERIAORgvKxESADk5ERIBFzkRMxEzETMRMzEwATIWFRQGBxYWFRQGIyImNTQlJiY1NDYDFBYzMjY1NCYnBgYBIgYVFBYXNjY1NCYCSMjqhpOylv7d6vwBMop463enl5WmnMKVhgE6fY52n493kQXLuqRssklVu3u22c28+4xOtXCfvfumeIaMemGXR0CbA2d4ZFyEQjyKXGV3AAACAGr/7AQlBcsAFwAlAEFAIhsRIgoKAAAEEQMmJw4eTVkLFA4OAhQUGEtZFAcCB01ZAhkAPysAGD8rERIAORgvEjkrERIBFzkRMxEzETMxMAEQISInNRYzMhITIwYGIyImNTQSMzIWEgEiBhUUFjMyNjY1NCYmBCX9aHREUGbw9QsMN7ZywuT/0JXfeP4Uj5yQk1uZWFKTA0b8phSPGgEpATNTV+jQ5AEImf7bATC4pJClSoBGabJmAAACAJj/4wGJBGQACwAVAChAFBAGBgwAABYXDhNPWQ4QCQNPWQkWAD8rABg/KxESATkRMzMRMzEwNzQ2MzIWFRQGIyImETQzMhUUBiMiJpg9OTpBQjkzQ3Z7QjkzQ2pDRUVDQUY/A7uHh0FGPwACAD/++AGFBGQACAASACJAEAENDQUJCRQTCxBPWQsQBQAAL80/KxESATkRMzMRMzEwJRcGAgcjNhI3AzQzMhUUBiMiJgFeDxpiNX0bQQ0Vd3tCOTo97hdk/vdyaAEyXALvh4dBRkYAAAEAaADyBCkE2QAGABVACQQABQEEBwgDAAAvLxESARc5MTAlATUBFQEBBCn8PwPB/PIDDvIBpmIB35X+jf64AAACAHcBwQQZA+MAAwAHACpAFQcCBAACAAkIBAVQWQQBAFBZDwEBAQAvXSsAGC8rERIBOTkRMxEzMTATNSEVATUhFXcDovxeA6IDWomJ/meJiQAAAQBoAPIEKQTZAAYAFUAJBQECAAQHCAYDAC8vERIBFzkxMBMBATUBFQFoAw/88QPB/D8BiQFGAXWV/iFi/loAAAIAG//jAzkFywAbACYAOUAdIRwbAAcTEwAcDgQnKAAAJBAkHk9ZJBYQCklZEAQAPysAGD8rERIAORgvERIBFzkRMxEzETMxMAE1NDY3NjY1NCYjIgYHJzYzMhYVFAYGBwYGFRUDNDMyFhUUBiMiJgEhSGKIR4N7T5ZhO73Ov9QnTH5lQbJ4Oj9AOTREAZM2dZdUc3RSZm8lMYdjvKtJb2NuVnJfIf7XiEZCQEc/AAIAef9GBrgFtAA1AD8ARUAiIy42DjsHFBsAACkUDi4FQEEYODgEPQgRCxELESsfMgMmKwAvMz8zEjk5Ly8SOTIzMxEzERIBFzkRMxEzMxEzETMxMAEUBgYjIiYnIwYGIyImNTQ2MzIWFwMVFDMyNjU0AiQjIgQCFRAAITI3FQYjIAAREBIkITIEEgEUMzITEyYjIgYGuFigaFZ2CwgolWaWqezARKxFGYVbcpT+77Hf/rauAUIBL9LiwPT+lf5v1gGMAQDXAU+3+/bDzxIOSFWCkwLZjuyCaFFXYs2wzP8ZFv4qFrLXrLUBEJO5/qnh/s/+uFaFVAGPAWYBBAGW37X+s/6k/gE5AQUUtAACAAAAAAUQBbwABwAOADlAHgIOCwgBBQADAAcDBAcEEA8OAklZCwUODgQFAwAEEgA/Mz8SOS8SOSsREgE5OREzETMREhc5MTAhAyEDIwEzAQEDJicGBwMEYLb9trSsAkKPAj/+ZaohIxYprAHR/i8FvPpEAmoBxVZ9YHP+OwADAMkAAAS+BbYADgAXACAASUAmEwQdCg8ZGQ4KBAcOBCEiCA8YDxhKWQ8PDgAOGUpZDhIAF0pZAAMAPysAGD8rERIAORgvKxESADkREgEXOREzETMRMxEzMTATISAEFRQGBxUEERQEIyETITI2NTQmIyMRESEyNjU0JiPJAZ0BIwEEkYsBTf737v4CqgEYtJ6wwPoBMbGzt7sFtq68gqkZCjn+28TcA0Rxhntt/ZH93YmSiIAAAAEAff/sBM8FywAWACZAFAMOFAkOAxcYEgBJWRIECwZJWQsTAD8rABg/KxESARc5ETMxMAEiABEQADMyNxUGIyAAETQSJDMyFwcmAzvx/ukBDfmZxJjf/r3+oakBP9jmrEimBTP+v/7p/uH+xzeVOQGIAWniAVS4VJJOAAACAMkAAAVYBbYACAARAChAFA4ECQAEABITBQ1KWQUDBA5KWQQSAD8rABg/KxESATk5ETMRMzEwARAAISERISAAAxAAISMRMyAABVj+d/6P/msBwAFVAXq0/uH+5ffPATABMgLp/pb+gQW2/ob+pwEeASL7cAErAAABAMkAAAP4BbYACwA6QB8GCgoBBAAIAQQMDQYJSVkGBgECAgVJWQIDAQpJWQESAD8rABg/KxESADkYLysREgEXOREzETMxMCEhESEVIREhFSERIQP4/NEDL/17Al79ogKFBbaX/imW/eYAAQDJAAAD+AW2AAkAMkAaBgAAAQMIAQMKCwYJSVkGBgECAgVJWQIDARIAPz8rERIAORgvKxESARc5ETMRMzEwISMRIRUhESEVIQFzqgMv/XsCXv2iBbaX/emXAAABAH3/7AU9BcsAGwA6QB8UCBkCAg4bCAQcHQAbSVkAAAUMDBFJWQwEBRdJWQUTAD8rABg/KxESADkYLysREgEXOREzETMxMAEhEQYGIyAAETQSJDMyFwcmIyAAERAAITI3ESEDTAHxdPCe/rT+jrcBWOfqykLGt/71/tQBIQEYmJH+uQL+/TklJgGLAWTkAVe1VpZU/sL+5v7Y/s4jAcIAAQDJAAAFHwW2AAsAM0AZCQEBAAgEBAUABQ0MCANJWQgIBQoGAwEFEgA/Mz8zEjkvKxESATk5ETMRMxEzETMxMCEjESERIxEzESERMwUfqvz+qqoDAqoCsP1QBbb9kgJuAAABAFQAAAJWBbYACwA3QBwFAQoDCAAAAwEDDA0JBAYESlkGAwoDAQNKWQESAD8rEQAzGD8rEQAzERIBFzkRMxEzETMxMCEhNTcRJzUhFQcRFwJW/f6srAICrKxiIwSqJWJiJftWIwAB/2D+fwFoBbYADQAdQA0LCAgODwkDAAVJWQAiAD8rABg/ERIBOREzMTADIic1FjMyNjURMxEUBgxeNkdNY2eqwP5/G5EUeHEFtvpYvtEAAAEAyQAABOkFtgALACpAFQgEBAUFAgsKAAUNDAIIBQkGAwEFEgA/Mz8zEjk5ERIBFzkRMxEzMTAhIwEHESMRMxEBMwEE6cj965mqqgKXyf20AsWI/cMFtv0rAtX9hQABAMkAAAP4BbYABQAfQA4DAAAEBgcBAwADSVkAEgA/KwAYPxESATk5ETMxMDMRMxEhFcmqAoUFtvrkmgABAMkAAAZxBbYAEwAyQBgIBQUGCw4ODQYNFBUBChEDBgsHAw4ABhIAPzMzPzMSFzkREgE5OREzETMRMxEzMTAhASMWFREjESEBMwEzESMRNDcjAQNQ/hAIDp0BAAHPCAHT/qoOCP4MBRCa1PxeBbb7SgS2+koDrqK++vIAAQDJAAAFPwW2ABAALkAVCQYGBwEPDwAHABESCwMHDwgDAQcSAD8zPzMSOTkREgE5OREzETMRMxEzMTAhIwEjFhURIxEzATMmAjcRMwU/wvzhCBCdwAMdCAIOAp8Ey9i0/MEFtvs6GwElPwNHAAACAH3/7AW+Bc0ACwAXAChAFBIADAYABhkYCRVJWQkEAw9JWQMTAD8rABg/KxESATk5ETMRMzEwARAAISAAERAAISAAARASMzISERACIyICBb7+nf7E/r3+oQFgAUQBOwFi+3P98fP49/Lz/QLd/qH+bgGLAWgBZQGJ/nD+oP7X/s0BMgEqAScBMf7NAAIAyQAABGgFtgAJABIANEAaCgUFBg4ABgATFAoESlkKCgYHBxJKWQcDBhIAPz8rERIAORgvKxESATk5ETMRMxEzMTABFAQhIxEjESEgATMyNjU0JiMjBGj+0f7mrKoBewIk/QuZ4sq+yb4EDN7v/cEFtv0bkqGRjgAAAgB9/qQFvgXNAA8AGwA0QBsQChYAAAQDCgQcHQMNBw0ZSVkNBAcTSVkFBxMAP8YrABg/KxESADkREgEXOREzETMxMAEQAgcBIwEHIAAREAAhIAABEBIzMhIREAIjIgIFvuLOAVz3/uM3/r3+oQFgAUQBOwFi+3P98fP49/Lz/QLd/uf+jEL+lgFKAgGLAWgBZQGJ/nD+oP7X/s0BMgEqAScBMf7NAAIAyQAABM8FtgAMABUASEAlDQEBAgwJEQcLCgoHCQIEFhcJDQANAEpZDQ0CAwMVSVkDAwsCEgA/Mz8rERIAORgvKxESADkREgEXOREzETMRMxEzETMxMAERIxEhIAQVEAUBIwElMzI2NTQmIyMBc6oBkQENAQH+2gGNyf6e/s/ptKirvd0CYP2gBbbOz/7eZv1vAmCSj4+RgAABAGr/7AQCBcsAJAA0QBseEwwAABgTBQQlJgweAxYWG0lZFgQDCUlZAxMAPysAGD8rERIAOTkREgEXOREzETMxMAEUBCMgJzUWFjMyNjU0JiYnJiY1NDYzMhcHJiMiBhUUFhYXFhYEAv7o8P78jFrUaKqsPY+SzK/+0dq3NbWrh5g4hYnmrQGFwdhDpCYsgXNMYVI0ScihqchQlEx0Z0xhUTFSvAAAAQASAAAEWgW2AAcAJEASAAEFAQMDCAkHAwQDSVkEAwESAD8/KxEAMxESARc5ETMxMCEjESE1IRUhAouq/jEESP4xBR+XlwAAAQC6/+wFGQW2ABEAJUAREAEKBwEHExIRCAMEDUlZBBMAPysAGD8zERIBOTkRMxEzMTABERQAISAANREzERQWMzI2NREFGf7S/vj++P7fqsjCucgFtvxO+v7iASD8A678RrfExbgDuAABAAAAAATDBbYACgAaQAsBBAwLCAMABAMDEgA/PzMSORESATk5MTABMwEjATMBFhc2NwQMt/3xqP30tAFQOiIkOgW2+koFtvxOo5qioQABABsAAAdMBbYAGQAkQBAZChsaFQ4OBQkYEQoDAQkSAD8zPzMzEjk5ETMREgE5OTEwISMBJiYnBgcBIwEzExYXNjcBMwEWFzY3EzMFxaj+2RU0ARYw/uKo/nu05zAWGzUBBrQBEzAhEzXmtAPTQcYUhJ38MwW2/Hm+mrevA3n8f5vDjswDhQAAAQAIAAAElgW2AAsAI0ASBAYFCwoABg0MAggECQYDAQQSAD8zPzMSOTkREgEXOTEwISMBASMBATMBATMBBJbB/nf+cLQB5v47vAFrAW61/jsCg/19AvwCuv29AkP9TAAAAQAAAAAEewW2AAgAIEAPBAUCBQcDCQoABQEHAwUSAD8/MxI5ERIBFzkRMzEwAQEzAREjEQEzAj0Bhrj+GKz+GboC2wLb/IH9yQIvA4cAAQBSAAAEPwW2AAkAK0AXCAEDBwAHBAEECgsFBElZBQMBCElZARIAPysAGD8rERIBFzkRMxEzMTAhITUBITUhFQEhBD/8EwMI/RADv/z4Ax6FBJiZhftpAAEApv68Am8FtgAHACBADgYBBAABAAgJBQIDBgEnAD8zPzMREgE5OREzETMxMAEhESEVIREhAm/+NwHJ/t8BIf68BvqN+iEAAAEAFwAAAt0FtgADABO3AwEEBQMDAhIAPz8REgE5OTEwEwEjAboCI6b94AW2+koFtgAAAQAz/rwB/AW2AAcAIEAOAwABBgAGCAkABycDBAMAPzM/MxESATk5ETMRMzEwFyERITUhESEzASH+3wHJ/je2Bd+N+QYAAAEAMQInBCMFwQAGABhACQADBwgFAgAEAgAvLzMSORESATk5MTATATMBIwEBMQGyYwHdmP6M/rICJwOa/GYC6f0XAAH//P7FA5r/SAADABG1AAUBBAECAC8zEQEzETMxMAEhNSEDmvxiA57+xYMAAQGJBNkDEgYhAAkAE7YABAsKBoABAC8azRESATk5MTABIyYmJzUzFhYXAxJuQbIoyyByLATZNMA/FUW1NQACAF7/7APNBFoAGQAkAEdAJSIICx4eGRkSCAMlJgECCx5HWQILCwAVFQ9GWRUQBRpGWQUWABUAPz8rABg/KxESADkYLzkrEQAzERIBFzkRMxEzETMxMCEnIwYGIyImNRAlNzU0JiMiByc2NjMyFhURJTI2NTUHBgYVFBYDUiEIUqN6o7kCE7pveomtM1HBYcS9/g6bsabGr22cZ0momwFMEAZEgXtUfywyrsD9FHWqmWMHB21zWl4AAgCw/+wEdQYUABMAHwBEQCIKFxcPDwwdAwwDICENAAwVEhEKEQYABhpGWQYWABRGWQAQAD8rABg/KxESADk5ETMYPz8REgE5OREzETMRMxEzMTABMhIREAIjIiYnIwcjETMRFAczNhciBhUUFjMyNjU0JgKu2O/x1muxPAwjd6YICHTMqpaaqpmWlgRa/tn+8v7y/tVPUo0GFP6Gf2Wki8Pn58ff0dbSAAABAHP/7AOLBFwAFgAmQBQPAwMVCQMYFwYNRlkGEAASRlkAFgA/KwAYPysREgEXOREzMTAFIgAREAAzMhYXByYmIyARFBYzMjcVBgJm7v77AQn1T54tMzeCMv6yo6CJkG4UASUBDAETASwiF40WHf5Wytg7kzkAAgBz/+wENwYUABIAHwBCQCEdBhcADg4RBhEgIRIVDwAAAQEMAwkJGkZZCRADE0ZZAxYAPysAGD8rERIAOTkRMxg/PxESATk5ETMRMzMRMzEwJSMGIyICERASMzIXMycnETMRIyUyNjU1NCYjIgYVFBYDmglz5dfv8Nbfdw0HBKaH/p6qmZuqkpuak6cBJgEPAQ8BLKJPTQG++ex3uc4j6cfjz9LWAAIAc//sBBIEXAATABoAO0AfGAoXCwMDEQoDHBsXC0ZZFxcABgYURlkGEAAORlkAFgA/KwAYPysREgA5GC8rERIBFzkRMzMRMzEwBSIAERAAMzISFRUhFhYzMjcVBgYDIgYHITQmAn/z/ucBBdzO8P0NBbmosa1YnZyEnQ4CPYwUASgBBwEJATj+8d5pwchKlCYhA+WsmJ2nAAABAB0AAAMOBh8AFAA5QB0UDAwTAgIHAwUDFRYKD0ZZCgABBQcFRlkTBw8DFQA/PzMrEQAzGD8rERIBOTkRMzMRMzMSOTEwASERIxEjNTc1ECEyFwcmIyIGFRUhAp7+6abExAFhV3UrYEReWgEXA8f8OQPHSzw9AZQjhR99ikcAAAMAJ/4UBDEEXAAqADcAQQBuQD4rGTglDB89BTETARMFAioiHB8lGQpCQxwPNQ81RlkIO0dZCiIIKg8IDwgWKioCR1kqDyg/R1koEBYuR1kWGwA/KwAYPysAGD8rERIAOTkYLy8REjk5KysREgA5ERIBFzkRMxEzETMRMxEzMTABFQcWFhUUBiMiJwYVFBYzMzIWFRQEISImNTQ2NyYmNTQ2NyYmNTQ2MzIXARQWMzI2NTQmIyMiBhMUFjMyNTQjIgYEMcscLNzAMStqSlrCsr/+3P7o1+mAdCo5QEVVa9jGVkX+EZaM0clumMdxflqCdPP2dX4ESGkYI3FHocAIOFUtK5aPtr+gkmSSGhNQNTxaKiOobLTDFPsAWVx9a1lFbAM8c3bs934AAQCwAAAERAYUABYAM0AZDgwICAkAFgkWFxgOCRISBEZZEhAKAAAJFQA/Mz8/KxESADkREgE5OREzETMRMzMxMCERNCYjIgYVESMRMxEUBzM2NjMyFhURA556gq2fpqYICjG1dMnJAsWGhLzW/cMGFP4pVThPW7/Q/TUAAAIAogAAAWYF3wADAA8AI0ARCgAABAEBEBENB0hZDQIPARUAPz/OKxESATkRMzMRMzEwISMRMwM0NjMyFhUUBiMiJgFWpqa0OCooOjooKjgESAEpOTU2ODg3NwAAAv+R/hQBZgXfAAwAGAAsQBYTCwsNCAgZGhYQSFkWQAkPAAVGWQAbAD8rABg/Gs4rERIBOREzMxEzMTATIic1FjMyNjURMxEQAzQ2MzIWFRQGIyImK187RUNOSaa0OCooOjooKjj+FBmHFFVXBPz7EP68B105NTY4ODc3AAEAsAAABB0GFAAQADZAGxAOCgoLCwgGBAUIBBESDAAAEBAICAMHCxUDDwA/PzMSOS85ETM/ERIBFzkROREzETMzMTABNjcBMwEBIwEHESMRMxEUBwFUK1gBYsX+RAHbyf59faSkCAIxPWMBd/4t/YsCBmz+ZgYU/Mc3cwABALAAAAFWBhQAAwAWQAkAAQEEBQIAARUAPz8REgE5ETMxMCEjETMBVqamBhQAAQCwAAAGywRcACMARkAjFREREggJACMJEiMDJCUcFhUVEhkEDRkNRlkfGRATDwkAEhUAPzMzPz8zKxEAMxESORgvMzMREgEXOREzETMRMxEzMTAhETQmIyIGFREjETQmIyIGFREjETMXMzY2MyAXMzY2MzIWFREGJXB2m5SmcHeckaaHGwgvq2oBAU8IMbp3urkCyYODsrn9nALJg4O71f3BBEiWUFq6VmS/0v01AAABALAAAAREBFwAFAAxQBgAFAwICAkUCRYVDAkQEARGWRAQCg8ACRUAPzM/PysREgA5ERIBOTkRMxEzETMxMCERNCYjIgYVESMRMxczNjYzMhYVEQOeeoKsoKaHGwgzuHHGyALFhoS61v3BBEiWUVm/0v01AAIAc//sBGIEXAAMABgAKEAUEwANBwAHGhkKFkZZChADEEZZAxYAPysAGD8rERIBOTkRMxEzMTABEAAjIiYCNRAAMzIAARQWMzI2NTQmIyIGBGL+8u6T5HwBDO7mAQ/8vaijo6mppaOmAiX+9P7TigECrQEMASv+zv770tzb09HZ1gACALD+FAR1BFwAFAAhAD9AIBkLBAcHCB8SCBIiIwQLAA8PFUZZDxAJDwgbABxGWQAWAD8rABg/Pz8rERIAOTkREgE5OREzETMRMzMzMTAFIiYnIxYVESMRMxczNjYzMhIREAIDIgYHFRQWMzI2NTQmAq5rsTwMDKaHFwhAqm7a7fHuqJYCmqqOoaEUT1JgVv49BjSWWlD+1v7z/vL+1QPjussl58fmys3bAAIAc/4UBDcEXAAMAB8AREAiChAdFgMaGhkQGSAhGhsXDx0eHhYNExMHRlkTEA0ARlkNFgA/KwAYPysREgA5OREzGD8/ERIBOTkRMxEzMzMRMzEwJTI2NzU0JiMiBhUUFhciAhEQEjMyFzM3MxEjETQ3IwYCTqaYBZypkpuZfdTu8NbheQkYg6YLDXN3stMl5srjz8/ZiwEqAQsBDQEuqpb5zAHVZEanAAEAsAAAAycEXAAQACpAFA0JCQoKAhESCw8NAAoVAAVGWQAQAD8rABg/Ejk/ERIBOTkRMxEzMTABMhcHJiMiBhURIxEzFzM2NgKkSToXRDSFvaaJEwg9rARcDJoP2KH9tARIy2t0AAEAav/sA3MEXAAkADZAHB4TDAAAGAUTBCUmDB4DFhYbRlkWEAYDCUZZAxYAPysAGC8/KxESADk5ERIBFzkRMxEzMTABFAYjIic1FhYzMjY1NCYnLgI1NDYzMhcHJiMiBhUUFhYXFhYDc+TO2npPtVSCjG+hmYE/2r6xqTulhnZ4LWSOw4kBK5mmRZooLlNVQFs+OVVsS4abSIdESkEsPjg1R5AAAQAf/+wCqAVGABYANEAbEBQUCQsJEgMEGBcKExATR1kOQBAPBwBGWQcWAD8rABg/Gs0rEQAzERIBFzkRMxEzMTAlMjY3FQYGIyARESM1NzczFSEVIREUFgISLFIYG2kq/sKdnUZgAT7+wl51DQd/DREBTwKMUEXq/oH9e2NqAAABAKT/7AQ5BEgAFAA0QBkBEwcMDAoTChUWDA0NEAgUDxAERlkQFgsVAD8/KwAYPzMSOREzERIBOTkRMxEzETMxMAERFBYzMjY1ETMRIycjBgYjIiY1EQFMeoKsn6aJGAkztXTIxwRI/TmGhLzVAkD7uJNRVr7RAs0AAAEAAAAABAIESAALABhACgEKDA0FCQEPABUAPz8zORESATk5MTAhATMTFhczNhITMwEBoP5gsuxQDggLdcyy/mAESP125EQ1AU0CMPu4AAEAFwAABiMESAAcACxAFAkbHR4XFg4NAwQNBAgaEgkPAAgVAD8zPzMzEjk5ETMRMzMzERIBOTkxMCEDJicjBgcDIwEzEhIXMzY2NxMzExYXMzY2EzMBBC/JEzQIKB7PwP7VrmpvCAgLMRLJtMQ4FAgEI7+s/tECgzvRr1/9fwRI/mP+UEs5tTUCdf2LrHUklgLc+7gAAAEAJwAABAgESAALACJAEQcFBgABBQwNCQMBCAsVBAEPAD8zPzMSOTkREgEXOTEwAQEzAQEzAQEjAQEjAbj+g70BIQEgu/6DAZG8/s3+yrwCMQIX/lwBpP3p/c8BvP5EAAEAAv4UBAYESAAVACRAEgkPAAMWFwQNAA0SRlkNGwgADwA/Mj8rERIAORESARc5MTATMxMWFzM2NhMzAQYGIyInNRYzMjc3ArLwTxMIDVPmsv4pRruITEo3RKtJPQRI/Y/WXzP3Anz7ILmbEYUMwJwAAAEAUgAAA20ESAAJACtAFwgBAwcABwQBBAoLBQRHWQUPAQhHWQEVAD8rABg/KxESARc5ETMRMzEwISE1ASE1IRUBIQNt/OUCVv3PAuf9sgJdcQNWgYH8ugABAD3+vALBBbYAHAAsQBUZGhoLFwAADwcUAwMHCwMdHhMDBCcAPz8REgEXOREzETMzETMRMxEzMTAlFBYXFSYmNRE0JiM1NjY1ETQ2MxUGFREUBxUWFQHbdXG+0H54gnTYtubf3wxmXAKMAqqaAS9oWY0CXGABMpusiwbB/tnXJwwn1wABAe7+EAJ7BhQAAwAWQAkCAwMEBQMbAAAAPz8REgE5ETMxMAEzESMB7o2NBhT3/AABAEj+vALLBbYAHQAsQBUVBQoSEgIZAB0dDg4ZBQMeHxUnBgMAPz8REgEXOREzETMRMzMRMxEzMTABJjURNCc1MhYVERQWFxUiBhURFAYHNTY2NRE0NjcCCt/juNN2gnp+zb5vdG5xAj8n1wEnwQaLrpn+zmFbAo1ZaP7RmasCjAJcZgEpcngUAAABAGgCUAQpA1QAFwAkQBEDDxgZEgxQWQMSDwYGAFBZBgAvKwAQGMQvxCsREgE5OTEwASIGBzU2MzIWFxYWMzI2NxUGIyImJyYmAVI1fzZkkERxWUJiLzaANmaOSH5IS1oCyUM2l20cJhwbQDmWbiEgIBgAAAIAmP6LAYkEXgADAA4AK0AUAgQEAwkJDxAAAAMMDAZPWQwQAyIAPz8rERIAORgvERIBOREzMxEzMTATMxMjExQjIiY1NDYzMhbbaTPP4Xk8PD85M0YCrPvfBUyHR0A/SEAAAQC+/+wD2wXLABsAPkAeFggNAwMKBAAQEAQIAxwdGQUCEwoNAg0CDQQLBwQZAD8/Ejk5Ly8RMzMRMzMREgEXOREzETMzETMRMzEwJQYHFSM1JgI1ECU1MxUWFhcHJiMiBhUUFjMyNwPLaZOFy8EBjIdLjjExhW2sop+njY7wNgbIziABEfoB/D6spAMhF4wz09nUyzsAAQA/AAAERAXJAB0ASEAmGBMJDQ0aFhECCxYTBR4fDBgZGE5ZCRkZEwATEExZExgABUtZAAcAPysAGD8rERIAORgvMysRADMREgEXOREzMxEzETMxMAEyFwcmIyIGFREhFSEVFAYHIRUhNTY1NSM1MxE0NgKqvqo9mo97fQGm/lpBSgMb+/vNxsbgBclUhU18jP7Zf91kiCyajS/0338BPLLNAAACAHsBBgQXBKAAGwAnACBADRwAIg4ADigpHxUVJQcALzMzLzMREgE5OREzETMxMBM0Nyc3FzYzMhc3FwcWFRQHFwcnBiMiJwcnNyY3FBYzMjY1NCYjIga4Sodeh2iCf2aJX4ZKSoNciWZ/hmSHXIVKgZ10dJ6gcnSdAtN6a4xchUlJhVyKcXaDZ4dchUdJhVyIa3xwoJ9xcqKkAAABAB8AAARxBbYAFgBWQC4SDgcLCxAMBQkCCQMMFA4VBxcYCg4OBw8GEhIDABMVDxMfEwIPEw8TDAEVBgwYAD8/MxI5OS8vXRESOTIyETMRMzMRMxESARc5ETMRMzMRMxEzMTABATMBIRUhFSEVIREjESE1ITUhNSEBMwJIAXuu/mABBv7DAT3+w6T+xAE8/sQBAP5lsgLfAtf8/n+qf/70AQx/qn8DAgACAe7+EAJ7BhQAAwAHACRAEAIGBgMHBwgJBAMEAwcbAAAAPz85OS8vERIBOREzMxEzMTABMxEjETMRIwHujY2NjQYU/Pj+Dfz3AAIAe//4A5YGHQAxAD0AQ0AmMgATBioeOBkZHgwGACMGPj8VAzs2HC0GIQkhJ0dZIRUJEEdZCQAAPysAGD8rERIAFzkREgEXOREzETMRMxEzMTATNDY3JiY1NDYzMhYXByYmIyIGFRQWFxYWFRQGBxYVFAYjIic1FhYzMjY1NCYmJy4CNxQWFxc2NTQmJwYGi1ZOSlTPxV6fYTVih0x0dHuaupZSSpnq1NqATsJSho0wbHOOhkKShKcxiZO5RFUDKVaJJShvVXmLHSeDJxs7QDxUN0SXa1qNKVGSjJlBlCUtTEcuOjorNFpyYk1pPRNQb1NwORNkAAIBNQUOA2gF0wALABcAHkAMBgAMEgASGBkPAxUJAC8zzTIREgE5OREzETMxMAE0NjMyFhUUBiMiJiU0NjMyFhUUBiMiJgE1NSUmNzcmJTUBfTUlJTc3JSU1BXE0Li40MjExMjQuLjQyMTEAAAMAZP/sBkQFywAWACYANgBGQCcnFwMPLx8fFAkPFwU3OAYMABIPDB8MAgASEBICDBIMEhsrIxMzGwQAPzM/MxI5OS8vXV0RMxEzERIBFzkRMxEzETMxMAEiBhUUFjMyNxUGBiMiJjU0NjMyFwcmATQSJDMyBBIVFAIEIyIkAjcUEgQzMiQSNTQCJCMiBAIDfX2Hf4NWfTBlRsLQ3b+Adjps/JfIAV7KyAFeysL+otDP/qLDaa4BLayuASqvrv7XsK7+1q8EI66aqKItfBQc8djR9jx2M/64yAFeysj+osrF/qbQzwFaxq3+062uASmwrgEqr67+1wAAAgBGAxQCcQXHABYAHwA3QBwXBhsKAQEWFhAGAyAhHAoKEhkWAAMQAwIDDRIfAD8z1F3EMxI5LzMREgEXOREzETMzETMxMAEnBiMiJjU0Njc3NTQjIgcnNjMyFhURJRQzMjU1BwYGAhQYXIxfb5qldZRkaCtyhYKJ/lBwyWJwZwMhVGFjZmZpBgQnhTNgOGl5/jy8ZLQxBAQ5AAIAUgB1A6oDvgAGAA0AKUATAwYKDQIECwkJBA0GBA4PDAUIAQAvMy8zERIBFzkRMxEzETMRMzEwEwEXAQEHASUBFwEBBwFSAVZ3/t8BIXf+qgGLAVh1/uEBH3X+qAInAZdF/qL+oUcBlxsBl0X+ov6hRwGXAAABAGgBCAQpAxcABQAbQAwCAQQBBgcFBFBZBQIALy8rERIBOTkRMzEwAREjESE1BCmJ/MgDF/3xAYWKAP//AFQB2QI/AnECBgAQAAAABABk/+wGRAXLAAgAFgAmADYAXUAzJxcAERESBAkvHx8NCQwSFwY3OAwQEAAADhMOEggTDxIfEgIAExATAhITEhMbKyMTMxsEAD8zPzMSOTkvL11dETMRMxESOS8zETMREgEXOREzETMRMxEzETMxMAEzMjY1NCYjIwUUBgcTIwMjESMRITIWATQSJDMyBBIVFAIEIyIkAjcUEgQzMiQSNTQCJCMiBAIC02xQYVZdagGyVU3uqM+HlAEFppv738gBXsrIAV7Kwv6i0M/+osNprgEtrK4BKq+u/tewrv7WrwL6U0BLQYhQex7+dQFi/p4De4L+xcgBXsrI/qLKxf6m0M8BWsat/tOtrgEpsK4BKq+u/tcAAf/6BhQEBgaTAAMAEbUABQEEAQIALzMRATMRMzEwASE1IQQG+/QEDAYUfwACAH8DXALuBcsADAAYACFADg0AEwYABhkaEArAFgMEAD8zGswyERIBOTkRMxEzMTATNDYzMhYVFAYGIyImNxQWMzI2NTQmIyIGf7WCgrZSklSCtXN1UVBzcVJTcwSTgra1g1SPVLSDUnJxU1RxcgD//wBoAAEEKQTDAiYADgAAAAcCKwAA/XQAAQAxAkoCjQXJABgAI0ARBxMXAQEOEwAEGhkKEB8XASAAPzM/MxESARc5ETMRMzEwASE1Nz4CNTQmIyIGByc2MzIWFRQGBwchAo39pOxZUiFQPzRiRUKDmISTWZOuAbgCSmjmVmFMNkRFJjJYb4JwUJeKpQABACECOQKNBckAIwA5QCIPBQUAAxIeCgYkJRJdE20TAkwTAQsTGxMCExMIGiEfDQghAD8zPzMSOS9dXV0zERIBFzkRMzEwARQGBxYVFAYjIic1FjMyNTQjIzUzMjY1NCYjIgYHJzY2MzIWAnNSRLC4qJh0k3vT53V3Z2NQQ0JwOEU/jF6InQTnUGcXL6KAjzh7RKKRa09EPUQrI1otNncAAQGJBNkDEgYhAAkAE7YJBAoLBIAJAC8azRESATk5MTABNjY3MxUGBgcjAYkwbyDKLK5AbwTyPrBBFUG+NAABALD+FAREBEgAFgA1QBoFCgoIEAATExQIFBgXBhUPFBsNAkZZDRYJFQA/PysAGD8/MxESATk5ETMRMzMRMxEzMTABEDMyNjURMxEjJyMGIyInIxYVESMRMwFW/qufpogaCm/lllgKCqamAX3++r3UAkD7uJOnXFSg/sAGNAABAHH+/ARgBhQADwAnQBIEBQEAAAULAxARCAgFAw8FAQUALzM/MxI5LxESARc5ETMRMzEwASMRIxEjEQYjIiY1EDYzIQRgctVzPlTYy9roAi3+/Aaw+VADMxL6+wEE/gABAJgCTAGJA1oACwAXQAoGAAANDAMJT1kDAC8rERIBOREzMTATNDYzMhYVFAYjIiaYPjg6QUI5M0MC00JFRUJBRj8AAAEAJf4UAbQAAAASACRAEBEOCwAADgUDExQOEREIAxAAL8wyOS8zERIBFzkRMxEzMTABFAYjIic1FjMyNjU0Jic3MwcWAbSZljMtLTtPUU9tWG43tP7fYWoJaggoNis1EbJzJwABAEwCSgHhBbYACgAgQA4CAAMDCgwLCQkDIAYAHgA/Mj85LxESATk5ETMzMTABMxEjETQ3BgYHJwFSj4UGFjaHQwW2/JQCQ1taFi1fYAACAEIDFAK+BccACwAXACVAEgwGEgAGABgZDwADEAMCAxUJHwA/M8RdMhESATk5ETMRMzEwARQGIyImNTQ2MzIWBRQWMzI2NTQmIyIGAr6rlpKpqJeYpf3+W2hpXFxpZ1wEb6S3uqGjtbaienp6ent2dgACAFAAdQOoA74ABgANACNAEQsJBAIAAwcCCgkGDg8MBQgBAC8zLzMREgEXOREzETMxMAEBJwEBNwEFAScBATcBA6j+qHUBH/7hdQFY/nX+qHUBH/7hdQFYAgz+aUcBXwFeRf5pG/5pRwFfAV5F/mn//wBLAAAF0QW2ACcCFwKDAAAAJgB7/wABBwI8Ax39twAJswMCEhgAPzU1AP//AC4AAAXbBbYAJwIXAj8AAAAmAHviAAEHAHQDTv23AAeyAhAYAD81AP//ABoAAAYhBckAJgB1+QAAJwIXAt8AAAEHAjwDbf23AAmzAwIrGAA/NTUAAAIAM/53A1QEXgAdACgAQUAiCBQeIwEcDxwjFAQpKgAdAQwDHR0RJiYgT1kmEBELSVkRIwA/KwAYPysREgA5GC9fXl0REgEXOREzETMRMzEwARUUBgcOAhUUFjMyNjcXBiMiJjU0PgI3NjY1NRMUIyImNTQ2MzIWAk5LYXk9GYR6UJZiO8XGvtgjQFk2ZUG0eTs+QjczRgKsM3qUVGpLTThkcSYwh2C6qkZpWVIvWHRdHwErh0VCQEdA//8AAAAABRAHcwImACQAAAEHAEP/wgFSAAizAhAFJgArNf//AAAAAAUQB3MCJgAkAAABBwB2AIUBUgAIswIYBSYAKzX//wAAAAAFEAdzAiYAJAAAAQcBSwAjAVIACLMCHQUmACs1//8AAAAABRAHLwImACQAAAEHAVIABAFSAAizAhgFJgArNf//AAAAAAUQByUCJgAkAAABBwBqADcBUgAKtAMCJAUmACs1Nf//AAAAAAUQBwYCJgAkAAAABwFQADkAgQAC//4AAAaBBbYADwATAE5ALAoODhEBAAgMARAFBRUFFAkTBhNJWRADSVkKDUlZEAoQCgEGAwUSAQ5JWQESAD8rABg/PxI5OS8vKysrEQAzEQEzERIXOREzMxEzMTAhIREhAyMBIRUhESEVIREhASERIwaB/RL9/uOwAroDyf28Ah394wJE+1QBvnYB0f4vBbaX/imW/eYB0gK1AP//AH3+FATPBcsCJgAmAAAABwB6AgIAAP//AMkAAAP4B3MCJgAoAAABBwBD/7cBUgAIswENBSYAKzX//wDJAAAD+AdzAiYAKAAAAQcAdgA/AVIACLMBFQUmACs1//8AyQAAA/gHcwImACgAAAEHAUv/+wFSAAizARoFJgArNf//AMkAAAP4ByUCJgAoAAABBwBqABIBUgAKtAIBIQUmACs1Nf//ADwAAAJWB3MCJgAsAAABBwBD/rMBUgAIswENBSYAKzX//wBUAAACcwdzAiYALAAAAQcAdv9hAVIACLMBFQUmACs1/////wAAAqEHcwImACwAAAEHAUv+8wFSAAizARoFJgArNf//ADwAAAJvByUCJgAsAAABBwBq/wcBUgAKtAIBIQUmACs1NQACAC8AAAVIBbYADAAXAFdAMhEVFQgEDQAAEwQGBBgZFAYHBklZEQ8HPwevB88H3wcFCwMHBwQJCRBKWQkDBBVKWQQSAD8rABg/KxESADkYL19eXTMrEQAzERIBFzkRMxEzMxEzMTABEAAhIREjNTMRISAAAxAhIxEhFSERMyAFSP53/o/+e5qaAbIBUQF8tf3H5wF7/oW+AmIC6f6W/oECiZYCl/6J/qQCQP38lv4K//8AyQAABT8HLwImADEAAAEHAVIAkwFSAAizARoFJgArNf//AH3/7AW+B3MCJgAyAAABBwBDAHkBUgAIswIZBSYAKzX//wB9/+wFvgdzAiYAMgAAAQcAdgEKAVIACLMCIQUmACs1//8Aff/sBb4HcwImADIAAAEHAUsAtAFSAAizAiYFJgArNf//AH3/7AW+By8CJgAyAAABBwFSAJoBUgAIswIhBSYAKzX//wB9/+wFvgclAiYAMgAAAQcAagDVAVIACrQDAi0FJgArNTUAAQCFARAEDASYAAsAGUAJBwkDAQkBDA0IABkvERIBOTkRMxEzMTABFwEBBwEBJwEBNwEDrGD+oAFeYP6e/qRlAV7+oGQBYQSYY/6e/qBjAV/+oWMBYAFgZf6dAAADAH3/wwW+BfYAEwAbACMATkAsFh8XHgQcFBwKFAAAEg8FCAoGJCUWHiEZDSFJWQ8SCAUEAxANBAMZSVkGAxMAP8YrABg/xhIXOSsREgA5ORESARc5ETMRMxESFzkxMAEQACEiJwcnNyYREAAhMhc3FwcWAxAnARYzMhIBEBcBJiMiAgW+/p3+xOuUZXhssgFgAUTRnWF4asC0bv1gc7Dz+PwnZQKdaqjz/QLd/qH+bmSNT5rGAW0BZQGJXodQlMr+lQEQmvxMUgEyASr++poDr0n+zQD//wC6/+wFGQdzAiYAOAAAAQcAQwBGAVIACLMBEwUmACs1//8Auv/sBRkHcwImADgAAAEHAHYAzwFSAAizARsFJgArNf//ALr/7AUZB3MCJgA4AAABBwFLAH0BUgAIswEgBSYAKzX//wC6/+wFGQclAiYAOAAAAQcAagCYAVIACrQCAScFJgArNTX//wAAAAAEewdzAiYAPAAAAQcAdgAxAVIACLMBEgUmACs1AAIAyQAABHkFtgAMABUANkAcDQkFBQYRAAYAFhcNBEpZCRVKWQ0JDQkGBwMGEgA/PxI5OS8vKysREgE5OREzETMRMzMxMAEUBCEjESMRMxEzIAQBMzI2NTQmIyMEef7R/uG4qqrXARkBFvz6qOLKvsrMAxDj7v7BBbb/AM/96o+klYoAAAEAsP/sBJwGHwAwAEFAIikqBR0jABcMDAAdESoFMTISEiouLiZGWS4AKhUPFUZZDxYAPysAGD8/KxESADkYLxESARc5ETMRMxEzETMxMAEUBwYGFRQWFhcWFhUUBiMiJzUWFjMyNTQmJyYmNTQ2NzY2NTQmIyAVESMRNDYzMhYEGY9YOBtHToxmwrO8az+cSNdTbn9gRUdLQIh//uym3N7O4QTyh3NGQyEgKjkzX51loKtFmicvtktrRlJ7VD9qNTlaNVBV3/tMBLKyu53//wBe/+wDzQYhAiYARAAAAQYAQ44AAAizAiYRJgArNf//AF7/7APNBiECJgBEAAABBgB2KwAACLMCLhEmACs1//8AXv/sA80GIQImAEQAAAEGAUvYAAAIswIzESYAKzX//wBe/+wDzQXdAiYARAAAAQYBUr0AAAizAi4RJgArNf//AF7/7APNBdMCJgBEAAABBgBq4gAACrQDAjoRJgArNTX//wBe/+wDzQaFAiYARAAAAQYBUPcAAAq0AwIoESYAKzU1AAMAXv/sBnMEXAApADQAOwBhQDMqACQRMDgZGQQwORgYHzALAAU8PRstJy1GWRkxBDFHWTgkJxEEBA4iJxY1CA4IRlkUDhAAPzMrEQAzGD8zEjkvORI5MysRADMrEQAzERIBFzkRMxEzMxEzEjk5ETMxMBM0Njc3NTQmIyIHJzY2MzIWFzY2MzISFRUhEiEyNjcVBgYjICcGBiMiJjcUFjMyNjU1BwYGASIGByE0Jl74/rh0d5CjNErHYoKlKTWrbsDo/UMIATpbnVRWlWX+331RxYajua5rWJGonrqkA715iwsCB4ABL6GzCAZEgXtUfyk1V19YYP713mv+dSMnlCYh6X9qqpdfWamaYwcIbQIypp6cqAD//wBz/hQDiwRcAiYARgAAAAcAegFGAAD//wBz/+wEEgYhAiYASAAAAQYAQ7UAAAizAhwRJgArNf//AHP/7AQSBiECJgBIAAABBgB2TgAACLMCJBEmACs1//8Ac//sBBIGIQImAEgAAAEGAUv3AAAIswIpESYAKzX//wBz/+wEEgXTAiYASAAAAQYAagoAAAq0AwIwESYAKzU1////2gAAAWMGIQImAPMAAAEHAEP+UQAAAAizAQURJgArNf//AKkAAAIyBiECJgDzAAABBwB2/yAAAAAIswENESYAKzX///+zAAACVQYhAiYA8wAAAQcBS/6nAAAACLMBEhEmACs1////7AAAAh8F0wImAPMAAAEHAGr+twAAAAq0AgEZESYAKzU1AAIAcf/sBGIGIQAbACYASkArIQYMHBwAABgZFg4RExAGCScoCR9GWQsDFhEZDg8FFAkJAxcUAQMkRlkDFgA/KwAYPzMSOS8SFzkSOSsREgEXOREzETMRMzEwARAAIyIANTQAMzIXNyYnBSc3Jic3Fhc3FwcWEgM0JiMgERQWMzI2BGL++/fe/ukBB9ziZAg5zf7xSelcXkWcZu5Mz5ilqLSc/q+voq+hAjP+5/7SAQ3i5gEGeQTWv5tshT4xdUlLimt3j/5y/uiTqv6Yp7fJAP//ALAAAAREBd0CJgBRAAABBgFSDgAACLMBHhEmACs1//8Ac//sBGIGIQImAFIAAAEGAEPUAAAIswIaESYAKzX//wBz/+wEYgYhAiYAUgAAAQYAdlYAAAizAiIRJgArNf//AHP/7ARiBiECJgBSAAABBgFLDgAACLMCJxEmACs1//8Ac//sBGIF3QImAFIAAAEGAVLxAAAIswIiESYAKzX//wBz/+wEYgXTAiYAUgAAAQYAahsAAAq0AwIuESYAKzU1AAMAaAD8BCkEqAADAA8AGwAzQBgWCgoQBAIEAQMcHRkTEwEHDQ0BAQBQWQEALysRADMYLzMRMy8zERIBFzkRMzMRMzEwEzUhFQE0NjMyFhUUBiMiJhE0NjMyFhUUBiMiJmgDwf2uOzY0OjszND07NjQ6OzM0PQKNior+6Dw9Pzo5QD8C9Dw9Pzo5QD8AAwBz/7wEYgSHABMAGwAjAEtAKRcfHBQUChwAABIPBQgKBiQlFh4hGQ0ZRlkPEggFBAMQDRADIUZZBgMWAD/GKwAYP8YSFzkrERIAOTkREgEXOREzETMREjk5MTABEAAjIicHJzcmERAAMzIXNxcHFgUUFwEmIyIGBTQnARYzMjYEYv7y7ppwVHJegQEM7pp0VHVhf/y9NQHRS3KjpgKXM/4vR3GjqQIl/vT+00V1ToOYAQABDAErTHdMhZj5q2YChjXW1KRk/X0z2wD//wCk/+wEOQYhAiYAWAAAAQYAQ8QAAAizARYRJgArNf//AKT/7AQ5BiECJgBYAAABBgB2cQAACLMBHhEmACs1//8ApP/sBDkGIQImAFgAAAEGAUsSAAAIswEjESYAKzX//wCk/+wEOQXTAiYAWAAAAQYAaiEAAAq0AgEqESYAKzU1//8AAv4UBAYGIQImAFwAAAEGAHYSAAAIswEfESYAKzUAAgCw/hQEdQYUABYAIgA+QB8gBhsUEBARBhEkIxIAERsMFgkDCR5GWQkWAxdGWQMQAD8rABg/KxESADk5GD8/ERIBOTkRMxEzMxEzMTABNjYzMhIREAIjIicjFxYVESMRMxEUByUiBgcVFBYzIBE0JgFYQqpq1/Dx1t56DAQIpqYGAUiomAKaqgEvlAO0WU/+1P71/vT+06EiTT/+NQgA/i40Whu4ySnnxwGw19H//wAC/hQEBgXTAiYAXAAAAQYAarUAAAq0AgErESYAKzU1//8AAAAABRAGtAImACQAAAEHAU0APwFSAAizAhIFJgArNf//AF7/7APNBWICJgBEAAABBgFN9QAACLMCKBEmACs1//8AAAAABRAHNwImACQAAAEHAU4AKwFSAAizAg8FJgArNf//AF7/7APNBeUCJgBEAAABBgFO5AAACLMCJREmACs1//8AAP5CBREFvAImACQAAAAHAVEDoAAA//8AXv5CBAAEWgImAEQAAAAHAVECjwAA//8Aff/sBM8HcwImACYAAAEHAHYBCAFSAAizASAFJgArNf//AHP/7AOLBiECJgBGAAABBgB2RAAACLMBIBEmACs1//8Aff/sBM8HcwImACYAAAEHAUsArAFSAAizASUFJgArNf//AHP/7AOLBiECJgBGAAABBgFL1AAACLMBJREmACs1//8Aff/sBM8HMQImACYAAAEHAU8CGwFSAAizASAFJgArNf//AHP/7AOLBd8CJgBGAAABBwFPAVAAAAAIswEgESYAKzX//wB9/+wEzwdzAiYAJgAAAQcBTADBAVIACLMBIgUmACs1//8Ac//sA6EGIQImAEYAAAEGAUzzAAAIswEiESYAKzX//wDJAAAFWAdzAiYAJwAAAQcBTABYAVIACLMCHQUmACs1//8Ac//sBYEGFAImAEcAAAEHAjgDDAAAAAeyAiMAAD81AP//AC8AAAVIBbYCBgCSAAAAAgBz/+wE0wYUABoAJwBkQDclBhIOAB4eFRkWGRAGBCgpGhUYEBEQR1kVDxEfES8RAwkDEREJEwABDAMJCSJGWQkQAxtGWQMWAD8rABg/KxESADk5GD8SOS9fXl0zKxEAMxg/ERIBFzkRMzMRMzMzETMxMCUjBiMiAhEQEjMyFzMmNTUhNSE1MxUzFSMRIyUyNjU1NCYjIgYVFBYDmglz5dfv8Nbfdw0L/kABwKacnIf+nqqZm6qSm5qTpwEmAQ8BDwEsolNJhYG4uIH7JXe5ziPpx+PP0tb//wDJAAAD+Aa0AiYAKAAAAQcBTQASAVIACLMBDwUmACs1//8Ac//sBBIFYgImAEgAAAEGAU0KAAAIswIeESYAKzX//wDJAAAD+Ac3AiYAKAAAAQcBTgAQAVIACLMBDAUmACs1//8Ac//sBBIF5QImAEgAAAEGAU77AAAIswIbESYAKzX//wDJAAAD+AcUAiYAKAAAAQcBTwFvATUACLMBFQUmACs1//8Ac//sBBIF3wImAEgAAAEHAU8BVAAAAAizAiQRJgArNf//AMn+QgP4BbYCJgAoAAAABwFRAnMAAP//AHP+YQQSBFwCJgBIAAAABwFRAmYAH///AMkAAAP4B3MCJgAoAAABBwFMABABUgAIswEXBSYAKzX//wBz/+wEEgYhAiYASAAAAQYBTPsAAAizAiYRJgArNf//AH3/7AU9B3MCJgAqAAABBwFLAOkBUgAIswEqBSYAKzX//wAn/hQEMQYhAiYASgAAAQYBS8oAAAizA1ARJgArNf//AH3/7AU9BzcCJgAqAAABBwFOAQABUgAIswEcBSYAKzX//wAn/hQEMQXlAiYASgAAAQYBTs4AAAizA0IRJgArNf//AH3/7AU9BzECJgAqAAABBwFPAmQBUgAIswElBSYAKzX//wAn/hQEMQXfAiYASgAAAQcBTwEfAAAACLMDSxEmACs1//8Aff47BT0FywImACoAAAAHAjkBJwAA//8AJ/4UBDEGIQImAEoAAAEGAjpEAAAIswNGESYAKzX//wDJAAAFHwdzAiYAKwAAAQcBSwCWAVIACLMBGgUmACs1//8AsAAABEQHqgImAEsAAAEHAUsAHwGJAAizASUCJgArNQACAAAAAAXnBbYAEwAXAFRALBcDDw8AEBQEDAwHCwgLEBIEGBkXDklZFgoSExJKWQcDExcTFxMBDBASBQEDAD8zPzMSOTkvLxEzMysRADMzKxESARc5ETMzETMzETMzETMzMTATNTMVITUzFTMVIxEjESERIxEjNQE1IRXJqgMCqsjIqvz+qskEdfz+BL74+Pj4jfvPArD9UAQxjf6K6ekAAQAUAAAERAYUAB4AWUAyFhQQCAgNCQAeHhIJCwQfIBcWGgRGWRMLDAtHWRAMDwwfDC8MAxYaDAwaFgMJDgAACRUAPzM/Ehc5Ly8vXREzKxEAMysRADMREgEXOREzETMzETMzMzEwIRE0JiMiBhURIxEjNTM1MxUhFSEVFAczNjYzMhYVEQOeeoKunqacnKYBwf4/CAoxtXTJyQKehoS61f3nBNt/urp/xFQ4T1u/0v1c////4gAAAsoHLwImACwAAAEHAVL+2gFSAAizARUFJgArNf///5AAAAJ4Bd0CJgDzAAABBwFS/ogAAAAIswENESYAKzX//wAqAAACgga0AiYALAAAAQcBTf79AVIACLMBDwUmACs1////2gAAAjIFYgImAPMAAAEHAU3+rQAAAAizAQcRJgArNf//AB4AAAKKBzcCJgAsAAABBwFO/vkBUgAIswEMBSYAKzX////MAAACOAXlAiYA8wAAAQcBTv6nAAAACLMBBBEmACs1//8AVP5CAlYFtgImACwAAAAGAVFoAP//ADX+QgGBBd8CJgBMAAAABgFREAD//wBUAAACVgcxAiYALAAAAQcBTwBQAVIACLMBFQUmACs1AAEAsAAAAVYESAADABZACQABAQUEAg8BFQA/PxESATkRMzEwISMRMwFWpqYESP//AFT+fwQQBbYAJgAsAAAABwAtAqgAAP//AKL+FANsBd8AJgBMAAAABwBNAgYAAP///2D+fwJlB3MCJgAtAAABBwFL/rcBUgAIswEcBSYAKzX///+R/hQCTwYhAiYCNwAAAQcBS/6hAAAACLMBGxEmACs1//8Ayf47BOkFtgImAC4AAAAHAjkAiQAA//8AsP47BB0GFAImAE4AAAAGAjkrAAABALAAAAQbBEYADQAvQBkNCwcHCAMBAgUIBQ4PAg0FBgQIAAkPBAgVAD8zPzMSFzkREgEXOREzETMzMTABMwEBIwEHESMRMxEUBwMvz/5iAbvJ/peHsrIMBEb+Hv2cAfhx/nkERv7lpnH//wDJAAAD+AdzAiYALwAAAQcAdv9jAVIACLMBDwUmACs1//8AowAAAiwHrAImAE8AAAEHAHb/GgGLAAizAQ0CJgArNf//AMn+OwP4BbYCJgAvAAAABgI5MQD//wBZ/jsBVwYUAiYATwAAAAcCOf7oAAD//wDJAAAD+AW3AiYALwAAAQcCOAEd/6MAB7IBCQMAPzUA//8AsAAAAqAGFAImAE8AAAEGAjgrAAAHsgEHAAA/NQD//wDJAAAD+AW2AiYALwAAAAcBTwIE/Wf//wCwAAACqAYUACYATwAAAAcBTwFC/TgAAQAdAAAD+AW2AA0APUAhBwsLBAAMCQADBA8OCQcECgMBBggCCAIIAAUDAAtJWQASAD8rABg/Ejk5Ly8SFzkREgEXOREzMxEzMTAzEQcnNxEzESUXBREhFclpQ6yqASlD/pQChQH8O3JlAx79Rq550/48mgAB//wAAAInBhQACwA3QBwABAQJBQUMAg0IDAACCQMIBgYBBwEHAQUKAAUVAD8/Ejk5Ly8SFzkRATMRMxI5ETMzETMxMAE3FwcRIxEHJzcRMwFWiUjRpm5GtKYDYF5wjf0/AlRIcXcDIAD//wDJAAAFPwdzAiYAMQAAAQcAdgECAVIACLMBGgUmACs1//8AsAAABEQGIQImAFEAAAEGAHZ5AAAIswEeESYAKzX//wDJ/jsFPwW2AiYAMQAAAAcCOQDNAAD//wCw/jsERARcAiYAUQAAAAYCOVYA//8AyQAABT8HcwImADEAAAEHAUwApgFSAAizARwFJgArNf//ALAAAAREBiECJgBRAAABBgFMHwAACLMBIBEmACs1//8AAQAABMsFtgAnAFEAhwAAAQYCB+gAAAeyARwDAD81AAABAMn+fwU/BbYAGQA4QBwQDQ0OCBQUFxcCDgMaGxIKDhUPAw4SAAVJWQAiAD8rABg/PzMSOTkREgEXOREzETMRMxEzMTABIic1FjMyNjUBIxIVESMRMwEzJjURMxEUBgPJYjZHU2lq/MAIEJ3AAx0IDp/B/n8bkRR6bwTL/vie/NsFtvtOleADPfpYw8wAAQCw/hQERARcAB0AOEAeEw8PEAcbGwIQAx4fFwtGWRcQExARDxAVAAVGWQAbAD8rABg/PxI5PysREgEXOREzETMRMzEwASInNRYzMjURNCYjIgYVESMRMxczNjYzMhYVERQGAyVWNzw+jHqCrKCmhxsKNLRuy8eM/hQZhxSsA3mGhLrW/cEESJZSWL/S/I2aqv//AH3/7AW+BrQCJgAyAAABBwFNAMcBUgAIswIbBSYAKzX//wBz/+wEYgViAiYAUgAAAQYBTRIAAAizAhwRJgArNf//AH3/7AW+BzcCJgAyAAABBwFOAMEBUgAIswIYBSYAKzX//wBz/+wEYgXlAiYAUgAAAQYBTg4AAAizAhkRJgArNf//AH3/7AW+B3MCJgAyAAABBwFTARQBUgAKtAMCKwUmACs1Nf//AHP/7ARiBiECJgBSAAABBgFTWgAACrQDAiwRJgArNTUAAgB9/+wG5wXNABQAHwBTQC4YBg8TEx0ADREdBgUgIQ8SSVkPDwALCw5JWQsDCRVJWQkEAxtJWQMSABNJWQASAD8rABg/KwAYPysAGD8rERIAORgvKxESARc5ETMRMxEzMTAhIQYjIAAREAAhMhchFSERIRUhESEBIgAREAAzMjcRJgbn/QBmXP65/p8BXAFAZloDDv2zAif92QJN/ET5/v8BAfdwV1cUAYkBagFoAYYXl/4plv3mBJ3+z/7Z/tf+zSEEdR4AAwBx/+wHHwRaAB4AKgAxAFVALR8IDgIWFiUvFRUcJQgEMjMrKAsoRlkuFkZZAgUOCy4uBRELEBgiBSJGWQAFFgA/MysRADMYPzMSOS8SORI5KysRADMREgEXOREzETMSOTkRMzEwBSAnBgYjIgAREAAzMhYXNjYzMhIVFSESITI2NxUGBgEUFjMyNjU0JiMiBiUiBgchNCYFlv7bfT7Rid/+9AEG64PNPjrAfsnu/ScIAUpeoVdYmPshmKejmZulppUER3+RDAIghBTrdHcBMQEIAQkBLHdycHn+9+Jp/ncjJ5QnIAI509vV0d3V2Niknp6k//8AyQAABM8HcwImADUAAAEHAHYAeQFSAAizAh8FJgArNf//ALAAAAMnBiECJgBVAAABBgB23AAACLMBGhEmACs1//8Ayf47BM8FtgImADUAAAAGAjl9AP//AGD+OwMnBFwCJgBVAAAABwI5/u8AAP//AMkAAATPB3MCJgA1AAABBwFMABsBUgAIswIhBSYAKzX//wCCAAADJwYhAiYAVQAAAQcBTP92AAAACLMBHBEmACs1//8Aav/sBAIHcwImADYAAAEHAHYAUAFSAAizAS4FJgArNf//AGr/7ANzBiECJgBWAAABBgB26gAACLMBLhEmACs1//8Aav/sBAIHcwImADYAAAEHAUv/6gFSAAizATMFJgArNf//AGr/7ANzBiECJgBWAAABBgFLlwAACLMBMxEmACs1//8Aav4UBAIFywImADYAAAAHAHoBJwAA//8Aav4UA3MEXAImAFYAAAAHAHoA1QAA//8Aav/sBAIHcwImADYAAAEHAUz/5AFSAAizATAFJgArNf//AGr/7ANzBiECJgBWAAABBgFMmQAACLMBMBEmACs1//8AEv47BFoFtgImADcAAAAGAjkZAP//AB/+OwKoBUYCJgBXAAAABgI5ggD//wASAAAEWgdzAiYANwAAAQcBTP/cAVIACLMBEwUmACs1//8AH//sAtcGFAImAFcAAAEGAjhiAAAHsgEaAAA/NQAAAQASAAAEWgW2AA8AP0AhBwsLAAwECQwOAgUQEQoODw5KWQcPDwMMEgYCAwJJWQMDAD8rEQAzGD8SOS8zKxEAMxESARc5ETMzETMxMAERITUhFSERIRUhESMRITUB4f4xBEj+MQE2/sqq/scDLwHwl5f+EI39XgKijQABAB//7AKoBUYAHABMQCkXExsbDAgCFRkICg4GHR4OFhMWR1kaCgsKR1kXCwsGEUATDwYARlkGFgA/KwAYPxrNEjkvMysRADMrEQAzERIBFzkRMzMRMzMxMCUyNxUGBiMgETUjNTMRIzU3NzMVIRUhESEVIRUUAhdVPCBqKv7IjY2dnUZgAT7+wgEt/tN1FH8OEAFc/oEBAFBF6v6B/wCB9N0A//8Auv/sBRkHLwImADgAAAEHAVIAbwFSAAizARsFJgArNf//AKT/7AQ5Bd0CJgBYAAABBgFS9wAACLMBHhEmACs1//8Auv/sBRkGtAImADgAAAEHAU0AkQFSAAizARUFJgArNf//AKT/7AQ5BWICJgBYAAABBgFNGQAACLMBGBEmACs1//8Auv/sBRkHNwImADgAAAEHAU4AiwFSAAizARIFJgArNf//AKT/7AQ5BeUCJgBYAAABBgFOEgAACLMBFREmACs1//8Auv/sBRkH1wImADgAAAEHAVAAnAFSAAq0AgEVBSYAKzU1//8ApP/sBDkGhQImAFgAAAEGAVAjAAAKtAIBGBEmACs1Nf//ALr/7AUZB3MCJgA4AAABBwFTAOEBUgAKtAIBJQUmACs1Nf//AKT/7AQ5BiECJgBYAAABBgFTaAAACrQCASgRJgArNTX//wC6/kIFGQW2AiYAOAAAAAcBUQIhAAD//wCk/kIEZQRIAiYAWAAAAAcBUQL0AAD//wAbAAAHTAdzAiYAOgAAAQcBSwFUAVIACLMBKAUmACs1//8AFwAABiMGIQImAFoAAAEHAUsAwQAAAAizASsRJgArNf//AAAAAAR7B3MCJgA8AAABBwFL/+ABUgAIswEXBSYAKzX//wAC/hQEBgYhAiYAXAAAAQYBS60AAAizASQRJgArNf//AAAAAAR7ByUCJgA8AAABBwBq//EBUgAKtAIBHgUmACs1Nf//AFIAAAQ/B3MCJgA9AAABBwB2AEIBUgAIswETBSYAKzX//wBSAAADbQYhAiYAXQAAAQYAdugAAAizARMRJgArNf//AFIAAAQ/BzECJgA9AAABBwFPAUQBUgAIswETBSYAKzX//wBSAAADbQXfAiYAXQAAAQcBTwDfAAAACLMBExEmACs1//8AUgAABD8HcwImAD0AAAEHAUz/7QFSAAizARUFJgArNf//AFIAAANtBiECJgBdAAABBgFMhgAACLMBFREmACs1AAEAsAAAAtsGHwAMAB1ADgABAQ0GDgQJRlkEAAEVAD8/KxEBMxI5ETMxMCEjERAhMhcHJiMiBhUBVqYBZ2BkK1dJYVkEnAGDJYUee3oAAAEAw/4UBBcFywAgAERAJBoeHgwIEhwICgIFISIdCgwKRlkaDAwQABAWRlkQBAAFRlkAGwA/KwAYPysREgA5GC8zKxEAMxESARc5ETMzETMxMAEiJzUWMzI2NREjNTc1NDYzMhcHByYjIgYVFSEVIREUBgFIRUBGPV9N3t6itlV4FhVmPGJQARr+6p7+FBOLEmZxA81LPIvDsitAQSBpfJWB/De4rwAEAAAAAAUUB6oAEAAYACIALgBhQDQRBQQYBhQHBAMHCCMAKQsICwkiFAIAHQMJMC8mDiwCCRgGSVkJFA4YIg4YGA4iAwgcBAgSAD8zLxIXOS8vLxESOTkrEQAzMxEzERIBFzkRMxEzETMRMxESOTkROTkxMAEUBwEjAyEDIwEmNTQ2MzIWEwMmJwYGBwMTNjY3MxUGBgcjEzQmIyIGFRQWMzI2A2hoAhSusP2epq4CFGp6Y2R9G7IZLw4wCbGYMWYXyyCoQm/TQjMzQjw5NUAFloU4+ycBkf5vBNc0iGVydfw2AbA6kTCHGP5UBIU7lSoQLqEt/vU5PDw5Nz09AAUAXv/sA80HqgAJACQALwA7AEcAZ0A3LRJCNjwwKRUVCyQkBjAANh0SB0hJCQkEPzlFMxELDBUpR1kMFRUPICAZRlkgEA8lRlkPFgoVBAAvPz8rABg/KxESADkYLzkrEQAzGD8zxDIROS8REgEXOREzMxEzETMRMxEzMTABNTY2NyEVBgYHAScjBgYjIiY1ECU3NTQmIyIGByc2NjMyFhURJTI2NTUHBgYVFBYBFAYjIiY1NDYzMhYHNCYjIgYVFBYzMjYB1y5qFgEEFaSAAQIhCFKjeqO5Ahm0d4Vgp0c3VNBl0cn+DpuxpsavbQGqe2ZleXllZXxtQTMzQjw5NEAG2RAqeB8MGGlE+SecZ0momwFMEAZEgno0IH8rM67A/RR1qpljBwdtc1peBT1id3RjYnN3Xjg9PTg4PT0A/////gAABoEHcwImAIgAAAEHAHYCTAFSAAizAh0FJgArNf//AF7/7AZzBiECJgCoAAABBwB2AYUAAAAIswNFESYAKzX//wB9/8MFvgdzAiYAmgAAAQcAdgEZAVIACLMDLQUmACs1//8Ac/+8BGIGIQImALoAAAEGAHZWAAAIswMtESYAKzX//wBq/jsEAgXLAiYANgAAAAYCOQYA//8Aav47A3MEXAImAFYAAAAGAjm5AAABAQwE2QOuBiEADgAYQAkHABAPCwSADgkALzMazTIREgE5OTEwATY2NzMWFhcVIyYnBgcjAQx/ZhemFm19d1iFiFNzBPCIgCkqhYIXN4OGNAAAAQEMBNkDrgYhAA4AGEAJBgAQDwUBgAMLAC8zGs0yERIBOTkxMAEzFhc2NzMVBwYHIyYmJwEMc3Jpglt3QpAuphdmfwYhSnOCOxlElFcpfogAAAEBLQTZA4UFYgADABG1AAEEBQADAC8zERIBOTkxMAEhFSEBLQJY/agFYokAAQElBNkDkQXlAA4AGEAJDAMQDwsEgAgAAC8yGswyERIBOTkxMAEiJiczHgIzMjY3MwYGAlaMnAloBilJVWVgCmgKpwTZiYMxOBpAQ36OAAABAKIFAgFmBd8ACwATtgYAAAwNAwkAL80REgE5ETMxMBM0NjMyFhUUBiMiJqI4Kig6OigqOAVxOTU2ODg3NwAAAgFvBNkDLQaFAAsAFwAeQAwSBgwABgAYGQ8JFQMALzPMMhESATk5ETMRMzEwARQGIyImNTQ2MzIWBzQmIyIGFRQWMzI2Ay17ZmV4eWRlfGxCMzNCPDk0QQWyYnd1YmJzd144PT04OD09AAEAJf5CAXEAAAAPABhACgAJBA0JAxARAgcALzMREgEXOREzMTAXFDMyNxUGIyI1NDY3MwYGsl4qN0E8z1ZIeERF7l4NbRK8Roc1Qm0AAAEBCATZA/AF3QAXACRADwkVGBkRAAUMAAwADBWACQAvGsw5OS8vETMRMxESATk5MTABIi4CIyIGByM2NjMyHgIzMjY3MwYGAxQrUk9JIjIzDmINc1suVk5IIDEwD2MNcQTbJS0lPD15iSUtJTs+eYkAAAIA5wTZA7YGIQAJABMAG0AMDgUTCQQUFQ0EgBMJAC8zGs0yERIBFzkxMBM2NjczFQYGByMlNjY3MxUGBgcj5yRuH7olqzphAWUxZRq6Jas6YATyMLpFFT/EMBlEsToVP8QwAAABAfwE2QMQBnMACQATtgQACwoEgAkALxrNERIBOTkxMAE2NjczFQYGByMB/Bs1DLgSbTFkBPZI41IXSu1MAAMBGwUOA4MGtAAIABQAIAArQBQPCRUbGwMICQQhIhgMCAwIDAMeEgAvM8w5OS8vETMREgEXOREzETMxMAE2NzMVBgYHIyc0NjMyFhUUBiMiJiU0NjMyFhUUBiMiJgIAQR+9IXkzUOU0JikxNyMmNAG0NCYpMTcjJjQFhamGFEOzPQQ0LjQuMjExMjQuNC4yMTH//wAAAAAFEAYKAiYAJAAAAQcBVP4g/5cAB7ICEgAAPzUA//8AmAJMAYkDWgIGAHkAAP///9QAAAR1BgoAJgAofQABBwFU/dj/lwAHsgEQAAA/NQD////UAAAFtQYKACcAKwCWAAABBwFU/dj/lwAHsgEQAAA/NQD////kAAADRAYKACcALADuAAABBwFU/ej/lwAHsgEQAAA/NQD////k/+wGAgYKACYAMkQAAQcBVP3o/5cAB7ICHAAAPzUA////1AAABYUGCgAnADwBCgAAAQcBVP3Y/5cAB7IBDQAAPzUA////5AAABjMGCgAmAXY/AAEHAVT96P+XAAeyASMAAD81AP///+n/7AKTBrQCJgGGAAABBwFV/s4AAAAMtQMCAS4RJgArNTU1//8AAAAABRAFvAIGACQAAP//AMkAAAS+BbYCBgAlAAAAAQDJAAAD+AW2AAUAHUAOAwQEAAYHBQJJWQUDBBIAPz8rERIBOTkRMzEwARUhESMRA/j9e6oFtpn64wW2AP//ACcAAARtBbYCBgIoAAD//wDJAAAD+AW2AgYAKAAA//8AUgAABD8FtgIGAD0AAP//AMkAAAUfBbYCBgArAAAAAwB9/+wFvgXNAAMADwAbAD9AIAIDEBYQChYECgQcHQADSVkAAAcNDRlJWQ0EBxNJWQcTAD8rABg/KxESADkYLysREgE5OREzETMREjk5MTABIRUhJRAAISAAERAAISAAARASMzISERACIyICAeMCdf2LA9v+nf7E/r3+oQFgAUQBOwFi+3P69PP49/L1+wMzlT/+of5uAYsBaAFlAYn+cP6g/tj+zAEwASwBKgEu/s4A//8AVAAAAlYFtgIGACwAAP//AMkAAATpBbYCBgAuAAAAAQAAAAAE0wW2AAoAGkALCAAMCwQICQMBCBIAPzM/EjkREgE5OTEwISMBJicGBwEjATME07b+tlcWIUf+uLYCELEDoPxai8n8XgW2//8AyQAABnEFtgIGADAAAP//AMkAAAU/BbYCBgAxAAAAAwBIAAAEJQW2AAMABwALADRAHQoHAwIGCAYNDAADSVkAAAoECgtJWQoSBAdJWQQDAD8rABg/KxESADkYLysREgEXOTEwEyEVIQMhFSEBFSE1wwLn/RlSA4v8dQO0/CMDSJYDBJf7eZiY//8Aff/sBb4FzQIGADIAAAABAMkAAAUMBbYABwAjQBEBAAQFAAUJCAYDSVkGAwEFEgA/Mz8rERIBOTkRMxEzMTAhIxEhESMRIQUMqv0RqgRDBR/64QW2AP//AMkAAARoBbYCBgAzAAAAAQBKAAAEXAW2AAwANUAcCAoKAAkCCwYDAgAFDQ4HCAQISVkEAwAKSVkAEgA/KwAYPysRADMREgEXOREzETMRMzEwMzUBATUhFSEnAQEhFUoB4f4rA8v9XGABzP4fA1SNAm8CK4+ZAv3f/ZqYAP//ABIAAARaBbYCBgA3AAD//wAAAAAEewW2AgYAPAAAAAMAav/sBfgFywAZACIAKwBQQCknFBoCDQ0rGQ4eBwcOFAMsLQwQGioQKkpZIiQYJEpZAhgQGBAYDhMABAA/Pzk5Ly8RMysRADMrEQAzETMREgEXOREzETMzMxEzMxEzMTABMxUzMhYWFRQCBCMjFSM1IyIkAjU0NjYzMxMzMjY1NCYrAyIGFRQWMzMC26xGq/uFlf79sCmsLbD+/pKH/KtDrBnJ3865Oqw5ttHeyhgFy7SI+J+m/v2C4eGEAQShnviL/EXbw7nS1LfF2QD//wAIAAAElgW2AgYAOwAAAAEAbQAABfIFtgAdAD5AHwoHEQAADgEVGBgBBwMeHx0DDQNJWRENDQEWDwgDARIAPz8zMxI5LzMrEQAzERIBFzkRMxEzMxEzETMxMCEjESMiJiY1ETMRFBYzMxEzETMyNjURMxEUBgQjIwODqi2w/5Cuz9Qbqh3Tz7CQ/v2vLQG+evekAeP+IbzJA2T8nMa7AeP+H6X3ewAAAQBQAAAF9AXNAB8AOUAgAw0dExgTFhkHCg0ICCAhEABJWRAEGhYGCQgJSVkZCBIAPzMrEQAzMzMYPysREgEXOREzETMxMAEiAhUUEhcVITUhJgI1EAAhIAARFAIHIRUhNTYSNTQCAyHu+q20/bYBbJegAWIBOgE7AWKelwFr/ba3qfkFNf7//eH+s4SFmHYBXssBNgFg/qX+x8/+pniYhYYBTt78AQL//wA8AAACbwclAiYALAAAAQcAav8HAVIACrQCASEFJgArNTX//wAAAAAEewclAiYAPAAAAQcAav/vAVIACrQCAR4FJgArNTX//wBz/+wExwZzAiYBfgAAAQYBVB0AAAizAjQRJgArNf//AFr/7AOHBnMCJgGCAAABBgFUyAAACLMBLxEmACs1//8AsP4UBEQGcwImAYQAAAEGAVQ7AAAIswEeESYAKzX//wCo/+wCkwZzAiYBhgAAAQcBVP7EAAAACLMBGREmACs1//8ApP/sBHEGtAImAZIAAAEGAVU7AAAMtQMCATQRJgArNTU1AAIAc//sBMcEXAALACoAR0AkCQ8nFQQEHSIdDwMrLBgPJygoFgwSEgdGWRIQHwAMAEZZJAwWAD8zKxEAMxg/KxESADk5ETMYPxESARc5ETMRMzMRMzEwJTI2NTU0JiMgERQWFyICERASMzIWFzM2NzMGBhURFDMyNxUGIyImJyMGBgJQqZaYqf7Rk4XW7vTheaE2DBgpgRUcVB0hLkFRWRINO6d3w9oP5cf+UNTUiwEpAQwBEgEpVFRcOEL2dP5Jcgp3GlFWVlEAAgCw/hQEqAYfABMAKQBMQCgYDw8QJwMeCAgDBSIQBSorEBsjIkZZDiMOIwsACxtGWQsWABRGWQAAAD8rABg/KxESADk5GC8vKwAYPxESARc5ETMRMxEzETMxMAEyFhUQBRUEERQEIyImJxEjETQ2FyIGFREWFjMyNjU0JiMjNTMyNjU0JgKT3Pn+xwF5/vjubaBPpv3knp1doVarrb6xcFybopwGH9C3/tozCCr+kdHhHyb94wY04faMrKX8iTEllp2dpI6TiXuFAAEACv4UBA4ESAASACFAEA8EAQUEExQKCQkBDgUPARsAPz8zEjkvMxESARc5MTABIzQSNwEzExYXMz4CEzMBBgICFLRAK/4/rPBeEwgFKSvqrP5rMDX+FGABJnIEPP2462cejoECbfvTfP7cAAIAcf/sBGAGEgAeACoAO0AgJRwQAx8WFgkAAxwFKywQACIDGQYZKEZZGRYGDUZZBgAAPysAGD8rERIAFzkREgEXOREzETMRMzEwASYmNTQ2MzIWFwcmJiMiBhUUFhcWFhUUACMiJDU0EgE0JicGBhUUFjMyNgIhjHTCpGe9fkhwn1FVYWun0rH+8Ozj/vDiAmF7jc6/spOirgOoTp9jgpgtP4c+LE9CR29bc/Gk6/74+NKxAQX+c4C3SjXZoJCrugAAAQBa/+wDhwRcACUATUArBBAjFx0LARMXEAYmJxQlAiUCRlkPJR8lAgsDJSUNGhohRlkaEA0HRlkNFgA/KwAYPysREgA5GC9fXl0rERIAORESARc5ETMRMzEwARUjIBUUFjMyNjcVBiMiJjU0Njc1JiY1NDYzMhYXByYmIyIVFCECy5T+yZOSVKZkid3S8W6CYmvgwGGlZD9egk/6AT0CgY3DWmInL5RLqZRigykLHH9chZ4hLYUqHKKsAAABAHP+bwOgBhQAIAAwQBgHGR4TEw4OAwAZBCEiESMeAwABAEZZAQAAPysRADMzGD8REgEXOREzETMRMzEwEzUhFQYAAhUUFhYXFhYVFAcjNjU0JicmJjU0PgI3BiGwAvDX/uCKO32slYh/pn1vj8u8O3DJ8ij+8QWHjYG0/r3+36ZidkklH21blaShazg9GiTbwnLQw+XaCAAAAQCw/hQERARcABQAL0AYABQMCAgJFAkWFRAERlkQEAwJCg8JFQAbAD8/PxI5PysREgE5OREzETMRMzEwARE0JiMiBhURIxEzFzM2NjMyFhURA556gqygpocbCDO4ccbI/hQEsYaEutb9wQRIllFZv9L7SQADAHP/7ARKBisACwASABkASUAnFhAQBhcPDwAGABobFhBGWQ8WvxYCCwMWFgMJCRNGWQkBAwxGWQMWAD8rABg/KxESADkYL19eXSsREgE5OREzETMRMxEzMTABEAIjIgIREBIzMhIBMhITIRISEyICAyECAgRK9Prw+fX09Pr+EqScBv15BJanoZYKAoULmAMM/mr+dgGTAY0BlwGI/mv74QExATP+0P7MBSn+4f7nARkBHwABAKj/7AKTBEgADwAfQA4BDgcOERAPDwsERlkLFgA/KwAYPxESATk5ETMxMAERFBYzMjY3FQYGIyImNREBTklXJWUbH2kyoJEESPz6aGUNB38NEaipAwv//wCwAAAEGwRGAgYA+gAAAAH/8v/sBEYGIQAiADNAGwgBFQMkAAAjGBNGWRgWHh8fAAsLBkZZCwEAFQA/PysREgA5ETMYPysRATMREhc5MTAjAScuAiMiBzU2MzIWFhcBFhYzMjcVBiMiJicDJicjBgcDDgHZOh4yQzE6OUQ/W3lYNgFrEyojGyEwPUpTHZxUFgkcWP4EN6JVRiQNhRE8gpj8DDEzCnkYTFMBtPBgdNH9tgD//wCw/hQERARIAgYAdwAAAAEAAAAABAIESAAOABxADAkKCgAQDwUOFQkADwA/Mj85ERIBOTkRMzEwETMTFhYXMzYSETMQAgcjrNsaUxAIsZ+mz+G6BEj9skPuPq8BvQFR/pX+BOEAAQBx/m8DoAYUADEASUAnBBktHx0cEwwMKAAcHyUZBzIzHDABMAFHWTAwECYpJSYlRlkmABAjAD8/KxEAMxESORgvKxESADkREgEXOREzETMRMxEzMTABIyIGFRQeAhcWFhUUBgcjNjY1NCYnJiY1NDY3NSY1NDY3BiMjNSEVIyIGBhUUFjMzA1aysNUyX4dUjoc2Q5w1QnOPyMeegNmLpoBzRAK6M4Lgf6evqgLyso5QYj0kEh1uWkGVY0eTNDc9GSLIsIzSJwxA2XWeMgyNg1CQX3Ns//8Ac//sBGIEXAIGAFIAAAABABn/7AT0BEgAFQA2QB0KCwcTEAMTCw0FFhcSCQ0PDUZZDw8LFQUARlkFFgA/KwAYPz8rEQAzMxESARc5ETMRMzEwJTI3FQYjIjURIREjESM1NyEVIxEUFgR9JjArVNv+I6bdjwRM1TN1EoMY/QLR/EYDukpEjv08SjcAAgCm/hQEYgRcABAAHAA2QBsVCQkKGgAKAB0eBgMODhFGWQ4QChsDF0ZZAxYAPysAGD8/KxESADkREgE5OREzETMRMzEwARAAIyInIxYVESMREBIzMhIlIgYVERYzMjY1NCYEYv8A6bN4CAio++rb/P4hnpd6t5+YkAIl/vH+1l491P7bBB8BCgEf/tGiz9H+rmbQ3tbUAAABAHP+bwOiBFwAIAAuQBcOBwAVFQcbAyIhBBISGAsYHkZZGBALIwA/PysREgA5ETMREgEXOREzETMxMAEUFhYXFhYVFAYHIzY2NTQmJicmJjUQADMyFhcHJiMiBgEfO4+glIM2Q5w2QzNuYczDART4T542NYJysKoCCoeEUCIga1pCmF9GlDIoLyYSJf7bAR4BNiEYjTPaAAIAc//sBLYESAANABkAMEAZFAAOBwcMAAsEGxoMFwkXRlkJDwQRRlkEFgA/KwAYPysRADMREgEXOREzETMxMAEUBgYjIgA1ECEhFSEWARQWMzI2NRAnIyIGBGB75Zrr/vgCUAHz/viy/L+qoZ+rrkHeyAH8nfGCASD+Aj6Op/73wtHFtgEOutAAAAEAEv/nA5MESAATACxAFwMPAAkPEQQUFQIRExFGWRMPDAVGWQwWAD8rABg/KxEAMxESARc5ETMxMAEVIREUMzI2NxUGBiMiJjURITU3A5P+UM0vYhsjbzC1qv7XlARIjv2W3w0HfQ8SqqoCf0pEAAABAKT/7ARxBEgAFQAlQBEMEwYDEwMXFg8EDwAJRlkAFgA/KwAYPzMREgE5OREzETMxMAUiJhERMxEUFjMyNjU0JiczFhYVEAACc+fopp6Zp6EcIqYkHP7+FPoBCgJY/bDAw+77guCIkNaM/sL+1AAAAgBz/hQFTARcABgAIgBBQCMKBCAYGAwAGRMTAAcEBCMkEBxGWRAQBg8gDAEMRlkXARYAGwA/PzMrEQAzGD8/KxESARc5ETMRMzMRMxEzMTABESQAERA3FwYGFRAFETQ2MzISFRQCBgcRATQmIyIGFRE2NgKD/vz+9M+DWVEBaKaVtNqI+KUBeXxmSU6zxv4UAdoLASMBDwEo/Vp14Hz+dSMCbLu+/tv6sv77kAj+JgQnudt4cv2SEOwAAf/s/hQEUAROACAAOUAhDgcIBRUYHgciFyEFGAgVBAYXGxEMRlkRGwYPABxGWQAPAD8rABg/PysAGD8SFzkRATMSFzkxMBMyFhYXEwEzARMWFjMyNxUGIyImJwMBIwEDJiYjIgc1NrI2Tj4skQE+tP5UvjBSPy0tPDtzjTuW/payAdCsJkYrJRsxBE4rW3D+jwJh/Pz+HHpKCIEPdp8Bg/1oA0QBvGNQC4ERAAEApP4UBYcGEgAaAD1AHxYTAQ4OGQ8ECgoPEwMbHBoABxQPARkQGUZZDRAWDxsAPz8zKxEAMxg/Mz8REgEXOREzETMzETMRMzEwARE2NjU0JiczEhUQAAURIxEkABERMxEUFhcRA1q8yxolpj/+4/7wpP74/vamtLgGEvppD+fMeOuo/vD0/uz+zhD+JgHaCQEiARACH/3bw9oNBZkAAQBz/+wFvARIACcAPUAeCgMmExMQGSAgEAMDKCkmEREAHAYPFg0ADUZZIwAWAD8yKxEAMxg/MxI5LzkREgEXOREzETMSOREzMTAFIgI1NBI3MwYGFRQWMzI2NREzERQWMzI2NTQCJzMWEhUUAiMiJyMGAfS2yzdErEQ5eGteaaFqXWt4N0WsQTnLttxECUEUASj+nAEBmZz/ncHYj30BN/7JgIzYwZcBBJ2S/vmd/P7Wtrb//wAJ/+wCkwXTAiYBhgAAAQcAav7UAAAACrQCASURJgArNTX//wCk/+wEcQXTAiYBkgAAAQYAajkAAAq0AgErESYAKzU1//8Ac//sBGIGcwImAFIAAAEGAVQhAAAIswIiESYAKzX//wCk/+wEcQZzAiYBkgAAAQYBVCcAAAizAR8RJgArNf//AHP/7AW8BnMCJgGWAAABBwFUAMkAAAAIswExESYAKzX//wDJAAAD+AclAiYAKAAAAQcAagAnAVIACrQCASEFJgArNTUAAQAS/+wFQgW2AB0ARkAmFg4ODwgbGxQCDxEFHh8WDUlZFhYPEhUREhFJWRIDDxIABUlZABMAPysAGD8/KxEAMxESORgvKxESARc5ETMRMxEzMTAFIic1FjMyNjU1NCYjIREjESE1IRUhESEyFhUVFAYDz2A2N1tlaIOM/oOq/rADt/5DAYzN3cQUFpYTfHCDgHH9GwUfl5f+Xr+yj77T//8AyQAAA/gHcwImAWEAAAEHAHYAWgFSAAizAQ8FJgArNQABAH3/7ATjBc0AGAA4QB4GAxEWDAURBBkaAwZJWQMDDhQUAElZFAQOCUlZDhMAPysAGD8rERIAORgvKxESARc5ETMzMTABIgQHIRUhEgAzMjcVBiMgABEQACEyFwcmA0Li/vMeAtP9KQoBC/miyaHi/rT+ogF5AU7tskepBTP68Zb+7v7jN5U5AYQBbQFfAZFYlFL//wBq/+wEAgXLAgYANgAA//8AVAAAAlYFtgIGACwAAP//ADwAAAJvByUCJgAsAAABBwBq/wcBUgAKtAIBIQUmACs1Nf///2D+fwFoBbYCBgAtAAAAAgAA/+kHIwW2ABoAIwBHQCYYGxsEHwAABA0DJCUYI0lZGBgLFhYGSVkWAwsQSlkLEgQbSlkEEgA/KwAYPysAGD8rERIAORgvKxESARc5ETMRMxEzMTABFAQhIREhAgIGBiMiJzUWMzI+AhITIREzIAEzMjY1NCYjIwcj/u3+/P65/pM5VFCLa0VAMj8wQSs3REECpnoCOv1Mhca3wNxmAarO3AUf/kj99vt5GY8aPmf6Ab4B4v2Q/U2LjIp8AAIAyQAAB1QFtgARABoASkAmCwcHCA8SEgwEFgAABAgDGxwaBgsGSVkPCwsEDQkDCBIEEkpZBBIAPysAGD8/MxI5LzMrEQAzERIBFzkRMxEzMxEzETMRMzEwARQEISERIREjETMRIREzETMgATMyNjU0JiMjB1T+8P77/rf9faqqAoOseQI5/U6FxLnB22YBqs7cArD9UAW2/ZICbv2Q/U2LjIl9AAABABIAAAVCBbYAEwA6QB8ADAwNBgUFEg0PBBQVEw8QD0lZAAtJWQAADRADBg0SAD8zPxI5LysrEQAzERIBFzkRMxEzETMxMAEhMhYVESMRNCYjIREjESE1IRUhAgwBkM3Zqn2M/n2q/rAD9v4EA328tf30AfZ+cf0bBR+Xl///AMkAAATlB3MCJgG0AAABBwB2AKIBUgAIswEUBSYAKzX//wAb/+wE+AdeAiYBvQAAAQcCNgBEAVIACLMBFwUmACs1AAEAyf6DBQwFtgALADBAGAgFAgMJAAADBQMMDQoGAwUISVkBBRIDIgA/PzMrABg/MxESARc5ETMRMxEzMTAhIREjESERMxEhETMFDP4vsP4+qgLvqv6DAX0FtvrkBRwA//8AAAAABRAFvAIGACQAAAACAMkAAAR9BbYADQAWAD1AIBIACQ4OBAQHAAMYFwkWSVkJCQQFBQhJWQUDBA5KWQQSAD8rABg/KxESADkYLysREgEXOREzETMRMzEwARQEISERIRUhETMyFhYBMzI2NTQmIyMEff79/vv+VANe/UzjwfJ0/Pbvvq2w288BqtrQBbaX/idZrv5UgpWOeAD//wDJAAAEvgW2AgYAJQAA//8AyQAAA/gFtgIGAWEAAAACAA7+gwVKBbYADQATAENAJAQFEwcQCg4MAQAADAoHBQUUFQoQSVkKAwEFIhMMBgMGSVkDEgA/KxEAMzMYPzM/KxESARc5ETMRMxEzETMRMzEwASMRIREjETMSEhMhETMhESEGAgcFSqL8CKJxmtsMApG5/p3+sxLOif6DAX3+gwIXAQMC5gEz+uQEg/L9WeoA//8AyQAAA/gFtgIGACgAAAABAAIAAAa8BbYAEQA8QB8GDQ0DDgoJCAEOABEHEhMPDAkGAwAAAQ4LERIHBAEDAD8zMz8zMxI5ETMzMzMzERIBFzkRMzMRMzEwAQEzAREzEQEzAQEjAREjEQEjAlb9wb4COaQCOr79wAJSxP26pP27xwLwAsb9PALE/TwCxP08/Q4C5f0bAuX9GwABAEr/7AQ1BcsAKABDQCQcABMHBwADFyMMBikqAxgXGBdKWRgYCiYmH0pZJgQKEEpZChMAPysAGD8rERIAORgvKxESADkREgEXOREzETMxMAEUBgcVFhYVFAQhIic1FhYzMjY1NCYjIzUzMjY1NCYjIgYHJzY2MzIWBBm3obe9/s7+6f+jYN9nxsvh39rRzeGiiW6ydVRl+4fh/wRgkLQYCBm0kc3lT54uMpaNhoqPk4RrgDJKcktNxQABAMsAAAVSBbYADwA0QBgOAgIPBgkJCA8IEBEFBAwNBA0JDxIGAAMAPzI/Mzk5ETMRMxESATk5ETMRMxEzETMxMBMzERQHMwEzESMRNDcjASPLnw4IAzS6oBEJ/Mu6Bbb80+G2BMT6SgMlyd37NQD//wDLAAAFUgdeAiYBsgAAAQcCNgDhAVIACLMBEAUmACs1AAEAyQAABOUFtgAKAC1AFgcDAwQACQoEBAsMCgcCBwQIBQMBBBIAPzM/MxI5OREzERIBFzkRMxEzMTAhIwERIxEzEQEzAQTlzv1cqqoCk8P9eQLl/RsFtv08AsT9OgABAAD/5wTZBbYAEwAtQBgDEgEAABIKAxQVEgNJWRIDCA1KWQgTARIAPz8rABg/KxESARc5ETMRMzEwISMRIQcCAgYnIic1FjMyNjYSEyEE2ar+JR89XZh+Sjs2OzVPPV04AxIFH/D+If5FrgIZjxpX1wJZAbj//wDJAAAGcQW2AgYAMAAA//8AyQAABR8FtgIGACsAAP//AH3/7AW+Bc0CBgAyAAD//wDJAAAFDAW2AgYBbgAA//8AyQAABGgFtgIGADMAAP//AH3/7ATPBcsCBgAmAAD//wASAAAEWgW2AgYANwAAAAEAG//sBPgFtgAWACpAFRIIAgkEFxgODQgNABEJAwAFSVkAEwA/KwAYPzMSOTkRMxESARc5MTAFIic1FjMyNjcBMwEWFzM2NwEzAQ4CASVvVF1gboVC/ce8AbAZDggcCwFntP4tVIepFB6mK2WLBEH8wTEvVBYDNfvqu6pP//8Aav/sBfgFywIGAXMAAP//AAgAAASWBbYCBgA7AAAAAQDJ/oMFuAW2AAsAMkAZCAUJAAMCAgAFAwwNCgYDAAgFCElZBRIDIgA/PysRADMYPzMREgEXOREzETMRMzEwJTMRIxEhETMRIREzBQysofuyqgLvqpr96QF9Bbb65AUcAAABAKoAAATHBbYAEwAtQBYLCBEBAQAIABQVBQ5JWQUFARIJAwESAD8/MxI5LysREgE5OREzETMRMzEwISMRBgYjIiY1ETMRFBYzMjY3ETMEx6qVxmrP36p/j2GxqaoCXDUnvrMCRf3PeXQdNwLKAAEAyQAAB3kFtgALADFAGAQBCAUJAAAFAQMMDQoGAgMIBAEESVkBEgA/KxEAMxg/MzMREgEXOREzETMRMzEwISERMxEhETMRIREzB3n5UKoCWKoCWKwFtvrkBRz65AUcAAEAyf6DCAQFtgAPADtAHgMABwQICw4NDQsEAAQQEQ4iCQUBAwsHAwADSVkAEgA/KxEAMzMYPzMzPxESARc5ETMRMxEzETMxMDMRMxEhETMRIREzETMRIxHJqgJHrAJIqqyiBbb65AUc+uQFHPrk/ekBfQAAAgASAAAFFwW2AAwAFQA9QCAJDQ0EEQAABAYDFhcJFUlZCQkEBwcGSVkHAwQNSlkEEgA/KwAYPysREgA5GC8rERIBFzkRMxEzETMxMAEUBCMhESE1IREzIAQBMzI2NTQmIyMFF/79+f5H/rAB+vQBBQES/PX8tamvy+ABqs7cBR+X/ZDN/hqLjIh+AAADAMkAAAYKBbYACgATABcAP0AgAwsLAA8HFRQUBwADGBkVEgMTSVkDAwAWAQMAC0pZABIAPysAGD8zEjkvKwAYPxESARc5ETMRMxEzETMxMDMRMxEzIAQVFAQjJTMyNjU0JiMjASMRM8mq7wEFARL+/fn+9ve1qrPI2wSXqqoFtv2Qzc/O3JGNjIl7/VIFtgACAMkAAAS6BbYACgASADJAGQcLCwQOAAQAExQHEklZBwcEBQMEC0pZBBIAPysAGD8SOS8rERIBOTkRMxEzETMxMAEUBCMhETMRISAEASEgETQmIyEEuv7x+/4ZqgEjAQsBGfy5ASsBbLvO/vIBqsvfBbb9kNP+IAEXh38AAQA9/+wEiQXLABoAOkAfGBUVCQkWDwMEGxwXFklZFxcMBQwSSVkMEwUASVkFBAA/KwAYPysREgA5GC8rERIBFzkRMxEzMTABIgcnNjMyBBIVEAAhIic1FhYzIAATITUhJgAB06yiSKzs2QE5ov6U/qrjnFOsYwEPARQI/TECzRb+8QUzTJBUsP663f6I/mw5lRUiASEBEJjlAQIAAgDJ/+wH5wXNABIAHgBHQCYMCAgJEw0GGQAABgkDHyAQHElZEAQMB0lZDAwJCgMJEgMWSVkDEwA/KwAYPz8SOS8rABg/KxESARc5ETMRMzMRMxEzMTABEAAhIAADIREjETMRIRIAISAAARASMzISERACIyICB+f+q/7Q/tP+qwv+nqqqAWQXAVEBHwEzAVb7oO7n6u3r6OnwAt3+nv5xAW8BVf1QBbb9kgE3AU7+b/6h/tj+zAEyASoBKgEu/s8AAgAzAAAETgW2AA0AFQA9QCAVDAwLEgYCBgMLBBcWABRKWQMJAAACCQkPSlkJAwwCEgA/Mz8rERIAORgvEjkrERIBFzkRMxEzETMxMAEBIwEmJjU0JCEhESMRESMiBhUQITMCe/6ByQGaoZIBDwETAZKq47e+AXvdAmL9ngJ/M8+exNP6SgJiAsF+jv7d//8AXv/sA80EWgIGAEQAAAACAHf/7ARUBiEAFwAiADtAHhoSIAsAAAYSAyQjDAsPHEZZCw8PFQUVGEZZFRYFAQA/PysREgA5GC85KxEAMxESARc5ETMzETMxMBMQEjckNxcEBwYGBzM2NjMyEhUQACMiAAUgERAhIgYGBxASd9TmAR7aH/6llZGRBww+xGvK4v766uf++gH8ATH+60yNdSCmApEBaAGTMj0mkjoiIfbUVGD++uj+//7fAWLXAYUBcz9oN/75/u0AAwCwAAAETARIAA4AFgAfAElAJhwUFAsXAA8HBwADCwQgIQQcExwTRlkcHAsMDBtGWQwPCxRGWQsVAD8rABg/KxESADkYLysREgA5ERIBFzkRMxEzETMRMzEwARQGBxUWFhUUBiMhESEgAzQmIyERISADNCYjIREhMjYEKXtvjIHh2P4dAeEBmIOHnP7TATEBHx97ff7HARmafgM1a28TCRN+b5mmBEj9AllR/pcCmlBD/stMAAABALAAAANEBEgABQAdQA4CAwADBwYEAUZZBA8DFQA/PysREgE5OREzMTABIREjESEDRP4SpgKUA7r8RgRIAAIAKf6FBGgESAANABMAQ0AkBAUTBxAKDgwBAAAMCgcFBRQVChBHWQoPAQUiEwwGAwZGWQMVAD8rEQAzMxg/Mz8rERIBFzkRMxEzETMRMxEzMTABIxEhESMRMzYSEyERMyERIwYCBwRoof0CoFaGmAMCK53+w/YNkWz+hQF7/oUCCrYB6gEZ/EcDNt7+OZEA//8Ac//sBBIEXAIGAEgAAAABAAQAAAXfBEYAEQA8QB8CCQkRCgYEBQoODw0HExIRCwgFAg4ODQMADw8KBw0VAD8zMz8zMxI5ETMzMzMzERIBFzkRMzMRMzEwATMRATMBASMBESMRASMBATMBAqSZAcW2/jYB8cD+Hpn+H78B8P43tgHDBEb97QIT/e39zQIr/dUCK/3VAjMCE/3tAAEARP/sA38EXAAiAE1AKwINHhMTDQ8hCBgGIyQQIiEiIUZZDyIfIgILAyIiFgoWG0ZZFhYKBEZZChAAPysAGD8rERIAORgvX15dKxESADkREgEXOREzETMxMAEgNTQjIgYHJzYzMhYVFAcVFhYVFAYjIic1FjMyNjU0ISM1AYEBN/xNfmY7qsm92s1+dPXY7YG3u5CT/smYAoGsohwqh0ybhrg5CCWJZ5ipR5hWY12/jQABALAAAARiBEgADQA0QBkIBAcHBgsDAwwGDA8OAwoMBA0PDBUHFQQPAD8/Pz8REjk5ERIBOTkRMxEzETMRMzMxMAERBwcBMxEjETc3ASMRAUwHAwJRz5sDBf2wzwRI/Um2OQOm+7gCnoSC/FwESAD//wCwAAAEYgYMAiYB0gAAAQYCNj0AAAizAQ4RJgArNQABALAAAAQMBEgACgAtQBYKBgYHAwECBwQMCwIKBQoHAAgPBAcVAD8zPzMSOTkRMxESARc5ETMRMzEwATMBASMBESMRMxEDL7b+JwIAwv4MpqYESP3v/ckCK/3VBEj96wABABD/8gPhBEgAEAAtQBgBAAMPCg8AAxIRDwNGWQ8PBwxHWQcWARUAPz8rABg/KxESARc5ETMRMzEwISMRIQICBiMiJzUWMzISEyED4aj+txtgmXY2IBYcc4gjAoEDuv6c/l7CDHsGAeYB7wABALAAAAUvBEYAFAA1QBkDBgYFEg8PEAUQFhUHDgAOCwMRDwYQFQsVAD8/Mz8zEjk5ETMREgE5OREzETMRMxEzMTAlNzcBMxEjEQcHASMBJicRIxEzARYC6R8rASnTkxQ6/uWL/uU1FJTLAR8roF12AtP7ugOJOpn9SgK4hkv8dwRG/UluAAEAsAAABGIESAALADlAHgIGBgUBCQkKBQoNDAEIRlkvAT8BAgEBCgMLDwYKFQA/Mz8zEjkvXSsREgE5OREzETMRMxEzMTABESERMxEjESERIxEBVgJmpqb9mqYESP41Acv7uAHu/hIESP//AHP/7ARiBFwCBgBSAAAAAQCwAAAESARIAAcAI0ARAAEFBAEECAkCB0ZZAg8FARUAPzM/KxESATk5ETMRMzEwISMRIREjESEBVqYDmKj9tgRI+7gDuAD//wCw/hQEdQRcAgYAUwAA//8Ac//sA4sEXAIGAEYAAAABACkAAAOTBEgABwAkQBICAwADBQMICQEFBgVGWQYPAxUAPz8rEQAzERIBFzkRMzEwASERIxEhNSEDk/6cpv6gA2oDuvxGA7qO//8AAv4UBAYESAIGAFwAAAADAHH+FAVGBhQAEQAYAB4ATEAnEgkcDwQEFQwFGQAABQkDHyANABsWDBZGWQ8MEBwVBhVGWQMGFgUbAD8/MysRADMYPzMrEQAzGD8REgEXOREzETMzMxEzMxEzMTABFAAHESMRJgA1NAA3ETMRFgAFFBYXEQYGBRAlETY2BUb+5f6k+P7gAR//nvsBHvvZsMC5twN7/pO+rwIl+f7ZFf4kAdwTAS70+QEmFAG8/kQX/tTwwNoSA1QRz8gBfyf8rhPa//8AJwAABAgESAIGAFsAAAABALD+hQTdBEgACwAyQBkGAwcKAQAACgMDDA0IBA8KBgMGRlkDFQEiAD8/KxEAMxg/MxESARc5ETMRMxEzMTABIxEhETMRIREzETME3ab8eaYCRqab/oUBewRI/EcDufxHAAEAnAAABC0ESAASAC1AFgYKCgkBEQkRFBMDDkZZAwMKBxIPChUAPz8zEjkvKxESATk5ETMRMxEzMTABERQzMjY3ETMRIxEGBiMiJjURAULbW6ZppqZps3GkugRI/nDAOEMB1fu4AfBIO6yTAZwAAQCwAAAGbwRIAAsAMUAYCAUACQEEBAkFAwwNCgIGDwAIBQhGWQUVAD8rEQAzGD8zMxESARc5ETMRMxEzMTAlIREzESERMxEhETMD4QHmqPpBpgHlpo8Dufu4BEj8RwO5AAABALD+hwcKBEYADwA7QB4MCQANAQQHBgYEDQkEEBEOAgoPBAAMCQxGWQkVByIAPz8rEQAzMxg/MzMREgEXOREzETMRMxEzMTAlIREzETMRIxEhETMRIREzA+EB5qadqPpOpgHlpo8Dt/xJ/fgBeQRG/EkDtwAAAgApAAAFHQRIAAwAFAA9QCAAEhIIDQQECAoDFRYAEUZZAAAICwsKRlkLDwgSRlkIFQA/KwAYPysREgA5GC8rERIBFzkRMxEzETMxMAEhMhYVFAYjIREhNSEBNCYjIREhIAItATng19/c/iX+ogIEAkx8nf7NATkBEwKDmpumqAO6jvz8XVP+lwAAAwCwAAAFeQRIAAoADgAWAD9AIAAQEAgEEwwLCxMIAxcYDBUAD0ZZAAAIDQkPCBBGWQgVAD8rABg/MxI5LysAGD8REgEXOREzETMRMxEzMTABITIWFRQGIyERMwEjETMBESEgNTQmIwFWASvRydXP/jmmBCOmpvvdARkBCHqTAoObmqWpBEj7uARI/az+l7lcVAACALAAAARMBEgACQASADJAGQ8DAAsLBwMHFBMACkZZAAAHCA8HC0ZZBxUAPysAGD8SOS8rERIBOTkRMxEzETMxMAEhIBEUBiMhETMRESEyNjU0JiMBVgFSAaTb0/4SpgFAhIyBlAKD/suirARI/az+l1xdW1UAAQA5/+wDfQRcABoAREAmDAkJGBgKEgIEGxwLCkZZDwsfCwILAwsLABUVD0ZZFRAABkZZABYAPysAGD8rERIAORgvX15dKxESARc5ETMRMzEwBSInNRYWMzI2NyE1ISYmIyIHJzY2MyAAERAAAVandjyMW669Cv3VAikQqaFnly83pFABAAEK/t8UOZMXJLq5jaygNowaI/7b/uz+8/7WAAIAsP/sBjMEXAASAB4AUUAtDAgICRMNBhkAAAYJAx8gEBxGWRAQDAdGWQ8MHwwCCwMMDAkKDwkVAxZGWQMWAD8rABg/PxI5L19eXSsAGD8rERIBFzkRMxEzMxEzETMxMAEQACMiAichESMRMxEhNjYzMgABFBYzMjY1NCYjIgYGM/7/4NX6Dv7hpqYBIRT8z9wBAfzukqGelZKhoZICJf7z/tQBC/f+EgRI/jXk+/7P/vrT29XZ0tjYAAIAJQAAA8EESAANABQAPUAgEQsLCg4FAQUCCgQWFQ0QRlkCCA0NAQgIE0ZZCA8LARUAPzM/KxESADkYLxI5KxESARc5ETMRMxEzMTAzIwEmJjU0NjMhESMRIQEUISERISLnwgE7f4fKtQHopv7r/vYBFAEL/tPyAc8coXqWrPu4AbYBTr4Bcv//AHP/7AQSBdMCJgBIAAABBgBqCAAACrQDAjARJgArNTUAAQAU/hQERAYUACcAZkA6HRsXDw8UEAclJRkCEBIFKCkeHSELRlkaEhMSR1kXEw8THxMvEwMJAx0hExMhHQMQFQAQFQAFRlkAGwA/KwAYPz8SFzkvLy9fXl0RMysRADMrEQAzERIBFzkRMxEzMxEzMzMxMAEiJzUWMzI1ETQmIyIGFREjESM1MzUzFSEVIRUUBzM2NjMyFhURFAYDL080OjeBeoKtnaicnKYBkf5vCAoxtXTJyYn+FBmJFKoDUoaEvNP95wTbf7q6f8RUOE9bv9L8tpyq//8AsAAAA0QGIQImAc0AAAEGAHbxAAAIswEPESYAKzUAAQBz/+wDqgRcABkAREAmDxISAwkYEQMEGhsPEkZZDw8fDwILAw8PAAYGDEZZBhAAFUZZABYAPysAGD8rERIAORgvX15dKxESARc5ETMRMzEwBSIAERAAMzIWFwcmIyIGByEVIRYWMzI3FQYCefj+8gET+1KeOTGPbaSqEAIp/dUJqqeMl3QUASMBEAETASogGY0zo6mNvrU7kzn//wBq/+wDcwRcAgYAVgAA//8AogAAAWYF3wIGAEwAAP///+wAAAIfBdMCJgDzAAABBwBq/rcAAAAKtAIBGREmACs1Nf///5H+FAFmBd8CBgBNAAAAAgAQ//IGQgRIABUAHQBMQCkJFAAbGwcWBAQHFA4EHh8AGkZZAAAMFBQJRlkUDwwRR1kMFQcbRlkHFQA/KwAYPysAGD8rERIAORgvKxESARc5ETMRMxEzETMxMAEzMhYVECEhESECAiMiJzUWMzISEyEBNCYjIxEzIAOw9NPL/kv+Zf7+KLWrOCAWHHOIIwJQAex9nuftARUCg5ua/rIDuv36/j4MewYB5gHv/PxbVf6XAAIAsAAABqQERgARABkASkAmDwsLDAETExAIFgUFCAwDGhsSCg8KRlkBDw8IEQ0PDBUIE0ZZCBUAPysAGD8/MxI5LzMrEQAzERIBFzkRMxEzMxEzETMRMzEwAREhMhYVECEhESERIxEzESERExEzIDU0JiMEAAEA2cv+Tv5g/gqsrAH6pvABFICZBEb+O5ma/rIB7v4SBEb+NwHJ/a7+l7lcVAD//wAUAAAERAYUAgYA6QAA//8AsAAABAwGIQImAdQAAAEGAHYzAAAIswEUESYAKzX//wAC/hQEBgYMAiYAXAAAAQYCNrcAAAizARYRJgArNQABALD+hwRGBEYACwAyQBkEAQoLBQgICwEDDA0LIgYCDwkBAQRGWQEVAD8rEQAzGD8zPxESARc5ETMRMxEzMTAhIREzESERMxEhESMCL/6BpgJKpv6PpgRG/EkDt/u6/ocAAAEAyQAABAgG4wAHACNAEQADBQYDBgkIBwRJWQEHAwYSAD8/xisREgE5OREzETMxMAERMxEhESMRA2ai/WuqBbYBLf46+uMFtgAAAQCwAAADRAWJAAcAJ0ASBQACAwADCQgGBAQBR1kEDwMVAD8/KwAYEMYREgE5OREzETMxMAEhESMRIREzA0T+EqYB7qYDx/w5BEgBQQD//wAbAAAHTAdzAiYAOgAAAQcAQwEXAVIACLMBGwUmACs1//8AFwAABiMGIQImAFoAAAEGAENzAAAIswEeESYAKzX//wAbAAAHTAdzAiYAOgAAAQcAdgGwAVIACLMBIwUmACs1//8AFwAABiMGIQImAFoAAAEHAHYBGwAAAAizASYRJgArNf//ABsAAAdMByUCJgA6AAABBwBqAWQBUgAKtAIBLwUmACs1Nf//ABcAAAYjBdMCJgBaAAABBwBqAM8AAAAKtAIBMhEmACs1Nf//AAAAAAR7B3MCJgA8AAABBwBD/5QBUgAIswEKBSYAKzX//wAC/hQEBgYhAiYAXAAAAQcAQ/9hAAAACLMBFxEmACs1AAEAUgHZA64CcQADABG1AAIEBQABAC8zERIBOTkxMBM1IRVSA1wB2ZiYAAEAUgHZB64CcQADABG1AAIEBQABAC8zERIBOTkxMBM1IRVSB1wB2ZiY//8AUgHZB64CcQIGAgMAAAAC//z+MQNO/9MAAwAHABxACwQACQUBAQgFBgIBAC8zLzMRATMRMxEzMjEwASE1ITUhNSEDTvyuA1L8rgNS/jGLjIsAAAEAGQPBAUQFtgAHABK2AQUICQAEAwA/zRESATk5MTATJzYSNzMGByUMFmI4e0IlA8EWWgEMef73AAABABkDwQFEBbYABwAStgUBCAkFBwMAP8YREgE5OTEwARcGAgcjEjcBNQ8aYjV6RiAFthZk/vdyAR3YAP//AD/++AFtAO4CBgAPAAAAAQAZA8EBRgW2AAcAErYCBgkIAwcDAD/NERIBOTkxMBMWFyMmAic33yVCey1tGA4Ftvv6XgEcZRYAAAIAGQPBArQFtgAHAA8AGkAMBAENCQQQEQAIAwwDAD8zzTIREgEXOTEwASc2EzMGAgchJzYSNzMGBwGWDzh6ex47Df3XDBZiOHtCJQPBFtcBCHP+32EWWgEMef73AAACABkDwQK0BbYABwAQABpADAkNAQUEERINBRAHAwA/M8YyERIBFzkxMAEXBgIHIxI3IRcGAgcjNhI3ATUPGmI1ekYgAicOGGA4fRpCDQW2FmT+93IBHdgWW/72emQBNF0A//8AGf75ArQA7gEHAgsAAPs4ACC3AQAHQA0NSAe4/8CzDAxIB7j/wLMJCUgHABErKys1NQABAHsAAAOJBhQACwBDQCEJAgIIAwoBAQcEAAQDBQQMDQAFBQsGBgcIAAEEBAoHAxIAPy4zMxEzPxI5LzMzETMREgEXOREzMxEzETMzETMxMAElEyMTBTUFAzMDJQOJ/qAxxDH+tAFMMcQxAWAD5x/7+gQGH6oeAaH+Xx4AAQB7AAADmgYUABUAdUA6DAcVEAQEDwoFFBEAAwMOCwkGEwEBBgUHBBYXAQgIAgcDBgYACRQLCxEOEwwMEgkODQcNBw0FDwAFEgA/PxI5OS8vEjk5MjIRMxEzMxEzETMzETMRMzMRMxESARc5ETMRMzMzMxEzMzMRMzMzETMzETMxMAElFSUTIxMFNQUDEwU1BQMzAyUVJRMCOQFh/p8xxjH+pgFaKyv+pgFaMcYxAWH+nysB5x+oHf6FAXsdqB8BKwEbH6geAXz+hB6oH/7lAAEApAH0Al4D4wALABO2BgAADA0JAwAvzRESATkRMzEwEzQ2MzIWFRQGIyImpHFsaXRzamtyAux5fnx7d4GDAP//AJj/4wWuAPIAJgARAAAAJwARAhIAAAAHABEEJQAAAAcAZP/sCTsFywAJABQAGAAkAC8AOwBGAFtAMAAQBQowQjY8GSsfJSUrPBVCChcQCEdIHDMzKD8ZAw0iOTktRA1EDUQXGAYXGAcSBwA/Mz8/Ejk5Ly8RMzMRMxEzPzMzETMREgEXOREzETMRMxEzETMRMzEwExQWMzIRECMiBgUUBiMiJjUQITIWJQEjAQEUFjMyNjU0JiMiBgUUBiMiJjUQITIWBRQWMzI2NTQmIyIGBRQGIyImNRAhMhbsU120tF1TAe2hnJWjATiYpQJp/NWUAysCoFNdW1lZW11TAe2im5SjATeWp/s4UV1bWVlbXVEB66KblaMBOJanBAKqqgFUAVKoqubn7t8ByfDb+koFtvwCq6mnraulpavm5u/dAcns3aupp62rpaWr5ubu3gHJ7AD//wCFA6YBPwW2AgYACgAA//8AhQOmArAFtgAGAAUAAAABAFIAdQIfA74ABgAaQAoEAgMGAgYIBwUBAC8vERIBOTkRMxEzMTATARcBAQcBUgFWd/7fASF3/qoCJwGXRf6i/qFHAZcAAQBQAHUCHQO+AAYAGkAKAwAEAgACCAcFAQAvLxESATk5ETMRMzEwAQEnAQE3AQId/qh1AR/+4XUBWAIM/mlHAV8BXkX+aQD//wCY/+MDSgW2ACYABAAAAAcABAHBAAAAAf55AAACjwW2AAMAE7cABQIEAwMCEgA/PxEBMxEzMTABASMBAo/8eY8DhwW2+koFtgABAG0DIQLDBccAEgAmQBEAEgwICAkSCRQTBA8fAAkKHwA/zTI/MxESATk5ETMRMxEzMTABETQmIyIGFREjETMXMzYzIBURAkxOUHJbdGAOCkuRAQIDIQGkVEdpev6kAplYZfr+VAABAGIAAAQjBbYAEQBLQCgOAAQECQULEAIFBwUSEwMHCAdOWQAIDhFMWQgOCA4FCgoNTFkKBgUYAD8/KxESADk5GC8vKxEAMysRADMREgEXOREzMxEzMzEwASEVIREjESM1MxEhFSERIRUhAbgBNP7MprCwAxH9lQJE/bwBi4H+9gEKgQQrl/3plwABAEQAAARIBckAJQBwQEANCRERIh4aCw8VAg8aHCAXByYnEBwdHE5ZDR0MICEgTlkJIQ8hHyE/IU8hBAkDHSEdIRcAFxRMWRcYAAVLWQAHAD8rABg/KxESADk5GC8vX15dETMrEQAzETMrEQAzERIBFzkRMxEzMzMRMzMxMAEyFwcmIyIGFRUhFSEVIRUhFRQGByEVITU2NTUjNTM1IzUzNTQ2ArDJnjyYk3p+AaT+XAGk/lxBSgMb+/zOyMjIyOAFyVCDR4eBuoGmgSFkiCyajTDzI4Gmgc+yzQAAAwCa/+wF0QW2ABYAIQAqAGBANyIcHB0mFxAUFA0JAhIJFwsdBissGyJLWRATTlkDGwsQDg4QCxsDBR0eHipLWR4GHRgGAE1ZBhkAPysAGD8/KxESABc5GC8vLy8vKysREgEXOREzMxEzETMRMxEzMTAlMjY3FQYjIiY1ESM1NzczFTMVIxEUFgEUBCEjESMRISAWATMyNjU0JiMjBU4iVgs8bm2BnZ0+Yt3dNP6R/uv+9kClAQYBAP79oTTIuay3UnUOBH0eiIoBz1BFv9OB/kdNUgOX4+r9wQW20/3ukaKRjgAAAQA//+wEiQXLACYAcUA/HRcfFhYaCwIHBxokEQQKGhcGJygLFxgXTlkIGAUdHh1OWQIeDx4fHi8eAwkDGB4YHhMiIgBMWSIHEw5MWRMZAD8rABg/KxESADk5GC8vX15dETMrEQAzETMrEQAzERIBFzkRMxEzMxEzETMRMzEwASADIRUhBxUXIRUhFhYzMjcVBiMiAAMjNTMnNTcjNTMSADMyFwcmAxv+wU8B/v30AgIBz/5BJcuqnJmSq+3+3y6mmAICmKQnASTtyaVHpgU1/m2BOUAtgbTFQpZBAQ0BAYEqLFCBAQUBJGGLVgAEAI3/+AYKBcEAAwAPABcAKwBFQCQlGyAqEAoUBAQACioCGwYsLSMeBhIHGBYNJxgNGA0YAgMGAhgAPz8SOTkvLxEzETM/Mz8zERIBFzkRMxEzETMRMzEwAQEjAQEUBiMiJjU0NjMyFgUUMzI1NCMiJSImNTQ2MzIXByYjIhUUMzI3FQYFH/zVlAMrAX+plIuqp5SNqv4VsrCwsv3Kpra8q2hYIVFQ4NxiWk4FtvpKBbb7mJ+3uZ2euLqc7u7r27GhqLMjZx/u6yFlJQACAHf/7AOcBcsAHAAkAD1AHyMaGg8JHRYDFgkMBCUmIw8NGQoFDBMCDAIMBh8TAAYALzMvMxI5OS8vERIXORESARc5ETMRMzMRMzEwJTI3MwYGIyImNTUGBzU2NxE0NjMyFhUUAgcRFBYTNCMiBhURJAJ9rhJfCJmOlqBgYE5ylod1h86vUq5/Qz4BAG/VprK1qfMjFnEVJgHyip+hirn+0Er+5Wh7BCvCVmz+S4kAAAQAyQAAB8MFtgAPABsAJwArAF9AMQkGBgcBDQ0AHBYiEBArKBYABwYsLR8TJRkLKBMDGQgTGRMZKAgoKUpZKBIOCAMBBxIAPzM/Mz8rERIAOTkYLy8REjkREjkRMxEzERIBFzkRMxEzETMRMxEzETMxMCEjASMSFREjETMBMyY1ETMBFAYjIiY1NDYzMhYFFBYzMjY1NCYjIgYDNSEVBMe7/UwIEJfCAqoIDpgC/KGTi6Khk4ui/iJRXVtPT1tcUlYCAATL/uBs/MEFtvs69YoDR/y3o7i7oKO1u51ydnVzc3Bw/SCHhwACACUC5QWFBbYABwAYAE9AJwABDwwMDREUFBMTDQYBAwUZGhcWCQoKEQ4OBAcDAwQQCAgUDQEEAwA/xDIyOS8zETMRMxEzETMzETMzMxESARc5ETMRMxEzETMRMzEwASMRIzUhFSMBAyMXESMRMxMTMxEjETcjAwFxe9ECH9MCWMkIBne7xMu0fwYI0wLlAmdqav2ZAi+B/lIC0f3RAi/9LwGkif3TAP//AFAAAAX0Bc0CBgF2AAAAAgBm/90EiwRIABcAHwA0QBofDg4EGAwMFQQDICENFC8fPx8CHx8RHAgRAAAvMi8zEjkvXTkzERIBFzkRMxEzETMxMAUiJgI1NDY2MzIWEhUhERYWMzI2NxcGBhMRJiYjIgcRAnmd8YWK9JWY84f8xTGmUoO3UUhi2ZMyo1iteiOTAQWdq/+Mjv79pf6cNUZpgSmbfAKLARU1QnX+6f//AEf/7AXzBbYAJwIXAlwAAAAmAHv7AAEHAkADYP2zAAu0BAMCGRkAPzU1NQD//wAg/+wGCAXJACcCFwKiAAAAJwJAA3X9swEGAHX/AAALtAEDAg4ZAD81NTUA//8AR//sBgQFtgAnAhcCnAAAACYCPQwAAQcCQANx/bMAC7QEAwIsGQA/NTU1AP//AGr/7AYABbYAJwIXAkYAAAAnAkADbf2zAQYCPzEAAAu0AQMCDhkAPzU1NQAAAgBm/+wENQXHABoAKABBQCImBx8PDwAAFAcDKSoLIkdZDgQLCxgEGBFGWRgDBBtGWQQWAD8rABg/KxESADkYLxI5KxESARc5ETMRMxEzMTABEAIEIyImNTQSNjMyFhc3ECEiBgc1NjYzMhIBMjYSNyYmIyIGBhUUFgQ1p/7sray7iOiXYZIrBP7mPpAwL5tK0tj9ol+meBYZgFBlpWVlA6b++v416cnAqQEzoV1LWgGVLCGfFyX+7PvGkAEDlmFshPqAdoIAAgAnAAAEbQW2AAUADAAoQBMJBQoEBQQODQYFAQUJSVkFEgEDAD8/KxESADkREgE5OREzETMxMDcBMwEVIQEGBwEhASYnAc+mAdH7ugIhPSj+/ALR/v5EaAVO+rBmBPThefz+AvnKAAABAMn+EAUhBbYABwAjQBEABwMEBwQJCAUCSVkFAwAEGwA/Mz8rERIBOTkRMxEzMTABESERIxEhEQR3/PyqBFj+EAcN+PMHpvhaAAEATP4QBN0FtgALADFAGgcJCQMACAIKBgIABAwNBAdJWQQDAAlJWQAbAD8rABg/KxESARc5ETMRMzMRMzEwEzUBATUhFSEBASEVTAJ3/ZkEQPywAkP9pAOq/hBrA5wDM2yX/Pz8jZgAAQBoAo0EKQMXAAMAFUAJAgAFBAEAUFkBAC8rERIBOTkxMBM1IRVoA8ECjYqKAAEAJf/yBLwGmAAIABxACwgKAwkDBgQEAQgBAC8vEjkvOTMRATMRMzEwBSMBIzUhEwEzAm9//um0ASHrAgKJDgMOh/1UBb0AAAMAdwGTBS0EDAAVACEALQAzQBgfDCsAACUZDAQuLyIcHBEGCRMPKBYWAwkALzMzETMvMxI5OTMRMxESARc5ETMRMzEwARQGIyImJwYGIyImNTQ2MzIXNjMyFgEyNjcmJiMiBhUUFgEiBgcWFjMyNjU0JgUtp4BdmUE8mViDqKiDtXp8uYWi/H1CbTYybUhMZGECoUJtNzNuR0xkZQLPg7lqdGhxrY6Gs9vXr/67W2RhXWlXU2oBeVxiYV5rVFVpAAEADP4UAvgGFAAUABxADAgSAhINAxUWEAsFAAAvMi8zERIBFzkRMzEwATIXFSYjIhURFAYjIic1FjMyNREQAn1PLDE+sKWjSjs9OrYGFBCJFvP64bC7E4cW8wUfAWoAAAIAYgGHBC0EHwAXAC8AcEBAKA8bAw8DMTAnHh4YUFkPHh8eLx4DCQMeKkAqJFBZGypADwYGAFBZDwYfBi8GAwkDBhJAEgxQWQMAEhASIBIDEgAvXcQrABoYEM1fXl0rABAYxBrexCsAGhgQzV9eXSsAEBjEERIBOTkRMxEzMTABIgYHNTYzMhYXFhYzMjY3FQYjIiYnJiYDIgYHNTYzMhYXFhYzMjY3FQYjIiYnJiYBUDZ/OWyUQ3BYTVstNYA2ZZlDb1hJWzE5gDVqlkV0UkVfMTeBM2SaRXZPVFUCAEA5lm4cJSEZQjmXbR0lHhkBlkQ1lW0gIh0aQjeWbiAhIhgAAAEAaACmBCkFAgATAEZAJgUBEAsLCQoOBAATAQgUFQ0FBgVQWQoIDwYBCQMGDgIBAlBZEhEBAC8zxCsRADMYL19eXcYzKxEAMxESARc5ETMRMzEwASE1IRMhNSETFwchFSEDIRUhAycBff7rAVR//i0CE4d9bQEX/qqBAdf96YN9AcGJARCJAR855on+8In+5Tf//wBoAAEEKQTZAiYAHwAAAQcCKwAA/XQACbMBAAcSAD81NQD//wBoAAEEKQTZAiYAIQAAAQcCKwAA/XQACbMBAAcSAD81NQAAAgBvAAAEPQXDAAUACQAgQA0IAAYDAAMKCwkHAgUCAC8vEjk5ERIBOTkRMxEzMTATATMBASMJA28BwkgBxP48SAFi/sP+wwE9At8C5P0c/SEC4QIT/e397AD//wAdAAAEHAYfACYASQAAAAcATAK2AAD//wAdAAAEDAYfACYASQAAAAcATwK2AAAAAQDbBNkDvgYMAA0AGEAJCwMPDgoEgAcAAC8yGswyERIBOTkxMAEiJiczFhYzMjY3MwYGAki5qgqcCVtxZ2MLnQyyBNmPpGhSWGKelQAAAf+R/hQBVgRIAAwAHUANCwgIDg0JDwAFRlkAGwA/KwAYPxESATkRMzEwEyInNRYzMjY1ETMRECtfO0VDTkmm/hQZhxRVVwT8+xD+vAAAAQGJBM0CdQYUAAkAE7YJBAoLBIAJAC8azRESATk5MTABNjY3MxUGBgcjAYkTJwqoC1gvWgTlN6dREjO8RgABAXH+OwJv/4MACQATtgkECgsJgAQALxrNERIBOTkxMAE2NjczFQYGByMBcRwzB6gLYjda/lRAujUSM8FCAAEBgQTZAn8GIQAJABO2CQQKCwmABAAvGs0REgE5OTEwAQYGByM1NjY3MwJ/HTUGpg5jMVwGCD3BMRM9vzkAAgAnAjkCngXHAAsAFQAgQA4GDAARDBEXFgkTHwMOIQA/Mz8zERIBOTkRMxEzMTATFBYzMjY1NCYjIgYFECEiJjUQITIWsFJeXlZWXl5SAe7+xJ6dATuengQAqKalq6qkpan+N+zdAcXoAAIAFAJKArQFvAAKABQAPEAfFAULBwMDCQIAAgUDFRYBBQUJDxQfFAIUFAMOBx8DIAA/PzMSOS9dMzMRMxESARc5ETMzETMzETMxMAEjFSM1ITUBMxEzITU0Nw4DBwcCtH2R/m4BmIt9/vIGBRgeHguoAxTKymUCQ/3Nw4ZLDCctLRH2AAEAOwI3AokFqgAdACtAFRADHBcJFxoDBB8eEwAABhsYHg0GIQA/Mz8zEjkvMxESARc5ETMRMzEwATIWFRQGIyImJzUWFjMyNjU0JiMiBgcnEyEVIQc2AUiRsKqmSospOIw2X25tZjlMHzshAe/+gxQ+BGiPe4ybHxeDIiZTWU5YEQgpAaBo5gwAAAIAKQI5AqIFxwAXACMANkAcGxIhCwAABhIDJSQeCxUADxAPAg8PAxgVIQgDHwA/Mz8zEjkvXRI5MxESARc5ETMzETMxMBMQNjMyFxUmIyIGBzM2NjMyFhUUBiMiJgUyNjU0JiMiBhUUFinb20oxNFONlgoIHXFVfZSmjZmtAURRY1hWVXBqA8MBBf8PchKZpis7lH6QpNJjXWNPW1o7WXwAAAEAOQJKAo8FtgAGABxADQEFBQACAwcIAgMeACAAPz8zERIBFzkRMzEwEwEhNSEVAaIBXv45Alb+oAJKAvh0XvzyAAMAMwI5ApMFxwAVACIALQA/QCIWDSYTKwMcBwcDBRATDQYuLwUQICALKRspAikpGQohIwAfAD8yPzM5L10zEjk5ERIBFzkRMxEzETMRMzEwATIWFRQHFhUUBiMiJjU0NjcmJjU0NgMUFjMyNjU0JicnBgYTIgYVFBYXNjU0JgFkfJeUsKWKkp9JVUo5nTVUVlpUXVEcSEasREtEUYxOBcd2aIJMSp5xiYB0RXQuLl1EZn79ZjxJSTw/TxwKIlQB7zw5L0chNmE5PAACACMCOQKcBckAFgAiADxAHxoRIAoAAAURAyMkHQ4KCwsUDw4fDgIODgMXFB8IAyEAPzM/MxI5L10SOREzETMREgEXOREzMxEzMTABEAYjIic1FjMgEyMGBiMiJjU0NjMyFiUiBhUUFjMyNjU0JgKc2tRTMTFdARQVCiN0QYOZqYiYsP64UV9VV1RzZwRG/vL/D3QUAUYzNJKDiKXKW19XUV9VPmFyAAAWAFT+gQfBBe4ABQALABEAFwAbAB8AIwAnACsALwAzADcAOwA/AEMARwBTAFsAawB0AHwAiQD4QIdBQD08MTAPBQAMVE5YSHZrcGB6Z4WGRUQpKCUkFAoJFxeGBhI7G39nYDgYNy9rNCxIIx8gHAMRTgwZiosKACpCWlGGXHRcKUFGPmR1dWxFPYJ9VktrdmsmMiUxFQ0AQgFBPlw9bA0xMgNrDFxsa2tsXAMBLSwdHBkYExIPDDk4NTQhIAcGBAEALzMzMzMzMzMzMy8zMzMzMzMzMzMSFzkvLy8REhc5ETkSOTkROTkRMxEzETMRMxDEMsQyETMRMxI5ETMRMxEzEMTEMhEzETMREgEXOREzMzMzMzMzMzMRMxEzETMRMxEzETMRMzMzMzMzMzMzMTATESEVIxUlNSERIzUBETMVMxUhNTM1MxEhNSEVITUhFQE1IRUBIxEzESMRMwE1IRUBIxEzATUhFTM1IRUBIxEzNSMRMwEjETMFFAYjIiY1NDYzMhYFFDMyNTQjIiUzMhYVFAYHFRYWFRQGIyMTMzI2NTQmIyMVFTMyNjU0IwEiJzUWMzI1ETMRFAZUAS/ABc4BMG35AG/ABQ7Dbf1JARH74QEO/vIBDgS3bW1tbfvCARD8MG9vAsABEHcBEfqob29vbwb+bW37n4d/f4eHf36I/nOHh4eHAeGsbXAuLD0ubV7Pe0IuJCovO0oxJVoBXjQcKxlWfWkEvgEwb8HBb/7QwfkCAS/CbW3C/tFtbW1tBv5vb/qoAQ4CAgEP+jttbQGmAQ4ESm9vb2/8LwEQeQEP/WgBEEmRnJyRkpuak8XFxGFDUzFCCAgORDVRWQFiIiAiHeOaKyVK/voKZghWAZL+cl9jAAADAFT+wQeqBhQAAwAeACoALkAZAQsXJQQeHxEDCSssKB4UDiIeDg4eIgMCAAAvLxc5Ly8vETMRMxESARc5MTAJAwU1NDY3NjY1NCYjIgYHFzYzMhYVFAYHBgYVFQMUFjMyNjU0JiMiBgP+A6z8VPxWA+ssQWdJu6VPukdSoFo/PjFIVDsbR0ZCSUhDSEUGFPxW/FcDqfsvMkExUn5Yh5o4KrJQOi81SzZEcEo7/u0/SEk+QElI////kf4UAlcGIQImAjcAAAEHAUz+qQAAAAizARgRJgArNf//ABkDwQFEBbYCBgIHAAAAAgAK/+wE3wYrAC0ANgBmQDkbBxcLNCUuHx8rAi0CJQsHEgY3OBQOR1kAIS4hR1krLg8uHy4CCQMULhQuBSgoMUZZKAEFHUZZBRYAPysAGD8rERIAOTkYLy9fXl0RMysRADMrERIBFzkRMzMRMxEzETMRMzEwARYVEAAhIBE0NzY1NCYjIgYHJzYzMhYVFAcGFRQzIBE0JyYkJjU0NjMyABMzFSUmAiMiBhUUBARWBP7g/v3+dxAPJCAZNg8hU19YXQ8Q6QF3BN/+yaC2qNABACqP/scct3tdYQETA04uQf6f/m4BWDl7ehcvIw8JdiddXSODhDrPAnA/LAJpvIOQo/7N/teBgdMBAF9LjZoAAQAAAAAEewXDABUAKEAUERIHEhQDFhcAEhQDEhIFCkpZBQQAPysAGD8/EjkREgEXOREzMTABEhI2NjMyFxUmIyIOAwcRIxEBMwI5eo1NXDowKBofKDtWfGUfrP4jugLNASMBN2wwD4cGOKH87FX94wIvA4cAAAIAEv/sBncESAAUACkATEAnGAMSISEeJw0KDR4DBgUqKxMfHwAIFQsGCAZGWQgPJBsAG0ZZEAAWAD8yKxEAMxg/KxEAMzMREjkYLzkREgEXOREzETMSOREzMTAFIiY1NBMhNTchFSMWFRQGIyInIwYBBgIVFBYzMjY1NTMVFBYzMjY1NCcCKbrHh/7jjgXX+nXIud1ECET+zz9CbHVdbKJrXXVtbxTn8PABB0pEjvz78Oe2tgPOhP7+Z66oj328vHqSqa3+7wD//wDJAAAGcQd1AiYAMAAAAQcAdgGcAVQACLMBHQUmACs1//8AsAAABssGIQImAFAAAAEHAHYBzQAAAAizAS0RJgArNf//AAD91QUQBbwCJgAkAAAABwJbATUAAP//AF791QPNBFoCJgBEAAAABwJbAMcAAP///t//7AXSBc0AJgAyFAABBwJc/kcAAAAJswMCGgMAPzU1AAACAHX91QI1/4MACwAXAB5ADBIGDAAGABgZFQMPCQAvM8wyERIBOTkRMxEzMTABFAYjIiY1NDYzMhYHNCYjIgYVFBYzMjYCNX1mZXh4ZWV+bkIzM0I8OTVA/q5heHViYnV2YTk8PDk4PT0AAgCYBGgCzwXFAAgAFwAeQA4OCQMIDBMJBRgZAgsIFQAvxNzGERIBFzkRMzEwATY3MxUGBgcjJTQ3FQYVFB4CFRQjIiYBsEYcvSl3MU7+6O15HyUfXTdDBIe1ehROrDl2oz1IKTUUExAaHEpEAP//AB0AAAbTBh8AJwBJArAAAAAmAEkAAAAHAEwFbQAA//8AHQAABsMGHwAnAEkCsAAAACYASQAAAAcATwVtAAAAAgB9/+wGZAYUABUAIQA8QB8WBg8RERwAABQLBgQiIxQLAwkJH0lZDwkEAxlJWQMTAD8rABg/xisREgA5ORESARc5ETMzETMRMzEwARAAISAAERAAISAXPgI1MxcGBgcWARASMzISERACIyICBbz+nf7G/r3+oQFhAUMBRbMyOhu2Dh2DaGD7dfr08/b18vP9At3+nv5xAYkBagFoAYbXDENmaRabrSew/v7+1v7OATEBKwEnATH+0QAAAgBz/+wFGQTwABYAIgA8QB8XBxASEh0AABUMBwQjJBUMAwoKIEZZEAoQAxpGWQMWAD8rABg/xisREgA5ORESARc5ETMzETMRMzEwARAAIyImAjUQADMyFz4CNTMXBgYHFgUUFjMyNjU0JiMiBgRi/vLuk+R8AQzu2YkzOhq0Dx95Zkf8vZ6tr52fr62cAiX+9P7TigECrQEMASuND0FjbhecryaKudPb29PS2NgAAQC6/+wGewYUABsAM0AYBQcHAQsUEQsRHRwKAQ4bBRIDDhdJWQ4TAD8rABg/xjMSOTkREgE5OREzETMzETMxMAEVPgI1MxcGBgcREAAhIAA1ETMRFBYzMjY1EQUZOkYftQ4hrJX+4f74/vT+1KrMxrjBBbbGCD5wbha2uBn9jf7+/uoBH/0DrvxGt8TBvAO4AAABAKT/7AWWBPIAHQBEQCIBHA0PDxMUBwcKExwTHh8VFgoSFgMUDQgdDxkERlkZFhQVAD8/KwAYPzPGEhc5ETMREgE5OREzMxEzETMRMxEzMTABERQWMzI2NREzFTY2NTMXBgYHESMnIwYGIyImNREBTHqCrJ+mUkqyDyCwjYkYCTS1b8vIBEb9O4aEvNUCPnkLgJoXur8O/KyTUlW+0QLLAP///FME2f3cBiEABwBD+soAAP///Q0E2f6WBiEABwB2+4QAAP///BkE2f8BBd0ABwFS+xEAAAAB/QgEuP5zBo8AEQAeQAwCBQUNDQgAABMLEAQAL8wyEQEzETMzEjkRMzEwARQHByMnNjY1NCYjIgc1NjMg/nOmCmkMVk5DST4gJkUBAAXXjCJxsA4yKyspBmQKAAH9O/6g/gL/fQALABG1BgAADQkDAC/NEQEzETMxMAU0NjMyFhUUBiMiJv07OyooOjooKjvyOTY2OTc3NwD//wDJAAAD+AdzAiYAKAAAAQcAQ//YAVIACLMBDQUmACs1//8AywAABVIHcwImAbIAAAEHAEMAaAFSAAizAREFJgArNf//AHP/7AQSBiECJgBIAAABBgBDtwAACLMCHBEmACs1//8AsAAABGIGIQImAdIAAAEGAEPcAAAIswEPESYAKzUAAQCF/+wHkQXJADEARUAkIhYqJy8JCQQnGxYFMjMAHxkfSVkQKCgTBhkELCUTJUlZDBMTAD8zKxEAMxg/MxI5LzkrEQAzERIBFzkRMxEzETMxMAEiBgcnNjMyABEQACMiJicjBgYjIAAREBIzMhcHJiYjIgIREBIzMjcRMxEWMzISERACBaQ8Xi1FfpbkAQH+5f9srFMIUKlr/wD+5f/kmXxGLV08k6XPu4tmqmaOu86lBS8pH5JQ/oj+rf6N/mEtMzIuAZsBdwFTAXhQkh8p/tf+9v7T/rJMAcn+N0wBSwEwAQsBKAABAAAAAAYdBEgAHQAoQBYXAA0OBQUeHxsVDQASCgQEFg4FDwQVAD8/MzMSFzk/ERIBFzkxMAEGBgMjATMTFhczNjYTAzMAFhczNhIRMxACByMDJgMnChSz1f5/rPYgLggTSo6ssgEJLQoIrZmmw9u2fSEByRoz/oQESP1JXb01owEkAdX8/5AsuAGzAVL+lv4H5QFaXAACABcAAAT8BhQAEQAaAExAKAgEEhIBDxYLCwYPAAQbHAcRABFJWQQACBpJWQAIAAgPAgAPEkpZDxIAPysAGD8SOTkvLysRADMrEQAzERIBFzkRMxEzMxEzMzEwEyERMxEhFSERMyARFAQhIREhATMyNjU0JiMjFwE/rAGi/l7JAjH+9/77/mj+wQHr1cC1utq2BPoBGv7mlP7g/mTQ2gRm/CuJkIp6AAACABcAAAScBScAEQAZAEdAJgQAExMPCxYHBwILDQQaGwMNDg1GWQQSRlkEBAsQAA4PCxNGWQsVAD8rABg/M8YSOS8rKxEAMxESARc5ETMRMzMRMzMxMAEhFSERISARFAYjIREjNTM1MxERISA1NCYjAagBWP6oAT8Btd/c/iHr66YBMQEfh5wESIz+xf7NpqgDvIzf/M3+l7lcVAABAMn/7AchBcsAIABKQCkXExMUBhgdDAUYERQGISIbAElZGwQGEhcSSVkDFxcUFQMUEg4JSVkOEwA/KwAYPz8SOS8zKxEAMxg/KxESARc5ETMRMxEzMTABIgQHIRUhEgAzMjcVBiMgAAMhESMRMxEhEgAlMhcHJiYFj+P+/B8Cv/09CAEJ95rCmN7+wf6lCP6iqqoBZB4BcQEw1bZIZJ0FM/rxlv7v/uI3lTkBcAFU/VAFtv2SATMBTgJckjAmAAABALD/7AWcBFwAIQBZQDIWGRkKAwkFBQYQIBgDBgUiIw0TRlkNEBkECQRGWRYPCR8JAgsDCQkGBw8GFQAcRlkAFgA/KwAYPz8SOS9fXl0zKxEAMxg/KxESARc5ETMRMxEzMxEzMTAFIgAnIREjETMRITYkMzIWFwcmIyIGByEVIRYWMzI2NxUGBHfr/vQL/uGmpgEhGAEN31GaNjKKZaOnEAIY/eYJqaQ9d2JuFAEK+P4SBEj+M+v2IBmNM6Sqjby1FiWTOQACAAAAAAVtBbYACwASADRAGwIDBwwDDQoFFBMBBQwFSVkQCAwMBwgDCwMHEgA/MzM/EjkvEjkrEQAzERIBFzkRMzEwASMRIxEjASMBMwEjASEnJicGBwOYlJyV/t+yAmieAme3/VwBTFI4HhhAAqr9VgKq/VYFtvpKAz/PkGRipAAAAgAKAAAEeQRIAAsAEgA1QBwFBgoMBg0DAQYUEwQIDAhGWRELDAwKCw8GAgoVAD8zMz8SOS8SOSsRADMREgEXOREzMTABASMDIxEjESMDIwEDISYmJyMGAqgB0azPcZdzzawB0SEBDys4IgkcBEj7uAHp/hcB6f4XBEj+LWyKalwAAAIAyQAAB14FtgATABoARkAlDgoKCwIDEhUDFAgHCwcbHAUBCQ4JSVkUGAwODgsQDAMTBwMLEgA/MzMzPzMSOS8SOTMrEQAzMxESARc5ETMRMxEzMTABIxEjESMBIwEhESMRMxEhATMBIwEhAiYnBgYFhY+ak/7jugEi/l+qqgHhAQaeAma8/WYBPnYcDBMjArD9UAKw/VACsP1QBbb9kgJu+koDSAE1Vi9DaAACALAAAAYUBEgAEwAZAE1AKxENDQ4FBgEZBhgLCg4HGhsIBAwRDEZZGBUTLxE/EQIREQ4TDw8PCgYCDhUAPzMzMz8/EjkvXRI5MysRADMzERIBFzkRMxEzETMxMAEBIwMjESMRIwMjEyERIxEzESETFyMGBgchBEYBzqrQcZhu0azR/t+mpgFexWgICiBZAQwESPu4Ae7+EgHu/hIB7v4SBEj+MwHNcyJf2QAAAgAUAAAFrgW2AB8AIgBLQCggAQ8QIR4eHRACAQcGJCMeASEfHyFJWQ4SHRJKWSICHR0YHwMQCBgSAD8zMz8SOS8zMysRADMrERIAOTkREgEXOREzETMRMzEwARUBHgIXEyMDLgIjIxEjESMiBgYHAyMTPgI3ATUFIQEFKf5adppkMoWuiSNEZVkbqhpbY0Egh7mIL2OVdv5lA779CgF7BbaF/hEGSIuk/jsByW9gJv1CAr4nX2/+NwHFn45JBwHvhZn+OQAAAgAMAAAFFARIACAAIwBOQCohAQ8QIh8YHx4QAgEHByUkHwEiICAiRlkRDhIeEkdZIwIeHhggDxAIGBUAPzMzPxI5LzMzKxEAMzMrERIAOTkREgEXOREzETMRMzEwARUBHgMTIwMuAiMjESMRIyIGBgcDIxM+AzcBNQUhAQSL/q5Xb0kxm6yFIjpUTAqZC0tSOCeHqoMYMEluV/6xAyD9tAElBEhp/qAHMFBp/nEBUFdHHP32AgoaQF7+rgFQPWlPMggBYGmM/sEAAAIAyQAAB8UFtgAkACcAYUA1IR0dHiYjDxACJyUBBwEnECIbIxgeCSkoIwEkJiQmSVkSDhwhHElZJwIhIR4kAx8DGBAIHhIAPzMzMz8/EjkvMzMrEQAzMysREgA5ORESARc5ETMRMxEzETMRMxEzMTABFQEeAhcTIwMuAiMjESMRIyIGBgcDIxM2NyERIxEzESEBNQUhAQc9/l14mWUtiKiKH0ZpXxisGV5kQiGHsoc3OP5SqqoC1/5oA8H9CgF7BbaF/g4GSJCc/jsByWhjKP1EArwoX2z+NwG+uDr9UAW2/ZIB6YWZ/jcAAAIAsAAABroESAAkACcAZ0A6IR0dHiYjDxACJyUBBwEnECIbIxgeCSkoIwEkJiQmRlkSDhwhHEZZJwIvIT8hAiEhHiQPHw8YEAgeFQA/MzMzPz8SOS9dMzMrEQAzMysREgA5ORESARc5ETMRMxEzETMRMxEzMTABFQEeAxMjAy4CIyMRIxEjIgYGBwMjEzY3IREjETMRIQE1BSEBBjH+rlhvSTCbrIUiOlZKCpoKS1Q3Joeqgy8l/s2mpgI1/rADIf20ASUESGn+ngcxTmn+cgFQVkYc/fgCCBs/XP6uAVB4KP4QBEj+NQFiaYz+xwABAD/+TgQ1BtEASwCEQE0AEyE/GUZGCj83QzwqHC0oEwtMTUkWSllJEzk0MQ8uHy4vLgMJAy4qQEMdHB0cSlkdHRA8KiokSlkqBAoJSVkKEBADSVkQIwwHSVkMIgA/KwAYPysAGBDGKwAYPysRADMSORgvKxESADkaGBDdX15dOcQyPysREgEXOREzETMRMzEwFxQWMzI3NjMyFxUmIyIHBiMiJjU0Njc2NjUQISM1MzI2NTQmIyIGByc2NyYnJzUzFhc2NjMyFxUmIyIGBxYWFRQGBxUWFhUUBAUGBvBXWWF4eEabR1CgRGlpabO42ejMtf5A2tHN4aKJartuVqi+OXUxe1yDXINAMjAYKyxvMLLBv6q6y/7l/uaKhok3MgcGJ6YzBQV9hX6BCQiKjQEMj5OEa4A3RXJyHEJ5NBs7iHNWDnEKUkcXvY+MuBoIGLKQ0NUJBTcAAAEAGf57A38FTgBGAINAThcpNgsuEBAgCwMOCD4yQDwpC0dIRD5BAAVHWQAPQR9BL0EDCQNBPiYaRlkjHUZZDjMyMzJGWSYjMzMjJgMgPj44RlkIPhAgIhMsR1kTFgA/KwAYPz8zKxESABc5GC8vLysREgA5KysAGBDUX15dxCsREgA5ERIBFzkRMxEzETMxMAEyFxUmIyIGBxYWFRQHFRYVFAYHDgIVFBYzMjc3MhcVJiYjBwYjIiY1NDY3JDU0JiMjNTMgNTQjIgYHJzY3Jic1MxYXNjYC+DMtGCkvZy16jNP48uFdbTBLWVZ6r30nFVQ3s4JckJ++tAFOnJ+UdwE3/EqPWDt8flxne0uMWIYFTg9wCk8+HIpruDkIR8qUqAMCFyosMSsFBSePExgFBXdwdH0DBL5hWo2soiIkhzcPdWIbNIluVf//AG0AAAXyBbYCBgF1AAD//wCk/hQFhwYSAgYBlQAAAAMAff/sBb4FzQALABIAGQBHQCUWEBAGFw8PAAYAGhsWEElZDxYBCwMWFgMJCRNJWQkEAwxJWQMTAD8rABg/KxESADkYL19eXSsREgE5OREzETMRMxEzMTABEAAhIAAREAAhIAABMhITIRISEyICAyEmAgW+/p3+xP69/qEBYAFEATsBYv1h5fcN/CsN+ejg+xMD0xH0At3+of5uAYsBaAFlAYn+cPxEAREBDP71/u4EtP7+/wD+AQQAAAMAc//sBGIEXAAMABMAGgBJQCcXEREHGBAQAAcAGxwXEUZZDxcfFwILAxcXAwoKFEZZChADDUZZAxYAPysAGD8rERIAORgvX15dKxESATk5ETMRMxEzETMxMAEQACMiJgI1EAAzMgABMjY3IRYWEyIGByEmJgRi/vLuk+R8AQzu5gEP/giepAr9aQmgoJyeDQKTD6ECJf70/tOKAQKtAQwBK/7O/U24v7q9A1itp6isAAABAAAAAAVIBcMAFQAgQBAGFhMXEQBKWREECgUGAwUSAD8/Ejk/KxEBMxI5MTABIgYHASMBMwEWFzY3Ez4CMzIXFSYE4TtOOf64xf3utAFSSCMgRqI7VG5ZKk84BTdntfvlBbb8VsePkN8CBr+YQRONFAABAAAAAAQ9BFIAFgAeQA8BFw8YDRJHWQ0QBQEPABUAPz85PysRATMSOTEwIQEzExIXMzYTEz4CMzIXFSYjIgYHAwGW/mqu4WQTCBdSYCVHW1QtHh0mLzoc+ARI/Zv+9GR2AQsBNXp7NAp/CFRc/N///wAAAAAFSAdzAiYCgAAAAQcDdgTXAVIACrQCASEFJgArNTX//wAAAAAEPQYhAiYCgQAAAQcDdgRkAAAACrQCASIRJgArNTUAAwB9/hQJogXNAAsAFwAuAERAJgwGEgAhLicYAAYGLzAlKkpZJRsdHBwDIBgPCRVJWQkEAw9JWQMTAD8rABg/KwAYPzMSOREzPysREgEXOREzETMxMAEQACEgABEQACEgAAEQEjMyEhEQAiMiAiUzExYXMzY2EzMBBgYjIic1FjMyNjc3BVT+uf7c/tf+vQFDASwBIwFF+93f2drd3Nja4QRvsPZOFAgLU+Sw/itFvIhMSjdCXnUjPQLd/qD+bwGLAWgBZgGI/nD+oP7X/s0BMQErASkBL/7SQf2Lz2Ys+wKD+yC2nhGFDGdZnP//AHP+FAh7BFwAJgBSAAAABwBcBHUAAAACAH3/hwYQBi0AEwAoAFFAKhQKJg0HESIiAxwfAAAcBxcKBSkqJCImDSZJWREPDQMcGhcHF0lZBQMHEgA/MzMrEQAzMxg/MzMrEQAzMxESARc5ETMRMzMRMxEzMxEzMTABEAAFBiMiJyQAERAAJTYzMhcEAAEUEhc2NjMyFzYSNTQCJwYjIicGAgYQ/tH++Bp3fBT+9P7RASsBEBR8eRYBDAEt+yHKvRFJNm4fvcrKvR9ucR+9ygLd/tL+cyxvbykBigE2ATEBhSxsbCz+c/7V9P7PKTAmVikBMfT0AS8nWFYn/tMAAAIAc/+TBM8EtAAXAC0AUEAqGAwPCSsbJRUDIwAAAyAbCQwGLi8oJSsPK0ZZFRIPECAeGwkbRlkGAwkVAD8zMysRADMzGD8zMysRADMzERIBFzkRMxEzMxEzETMRMzEwARQCBwYGIyImJyYCNTQSNzY2MzIWFxYSBRQWFzY2MzIXNjY1ECUGBiMiJicGBgTP4MwJQDg5PQnL5eDQCD45OEAJyuL8UH2JDDw1ZxiGfP78DT0zNTwMiX0CJen+3yU2LSs4JAEm5ekBICQ4Kis5Jv7c4bHSHyoiSh/SrwFgPiogICwf0QAAAwB9/+wHfwg7ABUARQBUAFVALkM3HysrASZGS1BIPAw3ClVWFQICBwcQDFJASDoiQDpASVkoOgQcFjQWSVkuNBMAPzMrEQAzGD8zKxEAMxgQ1hrc1M0yEjkvMxESARc5ETMRMzEwARUjIi4CIyIGFRUjNTQ2MzIeAjMBMjY3FhYzMhIREAIjIgYHJzYzMgAREAAhIiYnBgYjIAAREAAzMhcHJiYjIgIREBIBFAc1NjU0LgI1NDMyFgWiEVSOeGYrLzx9dHA6cHeFTv0oWKs9N6tdvNKlkzxfK0Z5muQBAf7g/v1oqkxLp27+/P7jAQHkmnlGK148lKXSAoDteB8kH1w4QwfHeSQrJDQzEBxnbiQsJPi6Qj85SAFOAS0BCwEoKx+SUv6I/q3+jP5iKDAtKwGdAXUBVQF2UpIfK/7Z/vT+0f60BmiiPUgpNRQSERocSUQAAAMAc//sBgQHBgAqAD8ATgBcQDMTBxwoKCwiQEUNSkI2BwpPUDI6Py0tNkxCCkAfEAoQRlkCF0ZZAgQlChAaFQQVRlkABBYAPzMrEQAzGD8zEjkrKxEAMxoYEN7c1DIRM80yERIBFzkRMxEzMTAFIicGIyICERASMzIWFwcmIyIGFRAhMjcWFjMgETQmIyIHJzY2MzISERACAxUjIi4CIyIVFSM1NDYzMh4CMwUUBzU2NTQuAjU0MzIWBCuUXlyP4frPuj53KDlZR3RtATF7cD5vQwEtbnNHWTkodz67zvdREFSPeGUra31zcDpxdoNO/vDudx4kHlw4QxRBQQEjAQ4BFwEoIBmLM9bW/l5QKiYBotbWM4sZIP7X/ur+9f7aBqV4JCokZhEfZG8lKyXdoT5IKDgUEREZG0pEAAACAF7/7Ad/BwQADQBAAF9ANDAkOTY+FxcBEjYpDCQHQUIOLSctSVkeNzchJwUJCQ1ACQ9IDQcDC0AUJwQ7MyEzSVkaIRMAPzMrEQAzGD8zGt4yMs0rMhEzERI5LzkrEQAzERIBFzkRMxEzETMxMAEVByMnIwcjJyMHIyc1ASIGByc2MzISERAAISImJyMGBiMgABEQADMyFwcmJiMiAhEQEjMyNjcRMxEWMzISERACBYtQIDK6MSExvC8hUANDPF0tRnyZ5P/+4v79dKxMCU6scP78/uMBAeWWfkYtXTyTpdK+QYIzqmaRvNSlBwQbrGdnZ2esG/4rKR+SUP6I/q3+i/5jMDAxLwGgAXIBVQF2UJIfKf7X/vb+0f60JiYByf43TAFKATEBCwEoAAACAAAAAAYdBaQADQAqAD9AJCQBDhobDBIHKywoFQ4fFgMREgUJCQ1ACQ9IDQcDCyMbEg8RFQA/PzMz3jIyzSsyETMREhc5PxESARc5MTABFQcjJyMHIycjByMnNQEHAyMBMxMWFzM2NhMDMwAWFzM2EhEzEAIHIwMmBLZSHjK8MR8xvDIeUAGsJ6rV/n+s9icpCAwjuqyyAQktCgitmabD27Z9IQWkG6xnZ2dnrBv8JV/+lgRI/UlvqyNRAYgB1fz/kCy4AbMBUv6W/gflAVpcAAABAH3+FATjBcsAFwAtQBgDDwkKFQoPAxgZEwBJWRMEDAZJWQwTChsAPz8rABg/KxESARc5ETMRMzEwASIAERAAITI3ESMRIyAAETQSJDMyFwcmA0j1/uABCgECbzmqFP61/p+vAUjY7apHqwUz/sD+6P7a/tQX/XQB2AGEAW3gAVa4VJJOAAEAc/4UA6IEXAAYAC9AGA8DFxYJFgMDGRoXGwYMRlkGEAASRlkAFgA/KwAYPysAGD8REgEXOREzETMxMAUiABEQADMyFhcHJiMiBhUUFjMyNjcRIxECdf7+/AER+0+kMDGOaLGrq6s1UDmmFAEfARIBFAErIheNM83d3MgRGv1uAdgAAAEAav/8BHUFBgATAC9AIQQCCAMGABEHChANEgwODhUUEwADEQYPBRAHDQoJDAsBEgA/zRc5ERIBFzkxMAEDJxMlNwUTJTcFExcDBQclAwUHAgK2ebb+4UIBIc3+30MBIbl2uAEhRP7hzAEeQQE5/sNDAUKmc6gBZKZ1qAE9Q/7ApnOm/p6ocwABAMsEkQOsBbQAEwAeQAwABgoQBhAUFQMADQkALzMzMhESATk5ETMRMzEwAQYGIyImNTQ2MyE2NjMyFhUUBiMBhwYqMDMpKjYBwQYrLzMtLDYE8C0yMjU1KS4wMTM4KAABAPgE5QPbBdcAEwAcQAsHEhUUABISDASACQAvGswyMxEzERIBOTkxMAEyNzYzMhYVFSM1NCMiDgIjIzUBBHiWlVFvdH1qK2Z5jlQQBWI7Om9kHxFmJCskeQABAd8E1wLNBjUADgAYQAoKAAwFAAMPEAMNAC/MERIBFzkRMzEwATQ2MzIVFA4CFRQXFSYB30M4XB4kHnfuBbg4RUwbGRASFDYoSkAAAQHhBNcCzwY1AA4AGEAKBQAACgIDDxAMAgAvzBESARc5ETMxMAEUBzU2NTQuAjU0MzIWAs/udx4kHlw4QwW4oUBKKDYUEhAZG0xFAAgAKf7BB8EFkQAMABoAKAA2AEQAUgBfAG0AgEBJXyhEWiI+DBoHFFI2bUwwZxBubwAHOkhIQU9FRD5MVmNjXGpmX1ptHiwsJTMvIigDNhAXB09Mam0zNhcXNjNtakxPBwgJDRQDCQAvMy8zEhc5Ly8vLy8vLy8RMxEXMxEzMxEzETMzMxEzMxEzETMzMxEzMxEzETMREgEXOTEwASYmIyIGByM2MzIWFwMmJiMiBgcjNjYzMhYXASYmIyIGByM2NjMyFhchJiYjIgYHIzY2MzIWFwEmJiMiBgcjNjYzMhYXISYmIyIGByM2NjMyFhcBJiYjIgYHIzYzMhYXISYmIyIGByM2NjMyFhcEbwU8RU4yBUsLxV1xB08FPEVOMgVLBWRnXHMGAfQFPEROMgVMBWVnXHMG+y8FPEROMgVMBWVnXHMGBDEFPEROMgVMBWVnXHMG+y8FPEROMgVMBWVnXHMGBPAFPEROMwVLC8Zccwb5vgU8RE4yBUwFZWdccwYEzywsKS/CZV358iwsKS9ZaWZcARYtKycxWmlmXS0rJzFaaWZdA9stKycxWmlmXS0rJzFaaWZd/hksLCgwwmhaLSsnMVpoZlwAAAgAKf5/B30F0wAHAA8AFwAfACcALgA1AD4ANEAlFRclID46BQEpLB8cMjUJDRA/QDsrBy42GRUdES8nDyQzDgUMBQAvLxIXORESARc5MTAFFwYGByM2NwMnNjY3MwYHATcWFhcVJicFByYmJzUWFwE3NjY3FwYHAQcGByc2NwMnJic3FhcBFxYWFwcmJicENwsRRiRhNRE7CxNJH2E0EgIjDkfIQd2B+2gOQr9P3YEDpgJDvkNFsXj86gKbqUWxeCsRUkVDe0wDahEnWhZDH4ImIw5Cv0/dgQSYDkfIQdyC/hYLE0kfYTUROwsRRiRhNREBqhAnWBlEblj8lRBZP0RuWALeAoy3RsZj/OkCRcI8RjLDNAAAAgDJ/oMGCAdeABQAIgBZQC8NCgwHDg4JEwICFBQYIAkKBSQjFBIGBRESBRIOAA4JSVkOEgwiHw8YARgcFQcAAwA/Mt4yzV0yPz8rERIAOTkRMxEzGD8REgEXOREzETMRMxEzMxEzMTATMxEUBwczATMRMwMjEyMRNDcjASMBIiYnMxYWMzI2NzMGBsmhCgQIAzS4uI/FnKATCfzJugJDuqgKmwpdbmljCZ4MtQW2/NF2zlMExvri/esBfQMlr/f7NQYrj6RsTl1dn5QAAgCw/ocFEgYMABEAHwBPQCoKBwkECwsGDwEBEBAVHQYHBSEgAw4QEQ8LBkZZCxAVCSIcDxUBFRkSBA8AP94yzV0yPz8zKwAYPxI5ORESARc5ETMRMxEzETMzETMxMAERFAcBMxEzAyMTIxE0NwEjESUiJiczFhYzMjY3MwYGAUwKAlHPsIGsfZsI/a7NAey5qgqcB1p0Z2QKnQyyBEj9aoiIA6b8R/34AXkCoJ5o/FoESJGPpGZUWmCelQACAC8AAAR9BbYAEQAZAE1AKQgEEhIBDxULCwYPEQQaGwgZSVkHEQARSVkEAAgACAAPAg8SSlkPEgIDAD8/KxESADk5GC8vETMrEQAzKxESARc5ETMRMzMRMzMxMBMzNTMVIRUhETMgERQEISERIwEzIBE0JiMjL5qqAVb+qsACSv7s/vH+b5oBRN0Be7jJ1wT8urqW/uD+ZNLYBGb8KwEZhIAAAAIAFAAABEwGFAASABoAS0AoBAAUFBAMFwgIAgwOBBscBBNGWQMODw5HWQAPBA8EDwwRAAwURlkMFQA/KwAYPxI5OS8vETMrEQAzKxESARc5ETMRMzMRMzMxMAEhFSERITIWFRQGIyERIzUzNTMRESEgNTQmIwFWASf+2QFA39fg3f4hnJymATEBH4SfBR+B/eWam6SqBJ6B9fvg/pe5XFQAAAIAyQAABHkFtgAPABwASEApEAoKCxgAAAQFAxYGFRMUCwodHhYTHBAMHEpZCRBKWQYDDAkJCwwDCxIAPz8SOS8SOTkrKxESADk5ERIBFzkRMxEzETMxMAEUBgcXBycGIyMRIxEhIAQBMzI3JzcXNjU0JiMjBHlzbHhklWaIuKoBiQESARX8+qZXTGxsjH/CysgEDH/JOZ1UwBv9wQW21/3yCo1SsEiykY4AAgCw/hQEdQRcABgAKQBVQDEdCwQHBwgnEhIVFhQlFyIkIwgKKislIhkgDxlGWQwLCwQUFwQADxAJDwgbACBGWQAWAD8rABg/Pz8SFzkRMysREgA5ORESARc5ETMRMxEzMzMxMAUiJicjFhURIxEzFzM2NjMyEhEQBxcHJwYDIgYHFRQWMzI3JzcXNjU0JgKua7E8DAymhxkIQKlt2u23c2SDR22olgKaqi8peWqBZZYUT1KUIv49BjSWWlD+1v7z/q6RnFCuGAPjussl58cMnlCqZ/nX0QAAAQAvAAAECAW2AA0APEAfAwcHDAgABQgKBA4PBgoLCklZAwsLCA0NAklZDQMIEgA/PysREgA5GC8zKxEAMxESARc5ETMzETMxMAEVIREhFSERIxEjNTMRBAj9awGo/liqmpoFtpn+Apb9dwKJlgKXAAEAEgAAA0IESAANADxAHwIGBgsHAAQHCQQODwUJCglHWQIKCgcMDAFGWQwPBxUAPz8rERIAORgvMysRADMREgEXOREzMxEzMTABIREhFSERIxEjNTMRIQNC/hQBWv6mpp6eApIDvP6of/4bAeV/AeQAAAEAyf4ABNsFtgAbAEFAIwkDAwQZDg4HFAQEHB0RF0lZERwLAElZCwsEBQUISVkFAwQSAD8/KxESADkYLysAGD8rERIBFzkRMxEzETMxMAEiBxEjESEVIRE2MyAAERAAISImJzUWMyARNAACMWRaqgNJ/WFaeQFAAVX+4v79U31Ge4kBf/8AAo8M/X0Ftpn9/Ar+rf7G/sX+pRUcmDEB/vUBBAAAAQCw/goD+gRIABsAQUAjCBkUDg4PDwISGQQdHBYLRlkWFg8QEBNGWRAPDxUABUZZABsAPysAGD8/KxESADkYLysREgEXOREzETMRMzEwASInNRYzMjY1NCYjIgcRIxEhFSERNjMgABEQAgJGkWV0e4WIsrVFSqYCmv4MUjsBEAEH5P4KPJU/ytff0BH+JQRIjv63DP7l/tn+9f7aAAABAAL+gwb4BbYAFQBNQCkGEREDEg0MDAgJEgABFQcWFxIVEhMQCQYDAAAPAQ8KSVkPEg0iBwQBAwA/MzM/PysREgA5ETMzMzMzGD8zERIBFzkRMxEzMxEzMTABATMBETMRATMBATMRIxEjAREjEQEjAlb9wb4COaQCOr79wAHatKJe/bqk/bvHAvACxv08AsT9PALE/Tz9qP3pAX0C5f0bAuX9GwAAAQAE/ocGHwRIABUAS0AoAg0NFQ4JCAgEBQ4SExEHFhcVDwwFAhISCwMAEw8OERULBkZZCxUJIgA/PysAGD8zPzMzEjkRMzMzMzMREgEXOREzETMzETMxMAEzEQEzAQEzESMRIwERIxEBIwEBMwECpJkBxbb+NgFwwaJe/h6Z/h+/AfD+N7YBwwRI/e0CE/3t/lr9+AF5Ai390wIt/dMCNQIT/e0A//8ASv5CBDUFywImAbEAAAAHA38BWAAA//8ARP5CA38EXAImAdEAAAAHA38BCAAAAAEAyf6DBSsFtgAPADtAIAwICAkDAgIODwYJBRARDwwGAwUNCgMJEgUASVkFEgMiAD8/KwAYPz8zEhc5ERIBFzkRMxEzETMxMCUzESMRIwEHESMRMxEBMwEEf6yiZv3pmaqqApfJ/bSa/ekBfQLFiP3DBbb9KwLV/YUAAQCw/oUEPQRIAA4AOkAfDgoKCwYFBQECCwQPEAIOCQMIAAwPCxUIA0ZZCBUGIgA/PysAGD8/MxIXORESARc5ETMRMxEzMTABMwEBMxEjESMBESMRMxEDL7b+JwF/sp9U/gympgRI/e/+WP32AXsCK/3VBEj96wAAAQDJAAAE6QW2ABIAOEAeBgICAwoREQcSDgwSAwQTFAgKBgAQEgYDCwQDDwMSAD8zPzMSFzkREgEXOREzMxEzETMRMzEwAQcRIxEzETcRMxUBMwEBIwERIwHwfaqqfX0Bm8v9tAJiyP5MfQKoa/3DBbb9JYsBXdMBxv2F/MUCXP7PAAEAsAAABDsESAATADpAHwYCAgMOChISBxMPDBMDBBQVCAoGARETBgMLBA8QAxUAPzM/MxIXORESARc5ETMzETMzETMRMzEwAScRIxEzETcRMxUBMwEVASMBFSMBzXempneDAQ62/jwB68L+1YEBsnn91QRI/et5AUrNAR/+JWv9/gE73QAAAQAvAAAE6QW2ABMAR0AmCAQQEAERCw4MCgYOERMGFBUHEwATSVkECwgOAxEAAAINERIJAgMAPzM/MxI5LxIXOTMrEQAzERIBFzkRMxEzMxEzMzEwEzM1MxUzFSMRATMBASMBBxEjESMvmqrd3QKVy/20AmLO/fGZqpoFBLKyl/5uAtv9hfzFAsWG/cEEbQAAAQAUAAAEGwYUABkATUArCggEFhYBFxIQBhEXGQYaGxQKDxMXFQcZABlHWQQPAB8ALwADAAACDw8CAAA/PxI5L10zKxEAMxg/MxI5ORESARc5ETMzETMzMzEwEzM1MxUhFSERBwczNzY2ATMBASMBBxEjESMUnKQBff6DAwMIEjcoAXDH/kQB2cf+fX2knAVaurp//ehbNxhKMAGF/i39iwIEav5mBNsAAQAQAAAFgwW2AA0ANUAbAgoKCwUIBgQICwQODwgCAAcLEgMDAA1JWQADAD8rABg/PzMSOTkREgEXOREzETMRMzEwEyERATMBASMBBxEjESEQAfwClsv9tAJiyf3smqr+rgW2/SUC2/2F/MUCxYj9wwUdAAABACkAAATjBEgADAA1QBsFAQEJCQoMCgQGBA4NCAIABwoVAw8ADEZZAA8APysAGD8/MxI5ORESARc5ETMRMxEzMTATIREBMwEBIwERIxEhKQICAdu2/icCAML+CqT+ogRI/esCFf3t/csCK/3VA7wAAQDJ/oMFwQW2AA8AREAkDAgICQ0FBQADAgIACQMQEQwHSVkMDAUOCgMJEgUASVkFEgMiAD8/KwAYPz8zEjkvKxESARc5ETMRMxEzETMRMzEwJTMRIxEjESERIxEzESERMwUfoqKq/P6qqgMCqpr96QF9ArD9UAW2/ZICbgAAAQCw/ocE+ARIAA8ATkArAQ0NDgIKCgUIBwcFDgMQEQEMRlkPAR8BAgsDAQEKAw8PDhUKBUZZChUIIgA/PysAGD8/MxI5L19eXSsREgEXOREzETMRMxEzETMxMAERIREzETMRIxEjESERIxEBVgJmppamlv2apgRI/jUBy/xH/fgBeQHu/hIESAAAAQDJAAAGbwW2AA0AP0AhCgYGBwsDAwIAAgcDDg8KBUlZCgoHDAwBSVkMAwgDAwcSAD8zPz8rERIAORgvKxESARc5ETMRMxEzETMxMAEhESMRIREjETMRIREhBm/+sKz9AKqqAwAB/AUd+uMCsP1QBbb9kgJuAAEAsAAABcEESAANAElAJwELCwwCCAgHBAcMAw4PDQ8BCkZZDwEfAQILAwEBAwgMFQMGRlkDDwA/KwAYPzMSOS9fXl0rABg/ERIBFzkRMxEzETMRMzEwAREhESEVIREjESERIxEBVgJmAgX+oab9mqYESP41AcuM/EQB7v4SBEgAAQDJ/gAIHQW2AB0AR0AmBAUIAAABFw0NEgEFBB4fEBVJWRAcChpJWQoKBQYGA0lZBgMBBRIAPzM/KxESADkYLysAGD8rERIBFzkRMxEzETMRMzEwISMRIREjESERNjMgABEQACEiJzUWMyARNAIjIgYHBNmq/USqBBBEfQEyAVH+5f7+nHuGfwF65ugqfxgFHfrjBbb9YQz+qP7I/sf+pjGYMQH+8gEFBwUAAAEAsP4KBqgESAAcAEdAJhESFQ0NDgcaGgIOEgQdHhcKRlkXFxITExBGWRMPDhIVAAVGWQAbAD8rABg/Mz8rERIAORgvKxESARc5ETMRMxEzETMxMAEiJzUWMzIRNCYjIgcRIxEhESMRIRE2MzIAERACBReDYW1s8KasQ0io/d+mA29LQvYBBtH+CjyVPwGh39AV/ikDuPxIBEj+Jw7+1/7n/vT+2wACAH3/rAXhBc0AKAA0AFBALBsRLyMpAAgAAxYgIxEHNTYmLEpZDDImJg4UFBlJWRQECgVJWQoODh5JWQ4TAD8rABgQxCsAGD8rERIAORgvOTkrERIBFzkRMxEzETMxMAEUAgcWMzI3FQYjIicGIyAAERAAITIXByYjIBEQEjMyNyYCNTQSMzISAzQmIyIGFRQWFzY2BbiKdEJaTj04W7KUZpD+yv6hAUkBOn9cL1Ra/jP/6zYuVlzGr7XBsGddXmddU2ZzAqa1/stWHhaZGWQkAYkBVgF4AYojkRz9nv7g/s4KZwEcoPQBCv72/v6xzMmwjP5VQ/8AAAIAc//HBNMEXAAKADUAUEAsHhMAJgYsNCwvGCQmEwc2NykIR1kNAykpDxYWG0ZZFhALMUZZCw8PIUZZDxYAPysAGBDEKwAYPysREgA5GC85OSsREgEXOREzETMRMzEwARQWFzY2NTQjIgYBIicGIyImJjUQEjMyFwcmIyIGFRQWMzI2NyY1NDYzMhYVFAYHFjMyNxUGAu5EP0RTh0hLAWaTgmB7leJ6+ONbTSU2T5yRqqQlNQaLqJeUnWteNENCMScB8l6hNSyebut9/WNNKIv+pAETATAWihPR587SCQOU4a3BvbF90UAaDokOAP//AH3+QgTPBcsCJgAmAAAABwN/AiUAAP//AHP+QgOLBFwCJgBGAAAABwN/AYMAAAABABD+gwRaBbYACwAyQBsGCwgJAwkLAQQMDQsGSVkLEgkiBQECAUlZAgMAPysRADMYPz8rERIBFzkRMxEzMTABITUhFSERMxEjESMB3/4xBEr+MaKirAUdmZn7ff3pAX0AAAEAKf6HA5EESAALADRAGwYLCAkDCQsBBAwNCSIFAQIBRlkCDwsGRlkLFQA/KwAYPysRADMYPxESARc5ETMRMzEwASE1IRUhETMRIxEjAYn+oANo/p6WppYDvIyM/NP9+AF5AP//AAAAAAR7BbYCBgA8AAAAAQAA/hQEAgRIAA0AKUAUAAEMAQMDDg8IBw0HAgsDDwIVARsAPz8/MxI5OREzERIBFzkRMzEwASMRATMTFhczNjcTMwECVKb+UqzsUxMIIUbprP5S/hQB6ARM/ZveYYq1AmX7tAAAAQAAAAAEewW2ABAAOkAeBAgIDQkCBgkLDwUREgcLDAtJWQQADwwMCQEPAwkSAD8/MxI5LxI5MysRADMREgEXOREzMxEzMTABATMBFSEVIREjESE1ITUBMwI9AYa4/hgBK/7VrP7TAS3+GboC2wLb/IE7mP6cAWSYMwOHAAEAAP4UBAIESAATADxAHxEBAQYCEBMCBAcFFBUMCwsFDwcPAAQFBEdZEQUVAhsAPz8zKxEAMxg/MxI5ETMREgEXOREzMxEzMTAFESMRITUhATMTFhczNjcTMwEhFQJUpv7qART+VKzsUxMIIUbprP5UARKB/pUBa4EESP2b3mGKtQJl+7iBAAABAAj+gwTVBbYADwA3QCADAgIODwwGCQoICBARDA8JBgQFDQoDCBIFAElZBRIDIgA/PysAGD8/MxIXORESARc5ETMxMCUzESMRIwEBIwEBMwEBMwEEM6KiXv53/nC0Aeb+O7wBawFutf47mv3pAX0Cg/19AvwCuv29AkP9TAABACf+hQQ3BEgADwA5QCEKCQkFBgMNAAEPCBARDxUDBgANBAwBDAdGWQwVCiIEAQ8APzM/PysREgAXORg/ERIBFzkRMzEwAQEzAQEzAQEzESMRIwEBIwG4/oO9ASEBILv+gwErlaZF/s3+yrwCMQIX/lwBpP3p/l799gF7Abz+RAAAAQAQ/oMGqAW2AA8AQEAiDAUADQMCAg0KBQcFEBEOAwsHCAdJWQgDAAwFDElZBRIDIgA/PysRADMYPysRADMYPxESARc5ETMRMxEzMTAlMxEjESERITUhFSERIREzBf6qovu0/lYEL/4lAvCqmv3pAX0FHZmZ+30FHAABACn+hwWYBEYADwA/QCICCwYDCQgIAwALDQUQEQENDg1GWQ4PBgILAkZZCxUJIgQPAD8/PysRADMYPysRADMREgEXOREzETMRMzEwASERIREzETMRIxEhESE1IQN5/pcCRqacpvx4/r8DUAO6/NUDt/xJ/fgBeQO6jAAAAQCq/oMFaAW2ABcAO0AfFQAFAwIPDAIFDAMYGRIJSVkSEgUWDQMFAElZBRIDIgA/PysAGD8zEjkvKxESARc5ETMRMxEzMzEwJTMRIxEjEQYGIyImNREzERQWMzI2NxEzBMehoaqVxmrP36p/j2Gxqaqa/ekBfQJcNSe+swJF/c95dB03AsoAAAEAnP6FBMMESAAWADtAHwEVCQYODAsLDhUDFxgDEkZZAwMOBxYPDglGWQ4VDCIAPz8rABg/MxI5LysREgEXOREzETMzETMxMAERFDMyNjcRMxEzESMRIxEGBiMiJjURAULbW6ZpppamlmmzcaS6BEj+cMA4QwHV/Ef99gF7AfBIO6yTAZwAAQCqAAAExwW2ABYASkAmBQILFRUIFg0RERAQFgIDFxgUAAgASVkLCBYICQkIFgMDERIOAwMAPzM/Ehc5Ly8vETMrEQAzERIBFzkRMxEzETMzETMRMzEwASARETMRFBYzETMRNjcRMxEjEQYHESMCdf41qoeafYajrKyogX0CAAFxAkX9z3d2AVz+qg08As/6SgJYQRH+zwABAJwAAAQdBEgAFwBKQCYBFgYQEAMRCAwMCwsRFgMYGQ8TAxNGWQYDEQMEBAMRAwwJFw8MFQA/PzMSFzkvLy8RMysRADMREgEXOREzETMRMzMRMxEzMTABERQXETMRNjcRMxEjEQYHFSM1IyImNREBQsh3cYWmpoB2dxaguARI/nC6BgEt/t0YWQHV+7gB8Fsa+OqqlQGcAAEAyQAABOUFtgASAC9AFwIRERIJCAgSFBMEDUlZAhIEBAkSEgADAD8/MzkvEjkrERIBOTkRMxEzETMxMBMzESQzMhYVESMRNCYjIgYHESPJqgEAxM/fqn+Pa7qVqgW2/aRcv7H9ugIxeHYiMv01AAABALAAAARCBEgAEgAvQBcAEgsHBwgSCBQTDgNGWQsODggJDwAIFQA/Mz8SOS85KxESATk5ETMRMxEzMTAhETQjIgYHESMRMxE2NjMyFhURA5rZWJx3pqZfunKjvgGNwTFK/i0ESP4ORT6ol/5mAAIAPf/sBj8FzQAgACcAUUAqBQMAJBERCB4lEBAYHgAEKCkRHgceSVkkBwIHAhsMGxRJWRsTDCFJWQwEAD8rABg/KxESADk5GC8vMysRADMREgEXOREzETMzETMRMzMxMBM0NzMGFRQzMzcSACEgABEVIRIAMzI2NxUGBiMgAAMiJgEiAgchECY9G5EUcSIFHQFNARcBKQEo+9wOAQX3ZcqNct2C/sb+oxOOmwOv0fAQA27LA4dJNjI8ZysBKgFH/oX+j0X++P7vHyucJx4BZAFMdgIj/vX5AQn7AAACADP/7ATdBFoAHwAmAExAKAoIBRYNJBUVHQ0DBQUnKBYDDANGWSMMBwwHABERIEZZERAAGUZZABYAPysAGD8rERIAOTkYLy8zKxEAMxESARc5ETMRMxEzMzEwBSIAJyQ1NDczBhUUMzM3NjYzMhIVFSEWFjMyNjcVBgYDIgYHITQmA0rz/uwG/vYZjRRqFQYi+rfP8f0MBqytZZ9iWJ2ghpcOAj2MFAEe/ATdRTIvO2cjyuD+9+JpxsMgKpQmIQPjpJ6dpQACAD3+gwY/Bc0AIgApAF1AMQsJBiYXFw4DISInFhYeIgMGBSorIiIgExcDDQNJWSYNCA0IABISI0lZEgQAGkpZABMAPysAGD8rERIAOTkYLy8zKxEAMxg/PxESARc5ETMRMxEzMxEzETMzMTAFJAADIiY1NDczBhUUMzM3EgAhIAARFSESADMyNjcVBgcRIxMiAgchECYDoP7+/tsTjpsbkRRxIgUdAU0BFwEpASj73A4BBfdlyo2w66ZM0fAQA27LDB0BWgExdnVJNjI8ZysBKgFH/oX+j0X++P7vHyucPgX+lQay/vX5AQn7AAIAM/6HBN0EWgAhACgAWEAvCggFFg0gISYVFR0hDQMFBikqISIfFhYDDANGWSUMBwwHABERIkZZERAAGUZZABUAPysAGD8rERIAOTkYLy8zKxEAMxg/PxESARc5ETMRMxEzETMzMTAFJgInJDU0NzMGFRQzMzc2NjMyEhUVIRYWMzI2NxUGBxEjEyIGByE0JgLVv9MG/vYZjRRqFQYi+rfP8f0MBqytZZ9ijqWmRIaXDgI9jAofARHgBN1FMi87ZyPK4P734mnGwyAqlEEE/pkFSKSenaUA//8AVAAAAlYFtgIGACwAAP//AAIAAAa8B2ACJgGwAAABBwI2ARABVAAIswESBSYAKzX//wAEAAAF3wYMAiYB0AAAAQcCNgCkAAAACLMBEhEmACs1AAEAyf4ABRkFtgAcAEJAJQcDAwQaDg4JChQEBR0eERdJWREcBwJJWQsASlkHCwsECAUDBBIAPz8zEjkvOSsrABg/KxESARc5ETMRMxEzMTABIgcRIxEzEQEzATcgABEQACEiJic1FjMyEjU0JAJejF+qqgKJzf2FGgFPAWL+2f71UnxGepi7yP7rAnsf/aQFtv08AsT9VAL+u/7P/sb+pBQdmDEBDfHo/QAAAQCw/goEIQRIABwAQkAlBAAAARcKEAoGBwEFHR4OFEZZDhsEHEdZBxpGWQQHBwEFAg8BFQA/PzMSOS85KysAGD8rERIBFzkRMxEzETMxMCEjETMRATMBBBIRFAYGIyInNRYWMzI2NTQmIyIHAVSkpAHjt/43AQD8bsyFiF8ubEeHmLu+UlwESP36Agb+HgT+5P71sfyEPJEZJtnI088YAAEAAP6DBZEFtgAXADlAHwMABQQBAQUOAxgZFgdJWRYDDBFKWQwSBQBJWQUSAyIAPz8rABg/KwAYPysREgEXOREzETMzMTAlMwMjEyMRIQcCAgYnIic1FjMyNjYSEyEE2biPxZyq/iUfPV2Yfko7Njs1Tz1dOAMSmv3pAX0FH/D+If5FrgIZjxpX1wJZAbgAAAEAEP6HBI8ERgAUADlAHwMABQQBAQUNAxUWEwdGWRMPCxBHWQsVBQBGWQUVAyIAPz8rABg/KwAYPysREgEXOREzETMzMTAlMwMjEyMRIQICBiMiJzUWMzISEyED37CBrH2m/rUcXph2OhwWHHGJIgKBj/34AXkDuP6Y/mTACn8GAdkB9gAAAQDJ/gAFHwW2ABUAPUAgEg4ODxMLCwAABg8DFhcSDUlZEhIPFBADDxIDCUlZAxwAPysAGD8/MxI5LysREgEXOREzETMRMxEzMTAlEAAhIiYnNRYzIBERIREjETMRIREzBR/+5v77UnpNe4cBjPz+qqoDAqqW/sL+qBMeljEB9wIj/VAFtv2SAm4AAQCw/goEYgRIABUAR0AnDwsLDBAICBMTAgwDFhcPCkZZDw8fDwILAw8PDBENDwwVAAVGWQAbAD8rABg/PzMSOS9fXl0rERIBFzkRMxEzETMRMzEwASInNRYzMjY1ESERIxEzESERMxEQAgLThF1vZn12/ZympgJkqM/+CjqVPcbPAb3+EgRI/jUBy/vr/vT+4wABAMn+gwXXBbYADwBEQCQMCAgJDQMABQQBAQUJAxARDAdJWQwMBQ4KAwkSBQBJWQUSAyIAPz8rABg/PzMSOS8rERIBFzkRMxEzMzMRMxEzMTAlMwMjEyMRIREjETMRIREzBR+4kcWeqvz+qqoDAqqa/ekBfQKw/VAFtv2SAm4AAAEAsP6HBRIERgAPAERAJAENDQ4IBQIKCQYGCg4DEBEBDEZZAQEKAw8PDhUKBUZZChUIIgA/PysAGD8/MxI5LysREgEXOREzETMzMxEzETMxMAERIREzETMDIxMjESERIxEBVgJmprCBrH2m/ZqmBEb+NwHJ/En9+AF5Ae7+EgRGAAABAKr+gwTHBbYAFwA9QCAPDAIDFQUFAAADDAMYGRIJSVkSEgEWDQMDIgEESVkBEgA/KwAYPz8zEjkvKxESARc5ETMRMxEzETMxMCEjESMRMxEGBiMiJjURMxEUFjMyNjcRMwTHqqKilcZqz9+qf49hsamq/oMCFwHCNSe+swJF/c95dB03AsoAAQCc/oUELQRIABYAPUAgARULDAYODgkJDBUDFxgDEkZZAwMKBxYPDCIKDUZZChUAPysAGD8/MxI5LysREgEXOREzETMRMxEzMTABERQzMjY3ETMRIxEjETMRBgYjIiY1EQFC21umaaaVppVps3GkugRI/nDAOEMB1fu4/oUCCgFhSDuskwGcAAEAyf6DBykFtgAYAEhAJQkGBgcRDgwTEg8PEwcDGRoXFgILAhMIEw5JWRMSESIMCAMABxIAPzM/Mz8/KxESADk5ETMzERIBFzkRMxEzMzMRMxEzMTAhASMXFhURIxEhATMBMxEzAyMTIxE0NyMBA1D+EAgHB50BAAHRCAHR/riPx56qDgj+DAUQf8Av/F4FtvtKBLb65P3pAX0DroTc+vIAAAEAsP6HBd8ERgAYAD9AIBMUCAUKCQYGChQDGRoLEgASDwMVDxQVCgVGWQoPFQgiAD8/MysAGD8/MxI5OREzERIBFzkRMxEzMxEzMTAlNzcBMxEzAyMTIxEHBwEjASYnESMRMwEWAukfKwEp07CBrH2TFDr+5Yv+5TUUlMsBKS2gXXYC0/xJ/fgBeQOJOpn9SgK4hkv8dwRG/S1u//8AVAAAAlYFtgIGACwAAP//AAAAAAUQB14CJgAkAAABBwI2ADkBUgAIswIPBSYAKzX//wBe/+wDzQYMAiYARAAAAQYCNugAAAizAiURJgArNf//AAAAAAUQByUCJgAkAAABBwBqAD0BUgAKtAMCJAUmACs1Nf//AF7/7APNBdMCJgBEAAABBgBq8wAACrQDAjoRJgArNTX////+AAAGgQW2AgYAiAAA//8AXv/sBnMEXAIGAKgAAP//AMkAAAP4B14CJgAoAAABBwI2ABABUgAIswEMBSYAKzX//wBz/+wEEgYMAiYASAAAAQYCNgwAAAizAhsRJgArNQACAHX/7AVYBc0AEgAZAD1AIBcOEBYWCQkCDgMaGw8XSVkPDwwGDBNJWQwTBgBJWQYEAD8rABg/KxESADkYLysREgEXOREzETMRMzEwASIHNTY2MyAAERAAISARNSECAAMyEjchEBYCmOPic9KGAUsBb/6m/sv9rAQvEf75w9L5EPyHzAU1TJ4mIP5x/pv+ov5xAutGAQoBDvtOAQ33/vj8AAACAGb/7AQGBFwAFAAbADtAHxkJGAsDAxEJAxwdChlGWQoKBgAGFUZZBhYADkZZABAAPysAGD8rERIAORgvKxESARc5ETMzETMxMAEyABEQACMiAjU1ISYmIyIGBzU2NhMyNjchFBYB+vUBF/792tDzAvQFs6ZipV9ZopqFmgz9w40EXP7U/vv++P7JAQzhacy7ISmTKCL8G6WcnaQA//8Adf/sBVgHJQImAuEAAAEHAGoAkwFSAAq0AwIvBSYAKzU1//8AZv/sBAYF0wImAuIAAAEGAGrqAAAKtAMCMREmACs1Nf//AAIAAAa8ByUCJgGwAAABBwBqARABUgAKtAIBJwUmACs1Nf//AAQAAAXfBdMCJgHQAAABBwBqAKIAAAAKtAIBJxEmACs1Nf//AEr/7AQ1ByUCJgGxAAABBwBq//MBUgAKtAIBPgUmACs1Nf//AET/7AN/BdMCJgHRAAABBgBqlAAACrQCATgRJgArNTUAAQBK/+wENwW2ABkAQEAjABMVGQ8DAxkTFggFGhsZFhcWSVkAEkpZAAAGFwMGDEpZBhMAPysAGD8SOS8rKxEAMxESARc5ETMRMxEzMTABBAQVFAQhICc1FhYzMjY1NCYjIzUBITUhFQH8ARcBJP7N/ur+/6Ng3mrHyuHfjAHu/U4DhwM/CdPBzuhPni4ymZCGio0B3pmLAAABABv+FAOmBEgAGQBAQCMAExUZDwQEGRMWCQUaGxkWFxZGWQASR1kAAAcXDwcMRlkHGwA/KwAYPxI5LysrEQAzERIBFzkRMxEzETMxMAEeAhUUACMiJzUWMzI2NTQmIyM1ASE1IRUBrJXmf/7Y7+qKt8ihxdbKeQHF/YkDOAHPB3LKiN7+7kaaVr6gpKpyAf6OewD//wDLAAAFUga0AiYBsgAAAQcBTQC0AVIACLMBEwUmACs1//8AsAAABGIFYgImAdIAAAEGAU0xAAAIswERESYAKzX//wDLAAAFUgclAiYBsgAAAQcAagC+AVIACrQCASUFJgArNTX//wCwAAAEYgXTAiYB0gAAAQYAaj0AAAq0AgEjESYAKzU1//8Aff/sBb4HJQImADIAAAEHAGoA0QFSAAq0AwItBSYAKzU1//8Ac//sBGIF0wImAFIAAAEGAGodAAAKtAMCLhEmACs1Nf//AH3/7AW+Bc0CBgJ+AAD//wBz/+wEYgRcAgYCfwAA//8Aff/sBb4HJQImAn4AAAEHAGoA0QFSAAq0BAMvBSYAKzU1//8Ac//sBGIF0wImAn8AAAEGAGobAAAKtAQDMBEmACs1Nf//AD3/7ASJByUCJgHHAAABBwBq/+0BUgAKtAIBMAUmACs1Nf//ADn/7AN9BdMCJgHnAAABBgBqjgAACrQCATARJgArNTX//wAb/+wE+Aa0AiYBvQAAAQcBTQAvAVIACLMBGgUmACs1//8AAv4UBAYFYgImAFwAAAEGAU2tAAAIswEZESYAKzX//wAb/+wE+AclAiYBvQAAAQcAagA7AVIACrQCASwFJgArNTX//wAC/hQEBgXTAiYAXAAAAQYAarcAAAq0AgErESYAKzU1//8AG//sBPgHcwImAb0AAAEHAVMAjQFSAAq0AgEqBSYAKzU1//8AAv4UBAYGIQImAFwAAAEGAVMEAAAKtAIBKREmACs1Nf//AKoAAATHByUCJgHBAAABBwBqAGoBUgAKtAIBKQUmACs1Nf//AJwAAAQtBdMCJgHhAAABBgBqFwAACrQCASgRJgArNTUAAQDJ/oMECAW2AAkALUAYBAkGBwEHCQMKCwkESVkJEgciAANJWQADAD8rABg/PysREgEXOREzETMxMBMhFSERMxEjESPJAz/9a6GhqgW2mft9/ekBfQABALD+hwNCBEYACQAtQBgECQYHAQcJAwoLCQRGWQkVByIAA0ZZAA8APysAGD8/KxESARc5ETMRMzEwEyEVIREzESMRI7ACkv4UlqaWBEaM/NX9+AF5//8AyQAABgoHJQImAcUAAAEHAGoBGwFSAAq0BAMtBSYAKzU1//8AsAAABXkF0wImAeUAAAEHAGoAxQAAAAq0BAMsESYAKzU1//8AL/51BAgFtgImApsAAAAHA4AAkwAA//8AEv51A0IESAImApwAAAAGA4F1AP//AAj+dQTJBbYAJgA7AAAABwOAA1gAAP//ACf+dQQ0BEgAJgBbAAAABwOBAsMAAAABAAYAAASWBbYAEQA7QCIPAhEBEA0ECgcJBgsMExIKEQARSVkHDQ8EAAACDA8SBQIDAD8zPzMSOS85EjkzKxEAMxESARc5MTATIQEzAQEzASEVIQEjAQEjASF/ATP+d7wBawFst/5wATz+ugG9wf53/nC2Ab/+ugNUAmL9uwJF/Z6Y/UQCg/19ArwAAAEAJwAABAgESAARADtAIg8CEQEQDQQKBwkGCwwTEgoRABFHWQcNDwQAAAIMDxUFAg8APzM/MxI5LzkSOTMrEQAzERIBFzkxMBMhATMBATMBIRUhASMBASMBIXUBEv60vQEhASC7/rIBGP7iAWi8/s3+yrwBZv7oAncB0f5cAaT+L4H+CgG8/kQB9gAAAgCDAAAENwW2AAoAEwA0QBoEExMHDwAHABUUAwxJWQMDCAUIEkpZCBIFAwA/PysREgA5GC8rERIBOTkRMxEzETMxMBM0JCEzETMRISAkASMiBhUUFjMzgwEkASDGqv5j/vX+9AMKut7CtsvZAaTUzgJw+krVAdt8jo+E//8Ac//sBDcGFAIGAEcAAAACAIP/7AZ3BbYAGQAjAEZAJB4DGAoKByMPEhIjAwMkJQYbSVkYBhAGEAAIAwwgACBKWRUAEwA/MisRADMYPxI5OS8vOSsREgEXOREzETMzEjkRMzEwBSImNTQkITMRMxEUMzI2NREzERQGIyImJwYTIyIGFRAhMjY1Ak7i6QEqASKRquZkearPuHafM3Epl9TCASF/jRLR0NneAnD7t+x7bgHm/hiuzlJaqgLAi5b+9HdwAAACAHP/7AaHBhQAIgAuAFFAKSwTDCAgHRomAwYGJhMDLzAeAA0QGhYEBBAWFipGWRYQACMQI0ZZCRAWAD8zKxEAMxg/KxESADkYLxI5Ejk/ERIBFzkRMxEzMzMSOREzMTAlMjY1ETMRFAYjIiYnIwYGIyICERASMzIWFzMmJjURMxEUFiEyNjU1NCYjIBEUFgT+dmuoyL2BnisIS7mB0Ojnz2qfPwwCCKZt/bmikpSi/uKLd4SIATn+vcjFW3FxWwEpAQwBDAEvTVURcBsBvvuMoIm5ziPnyf5O1tIAAQBO/+wGgQXLACoAS0AoBhMoGR8iIhYZEwENBissFwIBAgFKWQIgAiAlECUcSVklExAJSlkQBAA/KwAYPysREgA5ORgvLysREgA5ERIBFzkRMxEzETMxMAEjNTMyNjU0JiMiBgcnNjYzMhYVFAYHFQQTFhYzMjY1ETMRFAYjIiYnJiYBrsnBwNWagGexZ1Rd9oLW9bKcAWIGAmx8d3Co0r3K0AICzQKsj5OEbH83RXJIUMSnjbcaCDP+0ZZ/eYcBzf4pxsfRyJaRAAEAUP/sBcUEXAAlAEtAKBIeCiQCBQUkHiAOGAYmJyEPDg8ORlkPAw8DCBsbFEZZGxAIAEZZCBYAPysAGD8rERIAOTkYLy8rERIAORESARc5ETMRMxEzMTAlMhERMxEUBiMgAyYmIyM1MyA1NCMiBgcnNjYzMhYVFAcVFhYXFgRC3aa7xP6GEAWNlIxvASHyS4dNOVWjaLjTwGN7BQl3AQwBOf69ysMBTWNYjayiJCKHKCSbhrg5CBR6atMAAQBO/oME0QXLACMASkAoGRoeIyEgIBYaIwQQBiQlGgUEBQRKWQUFIxMjHklZIxIhIhMMSlkTBAA/KwAYPz8rERIAORgvKxESADkREgEXOREzETMRMzEwATQmIyM1MzI2NTQmIyIGByc2NjMyFhUUBgcVFhYVETMRIxEjA4Pl4tnRzeGkh2nDaVRh/oTc/b2juMOsoqwBnIWLj5OEa4A6QnJKTsSnjLcZCBmzlP7+/ekBfQAAAQBQ/ocEEARaAB4ASkAoBxIZHhwbGxUeEgMNBiAfFQQDBANGWQQEHg8eGUZZHhUcIg8KRlkPEAA/KwAYPz8rERIAORgvKxESADkREgEXOREzETMRMzEwATQhIzUzIDU0JiMiByc2MzIWFRQHFRYWFRUzESMRIwLV/suWdQE5hXeZlj2hy7/Vy35wnaaVAS3HjaxSUEaHSpqHtjkLJYlmnP34AXkAAAEAAP/pByEFtgAjADpAHRQjGh0dIwkDJCUbGwcSEgFJWRIDFwwHDEpZIAcTAD8zKxEAMxg/KxESADkYLxESARc5ETMRMzEwASEHAgIGBiMiJzUWMzI2NhISEyERFBYzMjY1ETMRFAYjIiY1BAz+SB8rTFOCZEVAMj8xQCw4SjcC729zcHGozbzEyAUf8P6u/kTSZhmPGj5oAQIB6QGu+8+JeXmHAc3+KcHMzMUAAAEAEP/sBikERgAdADpAHQAOBQgIDhYDHx4GBhQcHBBGWRwPAxkUGUdZCxQWAD8zKxEAMxg/KxESADkYLxESARc5ETMRMzEwARQWMzIRETMRFAYjIiY1ESECAgYjIic1FjMyEhMhA89od9Wmu768y/7FHF6YdjocFhxxiSICcQGDiYMBCgE7/r3Kw8TLAj3+mP5kwAp/BgHZAfYAAAEAyf/sB14FtgAZAENAIxcADwYJFhISEwkPEwMaGxYRSVkWBxYHExgUAxMSDANJWQwTAD8rABg/PzMSOTkvLysREgEXOREzETMRMxEzMzEwARQWMzI2NREzERQGIyImNREhESMRMxEhETME9m5zcHGmyL/DyP0nqqoC2aoBhYl5eYcBzf4pv87LxgEz/VAFtv2SAm4AAAEAsP/sBqgESAAYAE1AKgUCEwoNARYWFw0TFwMZGgEVRlkPAR8BAgsDAQsBCxcDGA8XFRAIRlkQFgA/KwAYPz8zEjk5Ly9fXl0rERIBFzkRMxEzETMRMzMxMAERIREzERQWMzIRETMRFAYjIiY1NSERIxEBVgJQpmp31aa7wLrN/bCmBEj+NQHL/T2JhQEMATn+vcrDxslz/hIESAAAAQB9/+wFmgXLABwAOkAfFggbAgIPHAgEHR4AHElZAAAFDAwTSVkMBAUZSVkFEwA/KwAYPysREgA5GC8rERIBFzkRMxEzMTABIRUQACEgABE0EiQzMhYXByYmIyAAERAAMyARIQNmAjT+zP7J/rv+k7MBVep47VNCWtZX/vX+3gEL9wG0/n8C8Fb+of6xAZEBYOUBVLUxJ5QmLv7F/uP+4/7DAdcAAAEAc//sBLAEXAAZADpAHxIHGAICDBkHBBobABlGWQAABAoKD0ZZChAEFUZZBBYAPysAGD8rERIAORgvKxESARc5ETMRMzEwASEVECEgABEQACEyFwcmIyIGFRQWMzI2NSECsgH+/f7+7v7XAUMBIdSvO6imzeXMxamv/qoCP0P98AEnARABDgErUINK3tLP36CdAAABABD/7AT0BbYAFAA5QB0FEwoNDQMTAAQVFgsLEAEQCElZEBMEAAEASVkBAwA/KxEAMxg/KxESADkYLxESARc5ETMRMzEwEzUhFSERFBYzMhERMxEUBiMiJjUREAQ8/i93cuio073GzQUdmZn8aIl7AQABz/4pwM3OwwOgAAABACn/7ASHBEYAFAA2QBwCEAcKCgAQEgQVFgESExJGWQgIDRMPDQVGWQ0WAD8rABg/EjkvKxEAMxESARc5ETMRMzEwASERFBYzMhERMxEUBiMiJjURITUhA4H+pm1216a9wMDJ/qgDWAO6/cmJgwEEAUH+vcrDy8QCP4wAAQBv/+wEWAXLACYAR0AmFSAMACQjBRsRIwAgBicoIw8SDxJKWQ8PHQMdGEpZHRMDCUpZAwQAPysAGD8rERIAORgvKxESADkREgEXOREzETMRMzEwEzQkMyAXByYmIyIGFRQWMzMVIyIGFRQWMzI3FQYhICQ1NDY3NSYmnAEI4QEC0V5ptWWMn9HI2dXe6Mq36cev/vv+9P7bz7yqtARcqcaQeEQ0e3KAk42Oio6NXJ5N3MWXwBYIGbL//wBa/+wDhwRcAgYBggAA//8AAP51BWsFtgAmAbUAAAAHA4AD+gAA//8AEP51BHMESAImAdUAAAAHA4EDAgAA//8AAP6gBRAFvAImACQAAAAHAmcE6QAA//8AXv6gA80EWgImAEQAAAAHAmcEeQAA//8AAAAABRAH4QImACQAAAEHAmYE/AFSAAizAhMFJgArNf//AF7/7APNBo8CJgBEAAABBwJmBKYAAAAIswIpESYAKzX//wAAAAAFEAfRAiYAJAAAAQcDdwTlAVIACrQDAhUFJgArNTX//wBe/+wEQQZ/AiYARAAAAQcDdwSTAAAACrQDAisRJgArNTX//wAAAAAFEAfRAiYAJAAAAQcDeATdAVIACrQDAhUFJgArNTX//wAt/+wDzQZ/AiYARAAAAQcDeASTAAAACrQDAisRJgArNTX//wAAAAAFEAhKAiYAJAAAAQcDeQTZAVIACrQDAhUFJgArNTX//wBe/+wEFwb4AiYARAAAAQcDeQScAAAACrQDAisRJgArNTX//wAAAAAFEAhiAiYAJAAAAQcDegTlAVIACrQDAi0FJgArNTX//wBe/+wDzQcQAiYARAAAAQcDegSRAAAACrQDAkMRJgArNTX//wAA/qAFEAdzAiYAJAAAACcCZwTpAAABBwFLACsBUgAIswMpBSYAKzX//wBe/qADzQYhAiYARAAAACcCZwR5AAABBgFL1AAACLMDPhEmACs1//8AAAAABRAIEwImACQAAAEHA3sE7AFSAAq0AwIXBSYAKzU1//8AXv/sA80GwQImAEQAAAEHA3sEmgAAAAq0AwItESYAKzU1//8AAAAABRAIEwImACQAAAEHA3wE6QFSAAq0AwIXBSYAKzU1//8AXv/sA80GwQImAEQAAAEHA3wEmAAAAAq0AwItESYAKzU1//8AAAAABRAIWAImACQAAAEHA30E6QFSAAq0AwIhBSYAKzU1//8AXv/sA80HBgImAEQAAAEHA30EoAAAAAq0AwI3ESYAKzU1//8AAAAABRAIXgImACQAAAEHA34E4wFSAAq0AwInBSYAKzU1//8AXv/sA80HDAImAEQAAAEHA34EmAAAAAq0AwI9ESYAKzU1//8AAP6gBRAHSQImACQAAAAnAU4ALQFkAQcCZwTpAAAACLMCDwUmACs1//8AXv6gA80F5QImAEQAAAAmAU7YAAEHAmcEeQAAAAizAiURJgArNf//AMn+oAP4BbYCJgAoAAAABwJnBMEAAP//AHP+oAQSBFwCJgBIAAAABwJnBLgAAP//AMkAAAP4B+ECJgAoAAABBwJmBNEBUgAIswEQBSYAKzX//wBz/+wEEgaPAiYASAAAAQcCZgTJAAAACLMCHxEmACs1//8AyQAAA/gHLwImACgAAAEHAVL/5AFSAAizARUFJgArNf//AHP/7AQSBd0CJgBIAAABBgFS0AAACLMCJBEmACs1//8AyQAABG8H0QImACgAAAEHA3cEwQFSAAq0AgESBSYAKzU1//8Ac//sBFwGfwImAEgAAAEHA3cErgAAAAq0AwIhESYAKzU1//8AXQAAA/gH0QImACgAAAEHA3gEwwFSAAq0AgESBSYAKzU1//8ASv/sBBIGfwImAEgAAAEHA3gEsAAAAAq0AwIhESYAKzU1//8AyQAABDkISgImACgAAAEHA3kEvgFSAAq0AgESBSYAKzU1//8Ac//sBB0G+AImAEgAAAEHA3kEogAAAAq0AwIhESYAKzU1//8AyQAAA/gIYgImACgAAAEHA3oEuAFSAAq0AgEqBSYAKzU1//8Ac//sBBIHEAImAEgAAAEHA3oEogAAAAq0AwI5ESYAKzU1//8Ayf6gA/gHcwImACgAAAAnAmcEvgAAAQcBSwACAVIACLMCJQUmACs1//8Ac/6gBBIGIQImAEgAAAAnAmcEsAAAAQYBS/EAAAizAzQRJgArNf//AFQAAAJWB+ECJgAsAAABBwJmA8kBUgAIswEQBSYAKzX//wB7AAAB5gaPAiYA8wAAAQcCZgNzAAAACLMBCBEmACs1//8AVP6gAlYFtgImACwAAAAHAmcDtAAA//8Anf6gAWYF3wImAEwAAAAHAmcDYgAA//8Aff6gBb4FzQImADIAAAAHAmcFfwAA//8Ac/6gBGIEXAImAFIAAAAHAmcEyQAA//8Aff/sBb4H4QImADIAAAEHAmYFjwFSAAizAhwFJgArNf//AHP/7ARiBo8CJgBSAAABBwJmBNkAAAAIswIdESYAKzX//wB9/+wFvgfRAiYAMgAAAQcDdwV9AVIACrQDAh4FJgArNTX//wBz/+wEdQZ/AiYAUgAAAQcDdwTHAAAACrQDAh8RJgArNTX//wB9/+wFvgfRAiYAMgAAAQcDeAV9AVIACrQDAh4FJgArNTX//wBh/+wEYgZ/AiYAUgAAAQcDeATHAAAACrQDAh8RJgArNTX//wB9/+wFvghKAiYAMgAAAQcDeQV7AVIACrQDAh4FJgArNTX//wBz/+wEYgb4AiYAUgAAAQcDeQTHAAAACrQDAh8RJgArNTX//wB9/+wFvghiAiYAMgAAAQcDegV5AVIACrQDAjYFJgArNTX//wBz/+wEYgcQAiYAUgAAAQcDegTFAAAACrQDAjcRJgArNTX//wB9/qAFvgdzAiYAMgAAACcCZwV/AAABBwFLAMEBUgAIswMxBSYAKzX//wBz/qAEYgYhAiYAUgAAACcCZwTNAAABBgFLDgAACLMDMhEmACs1//8Aff/sBmQHcwImAl8AAAEHAHYBKwFSAAizAisFJgArNf//AHP/7AUZBiECJgJgAAABBgB2bQAACLMCKxEmACs1//8Aff/sBmQHcwImAl8AAAEHAEMAhwFSAAizAiMFJgArNf//AHP/7AUZBiECJgJgAAABBgBD1AAACLMCJBEmACs1//8Aff/sBmQH4QImAl8AAAEHAmYFjwFSAAizAiYFJgArNf//AHP/7AUZBo8CJgJgAAABBwJmBNkAAAAIswInESYAKzX//wB9/+wGZAcvAiYCXwAAAQcBUgCgAVIACLMCKwUmACs1//8Ac//sBRkF3QImAmAAAAEGAVL1AAAIswIjESYAKzX//wB9/qAGZAYUAiYCXwAAAAcCZwV7AAD//wBz/qAFGQTwAiYCYAAAAAcCZwTJAAD//wC6/qAFGQW2AiYAOAAAAAcCZwVKAAD//wCk/qAEOQRIAiYAWAAAAAcCZwS4AAD//wC6/+wFGQfhAiYAOAAAAQcCZgVUAVIACLMBFgUmACs1//8ApP/sBDkGjwImAFgAAAEHAmYE1QAAAAizARkRJgArNf//ALr/7AZ7B3MCJgJhAAABBwB2AO4BUgAIswElBSYAKzX//wCk/+wFlgYhAiYCYgAAAQYAdnkAAAizASYRJgArNf//ALr/7AZ7B3MCJgJhAAABBwBDAFoBUgAIswEdBSYAKzX//wCk/+wFlgYhAiYCYgAAAQYAQ7sAAAizAR8RJgArNf//ALr/7AZ7B+ECJgJhAAABBwJmBWABUgAIswEgBSYAKzX//wCk/+wFlgaPAiYCYgAAAQcCZgTbAAAACLMBIhEmACs1//8Auv/sBnsHLwImAmEAAAEHAVIAfwFSAAizASUFJgArNf//AKT/7AWWBd0CJgJiAAABBgFS/wAACLMBHhEmACs1//8Auv6gBnsGFAImAmEAAAAHAmcFTAAA//8ApP6gBZYE8gImAmIAAAAHAmcEsgAA//8AAP6gBHsFtgImADwAAAAHAmcEnAAA//8AAv4UBAYESAImAFwAAAAHAmcFnv/9//8AAAAABHsH4QImADwAAAEHAmYEqgFSAAizAQ0FJgArNf//AAL+FAQGBo8CJgBcAAABBwJmBGoAAAAIswEaESYAKzX//wAAAAAEewcvAiYAPAAAAQcBUv/CAVIACLMBEgUmACs1//8AAv4UBAYF3QImAFwAAAEGAVKKAAAIswEfESYAKzX//wBz/sUE0wYUAiYA0wAAAAcAQgC0AAAAAvvlBNn+tAYhAAkAEwAeQAwECg4OAAAVDwaACwEALzMazTIRATMRMxI5OTEwASMmJic1MxYWFwUjJiYnNTMWFhf+tGA0sSW6HGMx/pxgOK4luxxjMQTZKso/FT2uRBksyD8VPa5EAAAC/HEE2f+uBn8ADQAVAChAERUABhERFwMGChUKFQoRwAYBAC8zGsw5OS8vERI5EQEzETM5OTEwASMmJwYHIzU3NjczFhcnNjczFQYHI/7TXnBjcmFeNXA0sEKXUEk2rFN4YATZS1tlQRk8e01epsJbcBVuYAAAAvuaBNn+1wZ/AA0AFQAqQBIGDhERAAAXAwYKDwoPChPABgEALzMazDk5Ly8REjkRATMRMxI5OTEwASMmJwYHIzU3NjczFhclIyYnNTMWF/7XXmFyamleNXA0sEKX/e5feFSsNEsE2UFlYEYXPHtNXqasXnAVbGEAAvxxBNn/ewb4AA0AHwA0QBgQEwATGwMGBhYODiEDCgYSChIKGR7ABgEALzMazDI5OS8vERI5EQEzETMzEhc5ETMxMAEjJicGByM1NzY3MxYXExQHByMnNjY1NCYjIgc1NjMy/tNecGNyYV41cDSwQpeofwZQCjk/OSsuGhk3wwTZS1tlQRk8e01epgF7Zx1RgwkgJiUZBlAGAAL8aATZ/ucHEAAXACUAOkAbGB4JCRUVJxseIh4ZEQkABQwiAAwMACIDFcAZAC8azBc5Ly8vETMQxDMRMxESOREBMxEzEjk5MTABIi4CIyIGByM2NjMyHgIzMjY3MwYGEyMmJwYHIzU3NjczFhf+LSVHQz8cKCoOWw1lSyVJQz4bKCoMWgtjXl5hcmppXjVwNLBClwY1HiUeMTJqcR4kHjExaHP+pEFlYEYXPHtNXqYAAvx5BNn+xwbBAAcAFAAkQA8HBAoKEhIWA0AHEQqADggALzMa3TLUGs0RATMRMxI5OTEwATY3MxUGByMTIAMzFhYzMjY3MwYG/V5QMaxWd2A+/uwPZglMamJWCGkLlQX0aGUVcl3+/AEESDlBQHiMAAL8eQTZ/scGwQAHABQAJEAPBwQKChISFgRAAREKgA4IAC8zGt0y1BrNEQEzETMSOTkxMAEjJic1MxYXAyADMxYWMzI2NzMGBv3RXndWrDRLNf7sD2YJTGpiVghpC5UF3V1yFWxh/uUBBEg5QUB4jAAC/HkE2f7HBwYAEQAeAC5AFQgAAAUNAxQUHBwgCxAEBBgYGxSAEgAvGs0yMxE5L8QyEQEzETMSFzkRMzEwARQHByMnNjY1NCYjIgc1NjMyAyADMxYWMzI2NzMGBv4xfwZSCjlCOSwlJBY+wJX+7A9mCUxqYlYIaQuVBnlkHSlaCSAlJRoGTgj90wEESDlBQHiMAAL8aATZ/ucHDAAXACQAMEAVGiIJCRUmBQwMHh4YFUARCQAhGoAYAC8a3TLWxDMazREzETkvMxEBMzIROTkxMAEiLgIjIgYHIzY2MzIeAjMyNjczBgYDIAMzFhYzMjY3MwYG/i0lR0M/HCgqDlsNZEwlSUM+GygqDFoLY93+7A9mCUxqYlYIaQuVBjMeJB4wMmhxHiQeMTFncv6mAQRIOUFAeIwAAQAx/kIBbQAAAA8AGkALAAUFAgoDEBENCAMAL8wyERIBFzkRMzEwFzQnMxYVFAYjIic1FjMyNt+Le55mY0EyIDYlM+5nh3iEW2cQbAowAAABABn+dQFxAJoACwAYQAkKAAYADA0IAwAAL8wyERIBOTkRMzEwJREQIyInNRYzMjURAXHkODwpPV6a/t/+/BiME2QBMAAAAQAZ/nUBcQCPAAsAGEAJCgAGAAwNCAMAAC/MMhESATk5ETMxMCURECMiJzUWMzI1EQFx5Dg8KT1ej/7q/vwYjBNkASUA//8ANAAAAkMFtgAHABT/eAAAAAIAc//sBBcEcwALABcAKEAUDAYSAAYAGBkJFUtZCSYDD01ZAxkAPysAGD8rERIBOTkRMxEzMTABEAIjIgIREBIzMhIBFBYzMjY1NCYjIgYEF/fe2fb52tj5/QSbjo2eno+NmgIv/vX+yAE1AQ4BDwE1/sv+8dDo6s7M7OkAAAEALQAAAjcEXgAKACZAEQkBAQAIAAsMBwQHBAEJEAEYAD8/Ejk5Ly8REgE5OREzETMxMCEjETQ3BgcHJwEzAjehCEM+lloBf4sCMe+MQzBwcgEjAAEAKQAAA9cEcwAZACxAGAcTABMXDgEFGhsQCktZECYYFwEXTFkBGAA/KxEAMxg/KxESARc5ETMxMCEhNQE+AjU0JiMiBgcnNjMyFhUUBgcFFyED1/xSAZGdcSyLd1icXFrA8sbagrr+uQICvoUBL3doU0FXZz1KbaiolnO7gOcGAAABAF7+lQQbBHQAJwBHQCYDBBsAEwcHAAQWIg0GKCkEFxYXFktZFxcKJSUeS1klJgoRS1kKJQA/KwAYPysREgA5GC8rERIAORESARc5ETMRMxEzMTABFAYHFRYWFRQEISImJzUWFjMgERAhIzUzMjY1NCYjIgYHJzY2MzIWA+6dkLCq/t7+9XTBW1/XYAF7/l6QkqvIk35gqm1UWuuC1ewDB4yyHggWtJLR4SMsni8xASkBCo+Xhmt6NEZwR1HDAAACABf+qARmBF4ACgASAEJAIRIFCQICCwcDAAMFAxMUAQUSBU1ZCRIODw8HEhIDBxADJAA/PxI5LxI5ETMRMysRADMREgEXOREzMzMRMxEzMTAlIxEjESE1ATMRMyERNDcjBgcBBGbZqP0yAr642f6GDAopRP45G/6NAXN9A8b8RAFc2t5WXP2eAAABAIX+lQQdBF8AGgA6QB8PAxkUCBQXAwQcGwARS1kAAAYVFRhMWRUQBgxLWQYlAD8rABg/KxESADkYLysREgEXOREzETMxMAEyBBUUACMiJzUWFjMyNjUQISIHJxMhFSEDNgIt5wEJ/t/+94JG0GWww/6JXqBWNwLX/bclcwIm5cfj/v5PoC0zpp0BMh03AqyZ/kkXAP//AHX/7AQvBcsCBgAZAAAAAQBe/qkEKwRfAAYAH0AQAQUFAAIDBwgDAkxZAxAAJAA/PysREgEXOREzMTABASE1IRUBAR0CXvzjA839qv6pBR2ZhfrP//8AaP/sBCkFywIGABsAAAACAGr+lQQlBHQAFwAlAEFAIhsRIgoKAAAEEQMmJw4eTVkKFA4OAhQUGEtZFCYCB01ZAiUAPysAGD8rERIAORgvEjkrERIBFzkRMxEzETMxMAEQISInNRYzMhITIwYGIyImNTQSMzIWEgEiBhUUFjMyNjY1NCYmBCX9aHREUGbw9QsMN7ZywuT/0JXfeP4Uj5yQk1uZWFKTAe/8phSPGgEpATNTV+jQ5AEImf7bATC4pJClSoBGabJmAP//AB0AAAXEBh8AJwBJArYAAAAGAEkAAAACAFwC3QWqBcEAIgAzAFpALiwwMC4qJiYoCgAcEQURFgAoLgY1NCsxJAMtLy0pLyMjKBwKFAgDAygpGRQUKQMAPzMvMxDNMi8zEjk5ETMRMxEzERIXORESARc5ETMRMxEzETMRMxEzMTABFAYjIic1FjMyNTQmJicmJjU0NjMyFwcmIyIGFRQWFhcWFgEDIxcRIxEzExMzESMRNyMDAkiVfJFKaneUFzZVeFGObn1cImRTPEsSK1+BUAGmyQgGd7zDy7R/BgjTA6xibSFsKGQhKCEfLFtMVmknYyUuKB0kHCQyWv7sAi+B/lIC0f3RAi/9LwGkif3T//8AEv4UBFoFtgImADcAAAAHAHoBPwAA//8AH/4UAqgFRgImAFcAAAAHAHoAxQAAAAIAcf4UBDcEXAAMACoAR0AmChUaAyoqHh4kFQMrLCEnRlkkIRscDxoPGBIYB0ZZGBASAEZZEhYAPysAGD8rERIAOTkYPz8zKxESARc5ETMRMzMRMzEwJTI2NzU0JiMiBhUUFgU0NyMGIyICERASMzIXMzczERQGIyInNRYWMzI2NQJMqpcEnquQmZcB2wkLcObZ7/PT33sLGIPs+fKVS9J2jqV3t8or4szg0NHZayRjpwEtAQoBCAExppL7pOzsRp4qLqmS//8Acf4UBDcGIQImA5EAAAEGAUsGAAAIswI5ESYAKzX//wBx/hQENwXlAiYDkQAAAQYBTgwAAAizAisRJgArNf//AHH+FAQ3Bd8CJgORAAABBwFPAVYAAAAIswI0ESYAKzX//wBx/hQENwYhAiYDkQAAAQYCOncAAAizAi8RJgArNQABAMkAAAFzBbYAAwARtgAEBQEDABIAPz8REgE5MTAzETMRyaoFtvpKAP//AAUAAAGOB3MCJgOWAAABBwBD/nwBUgAIswEFBSYAKzX//wCzAAACPAdzAiYDlgAAAQcAdv8qAVIACLMBDQUmACs1////xwAAAmkHcwImA5YAAAEHAUv+uwFSAAizARIFJgArNf//AAUAAAI4ByUCJgOWAAABBwBq/tABUgAKtAIBGQUmACs1Nf///6sAAAKTBy8CJgOWAAABBwFS/qMBUgAIswENBSYAKzX////zAAACSwa0AiYDlgAAAQcBTf7GAVIACLMBBwUmACs1////5wAAAlMHNwImA5YAAAEHAU7+wgFSAAizAQQFJgArNf//AFb+QgGiBbYCJgOWAAAABgFRMQD//wC7AAABfwcxAiYDlgAAAQcBTwAZAVIACLMBDQUmACs1//8Ayf5/A6MFtgAmA5YAAAAHAC0COwAA////5AAAAh0GCgAnA5YAqgAAAQcBVP3o/5cAB7IBCAAAPzUA//8AyQAAAXMFtgIGA5YAAP//AAUAAAI4ByUCJgOWAAABBwBq/tABUgAKtAIBGQUmACs1Nf//AMkAAAFzBbYCBgOWAAD//wAFAAACOAclAiYDlgAAAQcAav7QAVIACrQCARkFJgArNTX//wDJAAABcwW2AgYDlgAA//8AyQAAAXMFtgIGA5YAAP//AJkAAAIEB+ECJgOWAAABBwJmA5EBUgAIswEIBSYAKzX//wC4/qABfwW2AiYDlgAAAAcCZwN9AAAAAQAAA6oAigAWAFYABQACABAALwBcAAABDgD4AAMAAQAAAB8AHwAfAB8AUQB3AP8BewHsAmoCgwKuAtkDFQNBA18DdAOWA68D8QQaBFsEuQT7BUYFowXFBjQGkQbHBvsHGwdEB2QHuwhBCIAI2wkZCVUJigm4CggKOQpsCpQKwwrhCx8LVgucC9kMLAx5DMwM8A0kDUsNjw2/DeYOEg42Dk8Ocg6TDqkOyA8kD3kPtBAHEFQQlBEoEWYRlBHSEhASJxJ/ErkS+hNPE6MT1hQoFGgUpRTMFRcVRxWAFawV7hYGFksWhRaFFrYXARdTF6EX9RgaGJUYyxlHGZQZzxntGfUafxqVGs0a2RsTG2MbghvBG/EcExxFHGwcpRzdHPMdCB0eHXsdjB2dHa4dvx3RHd0eKx43HkgeWR5qHnwejR6eHq8ewR8ZHyofOx9MH10fbh+AH64gGSAqIDsgTCBeIG8gsSEYISghOCFIIVghaSF6IgUiESIhIjEiQSJSImMidCKFIpci/yMPIx8jLyM/I08jYCOmJAwkHCQsJDwkTSRdJLQkxSTWJOYk9yUHJRMlHyUwJUAlUSVhJXIlgyWUJaQltSXGJc4mOiZLJlsmbCZ8Jo0mniaqJrYmxybXJugm+CcJJxknKic7J0cnVydoJ3knySgiKDMoRChVKGYodyiIKJMoniivKMYo0ijeKO8pACkMKRcpTCldKW4peSmFKZYppimyKb4p+CotKj4qTipaKmUqdiqGKpcq3isnKzgrSCtZK2kreyuMK+8saSx6LIoslSyhLLIswyzULOQs9S0FLREtHS0uLT4tSS1ULWUtdS2yLgQuFS4lLjYuRi5XLmcueS6KLpwurS65LsUu1i7nLvgvCC8aLysvOy9ML10vbi9+L6Uv+DB3MRYxJzE4MUkxWTFkMW8xmDHBMdcx/zIfMlQyezK0MuYzBTNOM18zZzN4M4oznDOtM78z0DPjM+sz8zQSNBo0IjQqNDI0izSTNJs0wTTJNNE1BjUONTI1OjVxNXk1gTXoNfA2PDaQNqI2tDbENtQ25Db1Nwc3azfQOAY4ZzjFORI5TDmmOdI52josOjQ6XzrKOtI7EDtcO6g77TwlPF08uj0QPV89uT3LPdw97D38Pg0+Hz5vPoA+yj7SPto+7D70P1M/pj/lP/ZAB0A3QD9AhkCOQJZA30DnQSxBiUHBQdJCAUI8QkRCTEJUQlxCZEJsQnRCs0K7QsNC9EMrQ1tDlUPbRCNEYUSvRQ9FVkVeRbpGFUY0RnxGhEbKRyNHW0drR5tH0UgUSElIUUh1SH1IhUiqSLJJE0kbSUxJg0m0Se9KNEp9SrhLCEtlS6lLukwlTDVMg0yLTJNMpUytTQZNWE1gTXBNgE2xTdZN/U4OTh5OL05ATlJOZE51ToZOm06wTrhO2k73TxVPHU86T2lPmk+0T/JQWlB6UIpRJFEsUTRRV1F7UYdRoFHTUhhShlL4U25T1FQsVKBU9FT8VUtVYlV5VZBVp1YKVj5WY1aXVq5W0lcyV2JX41gsWD5YUFh9WIlYlVi8WONZAlkhWUBZdVm3WfxaTVpuWtNbJ1snWydbJ1snWydbJ1snWydbJ1snWydbJ1snXHFczFzdXOVdbF2nXgteHF4tXjleRV5XXoxew17TXuNfQF+XX+BgMWA6YENgTGB6YJlgqmC7YMtg22FOYZlh7WI7Ypti/mM/Y4Bj1mQsZI9k9GVpZeBmjGcwZzhnQGedZ/ZoL2hnaHloi2kBaQ1pgGnzap1rO2vRbDpsfWy/bQNtM21gbYZtrG6QbxtvgW/fcDFwgnDXcUNxe3G0cgZyVXKocvtzB3MTc1BzjHPNdBB0WHSsdOZ1HnVddaJ13XYddnN2xndCd7l3xXfReAJ4NHg8eG94rXjxeTB5cXmueex6MHpzer97C3tDe3p76HxLfMF9LX01fUZ9V32sffx+RH6Hfsx/FX9Vf5Z/2oAegG+AvYDFgNaA5oD4gQmBEYEZgSqBOoGLgdqB7IH9gg+CIYIzgkSCkILaguuC+4MNgx6DMINBg0mDUYNjg3SDhoOXg6iDuIPKg9uD7YP+hBCEIYRMhHeEiYSbhKeEsoS+hMqFEIVWhZSFnIX2hmSGyYcnh4GH1IgriHmIxIkTiWaJsInvii2KioqSip6Kqoq2isKK04rkivaLCIsaiyyLPotQi2KLdIuJi52Lr4vBi9OL5Yv3jAmMG4wtjEKMVoxijG6Mf4yQjKGMsYzDjNWM54z5jQuNHY0vjUGNVo1qjXuNjI2YjaSNsI28jc2N3o3wjgKOFI4mjjiOSo5cjm6Og46XjqiOuI7JjtmO6o77jwyPHI8ojzSPQI9Mj12Pbo9/j4+PoI+wj8GP0o/jj/OP/5ALkBeQI5A0kEWQVpBmkHKQppDhkR2RapHCkfqSMpJ7ks2S9ZMYkzuTRJODk62T7pROlJOU3pTmlQmVEZVulXqV9pYClg6WcZaBlpGWopaylseW2JbplvqXDJcdly6XP5dKl1uXZ5d5l4GXk5ebl62XtZe9l86X2gAAAAEAAAABGdsfPbV9Xw889QAJCAAAAAAAyTUxiwAAAADVK8zV+5r91QmiCGIAAAAJAAIAAAAAAAAEzQDBAAAAAAQUAAACFAAAAiMAmAM1AIUFKwAzBJMAgwaWAGgF1wBxAcUAhQJeAFICXgA9BGoAVgSTAGgB9gA/ApMAVAIhAJgC8AAUBJMAZgSTALwEkwBkBJMAXgSTACsEkwCFBJMAdQSTAF4EkwBoBJMAagIhAJgCIQA/BJMAaASTAHcEkwBoA28AGwcxAHkFEAAABS8AyQUMAH0F1QDJBHMAyQQhAMkF0wB9BecAyQKqAFQCI/9gBOkAyQQnAMkHOQDJBggAyQY7AH0E0QDJBjsAfQTyAMkEZABqBG0AEgXTALoEwwAAB2gAGwSeAAgEewAABJEAUgKiAKYC8AAXAqIAMwRWADEDlv/8BJ4BiQRzAF4E5wCwA88AcwTnAHMEfQBzArYAHQRiACcE6QCwAgYAogIG/5EEMwCwAgYAsAdxALAE6QCwBNUAcwTnALAE5wBzA0QAsAPRAGoC0wAfBOkApAQCAAAGOQAXBDEAJwQIAAIDvgBSAwgAPQRoAe4DCABIBJMAaAIUAAACIwCYBJMAvgSTAD8EkwB7BJMAHwRoAe4EIQB7BJ4BNQaoAGQC1QBGA/oAUgSTAGgCkwBUBqgAZAQA//oDbQB/BJMAaALHADECxwAhBJ4BiQT0ALAFPQBxAiEAmAHRACUCxwBMAwAAQgP6AFAGPQBLBj0ALgY9ABoDbwAzBRAAAAUQAAAFEAAABRAAAAUQAAAFEAAABvz//gUMAH0EcwDJBHMAyQRzAMkEcwDJAqoAPAKqAFQCqv//AqoAPAXHAC8GCADJBjsAfQY7AH0GOwB9BjsAfQY7AH0EkwCFBjsAfQXTALoF0wC6BdMAugXTALoEewAABOMAyQT6ALAEcwBeBHMAXgRzAF4EcwBeBHMAXgRzAF4G3QBeA88AcwR9AHMEfQBzBH0AcwR9AHMCBv/aAgYAqQIG/7MCBv/sBMUAcQTpALAE1QBzBNUAcwTVAHME1QBzBNUAcwSTAGgE1QBzBOkApATpAKQE6QCkBOkApAQIAAIE5wCwBAgAAgUQAAAEcwBeBRAAAARzAF4FEAAABHMAXgUMAH0DzwBzBQwAfQPPAHMFDAB9A88AcwUMAH0DzwBzBdUAyQTnAHMFxwAvBOcAcwRzAMkEfQBzBHMAyQR9AHMEcwDJBH0AcwRzAMkEfQBzBHMAyQR9AHMF0wB9BGIAJwXTAH0EYgAnBdMAfQRiACcF0wB9BGIAJwXnAMkE6QCwBecAAATpABQCqv/iAgb/kAKqACoCBv/aAqoAHgIG/8wCqgBUAgYANQKqAFQCBgCwBM0AVAQMAKICI/9gAgb/kQTpAMkEMwCwBCUAsAQnAMkCBgCjBCcAyQIGAFkEJwDJAgYAsAQnAMkCgwCwBC8AHQIX//wGCADJBOkAsAYIAMkE6QCwBggAyQTpALAFcwABBggAyQTpALAGOwB9BNUAcwY7AH0E1QBzBjsAfQTVAHMHYgB9B4kAcQTyAMkDRACwBPIAyQNEAGAE8gDJA0QAggRkAGoD0QBqBGQAagPRAGoEZABqA9EAagRkAGoD0QBqBG0AEgLTAB8EbQASAtMAHwRtABIC0wAfBdMAugTpAKQF0wC6BOkApAXTALoE6QCkBdMAugTpAKQF0wC6BOkApAXTALoE6QCkB2gAGwY5ABcEewAABAgAAgR7AAAEkQBSA74AUgSRAFIDvgBSBJEAUgO+AFICjwCwBJ4AwwUUAAAEcwBeBvz//gbdAF4GOwB9BNUAcwRkAGoD0QBqBLwBDAS8AQwEsgEtBLwBJQIGAKIEngFvAZMAJQS8AQgEngDnBJ4B/ASeARsFEAAAAiEAmATy/9QGff/UA5j/5AaB/+QFhf/UBoH/5AK2/+kFEAAABS8AyQQpAMkEkwAnBHMAyQSRAFIF5wDJBjsAfQKqAFQE6QDJBNMAAAc5AMkGCADJBG0ASAY7AH0F1QDJBNEAyQSJAEoEbQASBHsAAAZiAGoEngAIBl4AbQZCAFACqgA8BHsAAATjAHMDzQBaBOkAsAK2AKgE3wCkBOMAcwUGALAEGQAKBKQAcQPNAFoD3QBzBOkAsAS8AHMCtgCoBCUAsARG//IE9ACwBFYAAAPNAHEE1QBzBTMAGQTVAKYD2wBzBOcAcwPJABIE3wCkBb4AcwRe/+wGBgCkBi8AcwK2AAkE3wCkBNUAcwTfAKQGLwBzBHMAyQXfABIEKQDJBR0AfQRkAGoCqgBUAqoAPAIj/2AHbwAAB6AAyQXfABIE5QDJBPgAGwXVAMkFEAAABOcAyQUvAMkEKQDJBXcADgRzAMkGwQACBKYASgYZAMsGGQDLBOUAyQWiAAAHOQDJBecAyQY7AH0F1QDJBNEAyQUMAH0EbQASBPgAGwZiAGoEngAIBeUAyQWPAKoIQgDJCEQAyQWBABIG0wDJBSUAyQUKAD0IZgDJBRcAMwRzAF4ExQB3BI0AsANtALAEkwApBH0AcwXjAAQD3QBEBRIAsAUSALAEJwCwBJEAEAXhALAFEgCwBNUAcwT4ALAE5wCwA88AcwO8ACkECAACBbgAcQQxACcFAgCwBN0AnAcfALAHLQCwBY8AKQYpALAEvACwA/AAOQamALAEcQAlBH0AcwTpABQDbQCwA/AAcwPRAGoCBgCiAgb/7AIG/5EGsgAQBxcAsATpABQEJwCwBAgAAgT4ALAENwDJA20AsAdoABsGOQAXB2gAGwY5ABcHaAAbBjkAFwR7AAAECAACBAAAUggAAFIIAABSA0r//AFcABkBXAAZAfYAPwFcABkCzQAZAs0AGQM9ABkEBAB7BBQAewMCAKQGRgCYCZ4AZAHFAIUDJQCFAm8AUgJvAFAD4wCYAQr+eQMnAG0EkwBiBJMARAYbAJoEuAA/BpgAjQQpAHcIJwDJBjUAJQZCAFAE9ABmBj0ARwY9ACAGPQBHBj0AagSmAGYEkwAnBekAyQUMAEwEkwBoBGQAJQWkAHcDEgAMBJMAYgSTAGgEkwBoBJMAaASqAG8EvAAdBLwAHQSeANsCBv+RBAABiQQAAXEEAAGBAscAJwLHABQCxwA7AscAKQLHADkCxwAzAscAIwQAAAAIAAAABAAAAAgAAAACqgAAAgAAAAFWAAAEeQAAAiEAAAGaAAAAzQAAAAAAAAAAAAAIAABUCAAAVAIG/5EBXAAZBPoACgSFAAAGuAASBzkAyQdxALAFEAAABHMAXgZS/t8CqgB1AzMAmAd1AB0HdQAdBj0AfQTfAHMGJQC6BVIApAAA/FMAAP0NAAD8GQAA/QgAAP07BHMAyQYZAMsEfQBzBRIAsAgXAIUGjQAABWYAFwUOABcHWgDJBeMAsAVtAAAEgwAKB14AyQYhALAFxQAUBSMADAfLAMkGxQCwBKgAPwPdABkGXgBtBgYApAY9AH0E1QBzBQIAAAQMAAAFAgAABAwAAAmsAH0IfQBzBo0AfQVCAHMH/gB9BncAcwffAF4GjQAABR0AfQPnAHME3wBqBHUAywSeAPgEngHfBJ4B4QfpACkHpgApBikAyQUlALAE5wAvBLwAFATjAMkE5wCwBDcALwNtABIFIwDJBDMAsAcfAAIGPQAEBKYASgPdAEQFSgDJBFwAsATpAMkERACwBOkALwQjABQFgwAQBOwAKQX4AMkFLwCwBoEAyQXjALAIiQDJBuwAsAY7AH0FHwBzBQwAfQPPAHMEbQAQA7wAKQR7AAAEAgAABHsAAAQCAAAE9AAIBFYAJwbXABAFvAApBYkAqgTfAJwFjwCqBM0AnAWPAMkErgCwBrQAPQVGADMGtAA9BUYAMwKqAFQGwQACBeMABAWDAMkEZACwBaYAAASTABAF0QDJBO4AsAX2AMkFOQCwBY8AqgTdAJwHOwDJBeMAsAKqAFQFEAAABHMAXgUQAAAEcwBeBvz//gbdAF4EcwDJBH0AcwXXAHUEeQBmBdcAdQR5AGYGwQACBeMABASmAEoD3QBEBKoASgPpABsGGQDLBRIAsAYZAMsFEgCwBjsAfQTVAHMGPQB9BNUAcwY9AH0E1QBzBQoAPQPwADkE+AAbBAgAAgT4ABsECAACBPgAGwQIAAIFjwCqBN0AnAQ3AMkDbQCwBtMAyQYpALAENwAvA20AEgT4AAgEUgAnBJ4ABgQxACcE5wCDBOcAcwcxAIMHKwBzBzsATgZqAFAFAABOBC8AUAfZAAAGzwAQCBkAyQdOALAGDAB9BR8AcwWuABAFLQApBKoAbwPNAFoFmgAABJEAEAUQAAAEcwBeBRAAAARzAF4FEAAABHMAXgUQAAAEcwAtBRAAAARzAF4FEAAABHMAXgUQAAAEcwBeBRAAAARzAF4FEAAABHMAXgUQAAAEcwBeBRAAAARzAF4FEAAABHMAXgRzAMkEfQBzBHMAyQR9AHMEcwDJBH0AcwRzAMkEfQBzBHMAXQR9AEoEcwDJBH0AcwRzAMkEfQBzBHMAyQR9AHMCqgBUAgYAewKqAFQCBgCdBjsAfQTVAHMGOwB9BNUAcwY7AH0E1QBzBjsAfQTVAGEGOwB9BNUAcwY7AH0E1QBzBjsAfQTVAHMGPQB9BN8AcwY9AH0E3wBzBj0AfQTfAHMGPQB9BN8AcwY9AH0E3wBzBdMAugTpAKQF0wC6BOkApAYlALoFUgCkBiUAugVSAKQGJQC6BVIApAYlALoFUgCkBiUAugVSAKQEewAABAgAAgR7AAAECAACBHsAAAQIAAIE5wBzAAD75QAA/HEAAPuaAAD8cQAA/GgAAPx5AAD8eQAA/HkAAPxoAaQAMQGkABkBpAAZAy0ANASJAHMC9AAtBBQAKQSTAF4EjwAXBJMAhQSTAHUEkwBeBJMAaASTAGoFbQAdBloAXARtABIC0wAfBOcAcQTnAHEE5wBxBOcAcQTnAHECOwDJAjsABQI7ALMCO//HAjsABQI7/6sCO//zAjv/5wI7AFYCOwC7BF4AyQLl/+QCOwDJAAUAyQAFAMkAyQCZALgAAAABAAAIjf2oAAAJrPua/nsJogABAAAAAAAAAAAAAAAAAAADowADBLYBkAAFAAAFmgUzAAABHwWaBTMAAAPRAGYB8QgCAgsGBgMFBAICBOAAAu9AACBbAAAAKAAAAAAxQVNDAEAAIP/9Bh/+FACECI0CWCAAAZ8AAAAABEgFtgAAACAAAwAAAAEAAwABAAAADAAEA3wAAADGAIAABgBGAEgASQB+AMsAzwEnATIBYQFjAX8BkgGhAbAB8AH/AhsCNwK8AscCyQLdAvMDAQMDAwkDDwMjA4kDigOMA5gDmQOhA6kDqgPOA9ID1gQNBE8EUARcBF8EhgSPBJEEvwTABM4EzwUTHgEePx6FHsceyh7xHvMe+R9NIAsgFSAeICIgJiAwIDMgOiA8IEQgcCB5IH8gpCCnIKwhBSETIRYhICEiISYhLiFeIgIiBiIPIhIiGiIeIisiSCJgImUlyvsE/v///f//AAAAIABJAEoAoADMANABKAEzAWIBZAGSAaABrwHwAfoCGAI3ArwCxgLJAtgC8wMAAwMDCQMPAyMDhAOKA4wDjgOZA5oDowOqA6sD0QPWBAAEDgRQBFEEXQRgBIgEkASSBMAEwQTPBNAeAB4+HoAeoB7IHsse8h70H00gACATIBcgICAmIDAgMiA5IDwgRCBwIHQgfyCjIKcgqyEFIRMhFiEgISIhJiEuIVsiAiIGIg8iESIaIh4iKyJIImAiZCXK+wD+///8////4wNN/+P/wgLL/8IAAP/CAi3/wv+wAL8AsgBh/0kAAAAA/5b+hf6E/nb/aP9j/2L/XQBn/0T90AAX/c/9zgAJ/c79zf/5/c3+gv5/AAD9mv4a/ZkAAP4M/gv9aP4J/ub+Cf7Y/gnkWOQY43rkfQAA5H3jDuR74w3iQuHv4e7h7eHq4eHh4OHb4drh0+HL4cjhmeF24XQAAOEY4QvhCeJu4P7g++D04MjgJeAi4BrgGeAS4A/gA9/n39DfzdxpAAADTwJTAAEAAAAAAAAAAAAAAAAAugAAAAAAAAAAAAAAAAAAAAAAvgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJgAAAAAAAAArAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFIAAAAAAAADmwDrA5wA7QOdAO8DngDxA58A8wOgAUkBSgEkASUCaAGcAZ0BngGfAaADpAOlAaMBpAGlAaYBpwJpAmsB9gH3A6gDRgOpA3UCHAONAjQCNQJdAl5AR1taWVhVVFNSUVBPTk1MS0pJSEdGRURDQkFAPz49PDs6OTg3NjUxMC8uLSwoJyYlJCMiIR8YFBEQDw4NCwoJCAcGBQQDAgEALCCwAWBFsAMlIBFGYSNFI2FILSwgRRhoRC0sRSNGYLAgYSCwRmCwBCYjSEgtLEUjRiNhsCBgILAmYbAgYbAEJiNISC0sRSNGYLBAYSCwZmCwBCYjSEgtLEUjRiNhsEBgILAmYbBAYbAEJiNISC0sARAgPAA8LSwgRSMgsM1EIyC4AVpRWCMgsI1EI1kgsO1RWCMgsE1EI1kgsAQmUVgjILANRCNZISEtLCAgRRhoRCCwAWAgRbBGdmiKRWBELSwBsQsKQyNDZQotLACxCgtDI0MLLSwAsCgjcLEBKD4BsCgjcLECKEU6sQIACA0tLCBFsAMlRWFksFBRWEVEGyEhWS0sSbAOI0QtLCBFsABDYEQtLAGwBkOwB0NlCi0sIGmwQGGwAIsgsSzAioy4EABiYCsMZCNkYVxYsANhWS0sigNFioqHsBErsCkjRLApeuQYLSxFZbAsI0RFsCsjRC0sS1JYRUQbISFZLSxLUVhFRBshIVktLAGwBSUQIyCK9QCwAWAj7ewtLAGwBSUQIyCK9QCwAWEj7ewtLAGwBiUQ9QDt7C0ssAJDsAFSWCEhISEhG0YjRmCKikYjIEaKYIphuP+AYiMgECOKsQwMinBFYCCwAFBYsAFhuP+6ixuwRoxZsBBgaAE6WS0sIEWwAyVGUkuwE1FbWLACJUYgaGGwAyWwAyU/IyE4GyERWS0sIEWwAyVGUFiwAiVGIGhhsAMlsAMlPyMhOBshEVktLACwB0OwBkMLLSwhIQxkI2SLuEAAYi0sIbCAUVgMZCNki7ggAGIbsgBALytZsAJgLSwhsMBRWAxkI2SLuBVVYhuyAIAvK1mwAmAtLAxkI2SLuEAAYmAjIS0sS1NYirAEJUlkI0VpsECLYbCAYrAgYWqwDiNEIxCwDvYbISOKEhEgOS9ZLSxLU1ggsAMlSWRpILAFJrAGJUlkI2GwgGKwIGFqsA4jRLAEJhCwDvaKELAOI0SwDvawDiNEsA7tG4qwBCYREiA5IyA5Ly9ZLSxFI0VgI0VgI0VgI3ZoGLCAYiAtLLBIKy0sIEWwAFRYsEBEIEWwQGFEGyEhWS0sRbEwL0UjRWFgsAFgaUQtLEtRWLAvI3CwFCNCGyEhWS0sS1FYILADJUVpU1hEGyEhWRshIVktLEWwFEOwAGBjsAFgaUQtLLAvRUQtLEUjIEWKYEQtLEUjRWBELSxLI1FYuQAz/+CxNCAbszMANABZREQtLLAWQ1iwAyZFilhkZrAfYBtksCBgZiBYGyGwQFmwAWFZI1hlWbApI0QjELAp4BshISEhIVktLLACQ1RYS1MjS1FaWDgbISFZGyEhISFZLSywFkNYsAQlRWSwIGBmIFgbIbBAWbABYSNYG2VZsCkjRLAFJbAIJQggWAIbA1mwBCUQsAUlIEawBCUjQjywBCWwByUIsAclELAGJSBGsAQlsAFgI0I8IFgBGwBZsAQlELAFJbAp4LApIEVlRLAHJRCwBiWwKeCwBSWwCCUIIFgCGwNZsAUlsAMlQ0iwBCWwByUIsAYlsAMlsAFgQ0gbIVkhISEhISEhLSwCsAQlICBGsAQlI0KwBSUIsAMlRUghISEhLSwCsAMlILAEJQiwAiVDSCEhIS0sRSMgRRggsABQIFgjZSNZI2ggsEBQWCGwQFkjWGVZimBELSxLUyNLUVpYIEWKYEQbISFZLSxLVFggRYpgRBshIVktLEtTI0tRWlg4GyEhWS0ssAAhS1RYOBshIVktLLACQ1RYsEYrGyEhISFZLSywAkNUWLBHKxshISFZLSywAkNUWLBIKxshISEhWS0ssAJDVFiwSSsbISEhWS0sIIoII0tTiktRWlgjOBshIVktLACwAiVJsABTWCCwQDgRGyFZLSwBRiNGYCNGYSMgECBGimG4/4BiirFAQIpwRWBoOi0sIIojSWSKI1NYPBshWS0sS1JYfRt6WS0ssBIASwFLVEItLLECAEKxIwGIUbFAAYhTWli5EAAAIIhUWLICAQJDYEJZsSQBiFFYuSAAAECIVFiyAgICQ2BCsSQBiFRYsgIgAkNgQgBLAUtSWLICCAJDYEJZG7lAAACAiFRYsgIEAkNgQlm5QAAAgGO4AQCIVFiyAggCQ2BCWblAAAEAY7gCAIhUWLICEAJDYEJZsSYBiFFYuUAAAgBjuAQAiFRYsgJAAkNgQlm5QAAEAGO4CACIVFiyAoACQ2BCWVlZWVlZsQACQ1RYQAoFQAhACUAMAg0CG7EBAkNUWLIFQAi6AQAACQEAswwBDQEbsYACQ1JYsgVACLgBgLEJQBuyBUAIugGAAAkBQFm5QAAAgIhVuUAAAgBjuAQAiFVaWLMMAA0BG7MMAA0BWVlZQkJCQkItLEUYaCNLUVgjIEUgZLBAUFh8WWiKYFlELSywABawAiWwAiUBsAEjPgCwAiM+sQECBgywCiNlQrALI0IBsAEjPwCwAiM/sQECBgywBiNlQrAHI0KwARYBLSywgLACQ1CwAbACQ1RbWCEjELAgGskbihDtWS0ssFkrLSyKEOUtQJkJIUggVSABHlUfSANVHx4BDx4/Hq8eA01LJh9MSzMfS0YlHyY0EFUlMyRVGRP/HwcE/x8GA/8fSkkzH0lGJR8TMxJVBQEDVQQzA1UfAwEPAz8DrwMDR0YZH+tGASMzIlUcMxtVFjMVVREBD1UQMw9VDw9PDwIfD88PAg8P/w8CBgIBAFUBMwBVbwB/AK8A7wAEEAABgBYBBQG4AZCxVFMrK0u4B/9SS7AJUFuwAYiwJVOwAYiwQFFasAaIsABVWltYsQEBjlmFjY0AQh1LsDJTWLAgHVlLsGRTWLAQHbEWAEJZc3MrK15zdHUrKysrK3Qrc3QrKysrKysrKysrKysrc3QrKysYXgAAAAYUABcATgW2ABcAdQW2Bc0AAAAAAAAAAAAAAAAAAARIABQAkQAA/+wAAAAA/+wAAAAA/+wAAP4U/+wAAAW2ABP8lP/t/oX/6v6p/+wAGP68AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAIsAgQDdAJgAjwCOAJkAiACBAQ8AigAAAAAADQCiAAMAAQQJAAAAcgAAAAMAAQQJAAEAEgByAAMAAQQJAAIADgCEAAMAAQQJAAMANACSAAMAAQQJAAQAIgDGAAMAAQQJAAUAGADoAAMAAQQJAAYAIAEAAAMAAQQJAAcApAEgAAMAAQQJAAgAKAHEAAMAAQQJAAsAOAHsAAMAAQQJAAwAXAIkAAMAAQQJAA0AXAKAAAMAAQQJAA4AVALcAEQAaQBnAGkAdABpAHoAZQBkACAAZABhAHQAYQAgAGMAbwBwAHkAcgBpAGcAaAB0ACAAqQAgADIAMAAxADAALQAyADAAMQAxACwAIABHAG8AbwBnAGwAZQAgAEMAbwByAHAAbwByAGEAdABpAG8AbgAuAE8AcABlAG4AIABTAGEAbgBzAFIAZQBnAHUAbABhAHIAMQAuADEAMAA7ADEAQQBTAEMAOwBPAHAAZQBuAFMAYQBuAHMALQBSAGUAZwB1AGwAYQByAE8AcABlAG4AIABTAGEAbgBzACAAUgBlAGcAdQBsAGEAcgBWAGUAcgBzAGkAbwBuACAAMQAuADEAMABPAHAAZQBuAFMAYQBuAHMALQBSAGUAZwB1AGwAYQByAE8AcABlAG4AIABTAGEAbgBzACAAaQBzACAAYQAgAHQAcgBhAGQAZQBtAGEAcgBrACAAbwBmACAARwBvAG8AZwBsAGUAIABhAG4AZAAgAG0AYQB5ACAAYgBlACAAcgBlAGcAaQBzAHQAZQByAGUAZAAgAGkAbgAgAGMAZQByAHQAYQBpAG4AIABqAHUAcgBpAHMAZABpAGMAdABpAG8AbgBzAC4AQQBzAGMAZQBuAGQAZQByACAAQwBvAHIAcABvAHIAYQB0AGkAbwBuAGgAdAB0AHAAOgAvAC8AdwB3AHcALgBhAHMAYwBlAG4AZABlAHIAYwBvAHIAcAAuAGMAbwBtAC8AaAB0AHQAcAA6AC8ALwB3AHcAdwAuAGEAcwBjAGUAbgBkAGUAcgBjAG8AcgBwAC4AYwBvAG0ALwB0AHkAcABlAGQAZQBzAGkAZwBuAGUAcgBzAC4AaAB0AG0AbABMAGkAYwBlAG4AcwBlAGQAIAB1AG4AZABlAHIAIAB0AGgAZQAgAEEAcABhAGMAaABlACAATABpAGMAZQBuAHMAZQAsACAAVgBlAHIAcwBpAG8AbgAgADIALgAwAGgAdAB0AHAAOgAvAC8AdwB3AHcALgBhAHAAYQBjAGgAZQAuAG8AcgBnAC8AbABpAGMAZQBuAHMAZQBzAC8ATABJAEMARQBOAFMARQAtADIALgAwAAAAAgAAAAAAAP9mAGYAAAAAAAAAAAAAAAAAAAAAAAAAAAOqAAABAgACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUABUAFgAXABgAGQAaABsAHAAdAB4AHwAgACEAIgAjACQAJQAmACcAKAApACoAKwEDAC0ALgAvADAAMQAyADMANAA1ADYANwA4ADkAOgA7ADwAPQA+AD8AQABBAEIAQwBEAEUARgBHAEgASQBKAEsATABNAE4ATwBQAFEAUgBTAFQAVQBWAFcAWABZAFoAWwBcAF0AXgBfAGAAYQCsAKMAhACFAL0AlgDoAIYAjgCLAJ0AqQCkAQQAigEFAIMAkwDyAPMAjQCXAIgAwwDeAPEAngCqAPUA9AD2AKIArQDJAMcArgBiAGMAkABkAMsAZQDIAMoBBgEHAQgBCQDpAGYA0wDQANEArwBnAPAAkQDWANQA1QBoAOsA7QCJAGoAaQBrAG0AbABuAKAAbwBxAHAAcgBzAHUAdAB2AHcA6gB4AHoAeQB7AH0AfAC4AKEAfwB+AIAAgQDsAO4AugEKAQsBDAENAQ4BDwD9AP4BEAERARIBEwD/AQABFAEVARYBAQEXARgBGQEaARsBHAEdAR4BHwEgASEBIgD4APkBIwEkASUBJgEnASgBKQEqASsBLAEtAS4BLwEwATEBMgEzANcBNAE1ATYBNwE4ATkBOgE7ATwBPQE+AT8BQAFBAUIA4gDjAUMBRAFFAUYBRwFIAUkBSgFLAUwBTQFOAU8BUAFRALAAsQFSAVMBVAFVAVYBVwFYAVkBWgFbAPsA/ADkAOUBXAFdAV4BXwFgAWEBYgFjAWQBZQFmAWcBaAFpAWoBawFsAW0BbgFvAXABcQC7AXIBcwF0AXUA5gDnAXYApgF3AXgBeQF6AXsBfAF9AX4A2ADhANoA2wDcAN0A4ADZAN8BfwGAAYEBggGDAYQBhQGGAYcBiAGJAYoBiwGMAY0BjgGPAZABkQGSAZMBlAGVAZYBlwGYAZkBmgGbAZwBnQGeAZ8BoAGhAaIBowGkAaUBpgGnAagBqQGqAasBrAGtAa4BrwGwAbEBsgGzAbQBtQG2AbcAmwG4AbkBugG7AbwBvQG+Ab8BwAHBAcIBwwHEAcUBxgHHAcgByQHKAcsBzAHNAc4BzwHQAdEB0gHTAdQB1QHWAdcB2AHZAdoB2wHcAd0B3gHfAeAB4QHiAeMB5AHlAeYB5wHoAekB6gHrAewB7QHuAe8B8AHxAfIB8wH0AfUB9gH3AfgB+QH6AfsB/AH9Af4B/wIAAgECAgIDAgQCBQIGAgcCCAIJAgoCCwIMAg0CDgIPAhACEQISAhMCFAIVAhYCFwIYAhkCGgIbAhwCHQIeAh8CIAIhAiICIwIkAiUCJgInAigCKQIqAisAsgCzAiwCLQC2ALcAxAIuALQAtQDFAIIAwgCHAKsAxgIvAjAAvgC/AjEAvAIyAPcCMwI0AjUCNgI3AjgAjACfAjkCOgI7AjwCPQCYAKgAmgCZAO8ApQCSAJwApwCPAJQAlQC5Aj4CPwJAAkECQgJDAkQCRQJGAkcCSAJJAkoCSwJMAk0CTgJPAlACUQJSAlMCVAJVAlYCVwJYAlkCWgJbAlwCXQJeAl8CYAJhAmICYwJkAmUCZgJnAmgCaQJqAmsCbAJtAm4CbwJwAnECcgJzAnQCdQJ2AncCeAJ5AnoCewJ8An0CfgJ/AoACgQKCAoMChAKFAoYChwKIAokCigKLAowCjQKOAo8CkAKRApICkwKUApUClgKXApgCmQKaApsCnAKdAp4CnwKgAqECogKjAqQCpQKmAqcCqAKpAqoCqwKsAq0CrgKvArACsQKyArMCtAK1ArYCtwK4ArkCugK7ArwCvQK+Ar8CwALBAsICwwLEAsUCxgLHAsgCyQLKAssCzALNAs4CzwLQAtEC0gLTAtQC1QLWAtcC2ALZAtoC2wLcAt0C3gLfAuAC4QLiAuMC5ALlAuYC5wLoAukC6gLrAuwC7QLuAu8C8ALxAvIC8wL0AvUC9gL3AvgC+QL6AvsC/AL9Av4C/wMAAwEDAgMDAwQDBQMGAwcDCAMJAwoDCwMMAw0DDgMPAxADEQMSAxMDFAMVAxYDFwMYAxkDGgMbAxwDHQMeAx8DIAMhAyIDIwMkAyUDJgMnAygDKQMqAysDLAMtAy4DLwMwAzEDMgMzAzQDNQM2AzcDOAM5AzoDOwM8Az0DPgM/A0ADQQNCA0MDRANFA0YDRwNIA0kDSgNLA0wDTQNOA08DUANRA1IDUwNUA1UDVgNXA1gDWQNaA1sDXANdA14DXwNgA2EDYgNjA2QDZQNmA2cDaANpA2oDawNsA20DbgNvA3ADcQNyA3MDdAN1A3YDdwN4A3kDegN7A3wDfQN+A38DgAOBA4IDgwOEA4UDhgOHA4gDiQOKA4sDjAONA44DjwOQA5EDkgOTA5QDlQOWA5cDmAOZA5oDmwOcA50DngOfACwAzwDMAM0AzgOgA6EDogOjAPoDpAOlA6YDpwOoA6kDqgOrA6wDrQRudWxsBUkuYWx0B3VuaTAwQUQJb3ZlcnNjb3JlCklncmF2ZS5hbHQKSWFjdXRlLmFsdA9JY2lyY3VtZmxleC5hbHQNSWRpZXJlc2lzLmFsdAdBbWFjcm9uB2FtYWNyb24GQWJyZXZlBmFicmV2ZQdBb2dvbmVrB2FvZ29uZWsLQ2NpcmN1bWZsZXgLY2NpcmN1bWZsZXgEQ2RvdARjZG90BkRjYXJvbgZkY2Fyb24GRGNyb2F0B0VtYWNyb24HZW1hY3JvbgZFYnJldmUGZWJyZXZlCkVkb3RhY2NlbnQKZWRvdGFjY2VudAdFb2dvbmVrB2VvZ29uZWsGRWNhcm9uBmVjYXJvbgtHY2lyY3VtZmxleAtnY2lyY3VtZmxleARHZG90BGdkb3QMR2NvbW1hYWNjZW50DGdjb21tYWFjY2VudAtIY2lyY3VtZmxleAtoY2lyY3VtZmxleARIYmFyBGhiYXIKSXRpbGRlLmFsdAZpdGlsZGULSW1hY3Jvbi5hbHQHaW1hY3JvbgpJYnJldmUuYWx0BmlicmV2ZQtJb2dvbmVrLmFsdAdpb2dvbmVrDklkb3RhY2NlbnQuYWx0BklKLmFsdAJpagtKY2lyY3VtZmxleAtqY2lyY3VtZmxleAxLY29tbWFhY2NlbnQMa2NvbW1hYWNjZW50DGtncmVlbmxhbmRpYwZMYWN1dGUGbGFjdXRlDExjb21tYWFjY2VudAxsY29tbWFhY2NlbnQGTGNhcm9uBmxjYXJvbgRMZG90BGxkb3QGTmFjdXRlBm5hY3V0ZQxOY29tbWFhY2NlbnQMbmNvbW1hYWNjZW50Bk5jYXJvbgZuY2Fyb24LbmFwb3N0cm9waGUDRW5nA2VuZwdPbWFjcm9uB29tYWNyb24GT2JyZXZlBm9icmV2ZQ1PaHVuZ2FydW1sYXV0DW9odW5nYXJ1bWxhdXQGUmFjdXRlBnJhY3V0ZQxSY29tbWFhY2NlbnQMcmNvbW1hYWNjZW50BlJjYXJvbgZyY2Fyb24GU2FjdXRlBnNhY3V0ZQtTY2lyY3VtZmxleAtzY2lyY3VtZmxleAxUY29tbWFhY2NlbnQMdGNvbW1hYWNjZW50BlRjYXJvbgZ0Y2Fyb24EVGJhcgR0YmFyBlV0aWxkZQZ1dGlsZGUHVW1hY3Jvbgd1bWFjcm9uBlVicmV2ZQZ1YnJldmUFVXJpbmcFdXJpbmcNVWh1bmdhcnVtbGF1dA11aHVuZ2FydW1sYXV0B1VvZ29uZWsHdW9nb25lawtXY2lyY3VtZmxleAt3Y2lyY3VtZmxleAtZY2lyY3VtZmxleAt5Y2lyY3VtZmxleAZaYWN1dGUGemFjdXRlClpkb3RhY2NlbnQKemRvdGFjY2VudAVsb25ncwpBcmluZ2FjdXRlCmFyaW5nYWN1dGUHQUVhY3V0ZQdhZWFjdXRlC09zbGFzaGFjdXRlC29zbGFzaGFjdXRlDFNjb21tYWFjY2VudAxzY29tbWFhY2NlbnQFdG9ub3MNZGllcmVzaXN0b25vcwpBbHBoYXRvbm9zCWFub3RlbGVpYQxFcHNpbG9udG9ub3MIRXRhdG9ub3MNSW90YXRvbm9zLmFsdAxPbWljcm9udG9ub3MMVXBzaWxvbnRvbm9zCk9tZWdhdG9ub3MRaW90YWRpZXJlc2lzdG9ub3MFQWxwaGEEQmV0YQVHYW1tYQd1bmkwMzk0B0Vwc2lsb24EWmV0YQNFdGEFVGhldGEISW90YS5hbHQFS2FwcGEGTGFtYmRhAk11Ak51AlhpB09taWNyb24CUGkDUmhvBVNpZ21hA1RhdQdVcHNpbG9uA1BoaQNDaGkDUHNpB3VuaTAzQTkQSW90YWRpZXJlc2lzLmFsdA9VcHNpbG9uZGllcmVzaXMKYWxwaGF0b25vcwxlcHNpbG9udG9ub3MIZXRhdG9ub3MJaW90YXRvbm9zFHVwc2lsb25kaWVyZXNpc3Rvbm9zBWFscGhhBGJldGEFZ2FtbWEFZGVsdGEHZXBzaWxvbgR6ZXRhA2V0YQV0aGV0YQRpb3RhBWthcHBhBmxhbWJkYQd1bmkwM0JDAm51AnhpB29taWNyb24DcmhvBnNpZ21hMQVzaWdtYQN0YXUHdXBzaWxvbgNwaGkDY2hpA3BzaQVvbWVnYQxpb3RhZGllcmVzaXMPdXBzaWxvbmRpZXJlc2lzDG9taWNyb250b25vcwx1cHNpbG9udG9ub3MKb21lZ2F0b25vcwlhZmlpMTAwMjMJYWZpaTEwMDUxCWFmaWkxMDA1MglhZmlpMTAwNTMJYWZpaTEwMDU0DWFmaWkxMDA1NS5hbHQNYWZpaTEwMDU2LmFsdAlhZmlpMTAwNTcJYWZpaTEwMDU4CWFmaWkxMDA1OQlhZmlpMTAwNjAJYWZpaTEwMDYxCWFmaWkxMDA2MglhZmlpMTAxNDUJYWZpaTEwMDE3CWFmaWkxMDAxOAlhZmlpMTAwMTkJYWZpaTEwMDIwCWFmaWkxMDAyMQlhZmlpMTAwMjIJYWZpaTEwMDI0CWFmaWkxMDAyNQlhZmlpMTAwMjYJYWZpaTEwMDI3CWFmaWkxMDAyOAlhZmlpMTAwMjkJYWZpaTEwMDMwCWFmaWkxMDAzMQlhZmlpMTAwMzIJYWZpaTEwMDMzCWFmaWkxMDAzNAlhZmlpMTAwMzUJYWZpaTEwMDM2CWFmaWkxMDAzNwlhZmlpMTAwMzgJYWZpaTEwMDM5CWFmaWkxMDA0MAlhZmlpMTAwNDEJYWZpaTEwMDQyCWFmaWkxMDA0MwlhZmlpMTAwNDQJYWZpaTEwMDQ1CWFmaWkxMDA0NglhZmlpMTAwNDcJYWZpaTEwMDQ4CWFmaWkxMDA0OQlhZmlpMTAwNjUJYWZpaTEwMDY2CWFmaWkxMDA2NwlhZmlpMTAwNjgJYWZpaTEwMDY5CWFmaWkxMDA3MAlhZmlpMTAwNzIJYWZpaTEwMDczCWFmaWkxMDA3NAlhZmlpMTAwNzUJYWZpaTEwMDc2CWFmaWkxMDA3NwlhZmlpMTAwNzgJYWZpaTEwMDc5CWFmaWkxMDA4MAlhZmlpMTAwODEJYWZpaTEwMDgyCWFmaWkxMDA4MwlhZmlpMTAwODQJYWZpaTEwMDg1CWFmaWkxMDA4NglhZmlpMTAwODcJYWZpaTEwMDg4CWFmaWkxMDA4OQlhZmlpMTAwOTAJYWZpaTEwMDkxCWFmaWkxMDA5MglhZmlpMTAwOTMJYWZpaTEwMDk0CWFmaWkxMDA5NQlhZmlpMTAwOTYJYWZpaTEwMDk3CWFmaWkxMDA3MQlhZmlpMTAwOTkJYWZpaTEwMTAwCWFmaWkxMDEwMQlhZmlpMTAxMDIJYWZpaTEwMTAzCWFmaWkxMDEwNAlhZmlpMTAxMDUJYWZpaTEwMTA2CWFmaWkxMDEwNwlhZmlpMTAxMDgJYWZpaTEwMTA5CWFmaWkxMDExMAlhZmlpMTAxOTMJYWZpaTEwMDUwCWFmaWkxMDA5OAZXZ3JhdmUGd2dyYXZlBldhY3V0ZQZ3YWN1dGUJV2RpZXJlc2lzCXdkaWVyZXNpcwZZZ3JhdmUGeWdyYXZlCWFmaWkwMDIwOA11bmRlcnNjb3JlZGJsDXF1b3RlcmV2ZXJzZWQGbWludXRlBnNlY29uZAlleGNsYW1kYmwJbnN1cGVyaW9yCWFmaWkwODk0MQZwZXNldGEERXVybwlhZmlpNjEyNDgJYWZpaTYxMjg5CWFmaWk2MTM1Mgllc3RpbWF0ZWQJb25lZWlnaHRoDHRocmVlZWlnaHRocwtmaXZlZWlnaHRocwxzZXZlbmVpZ2h0aHMHdW5pRkIwMQd1bmlGQjAyDWN5cmlsbGljYnJldmUIZG90bGVzc2oQY2Fyb25jb21tYWFjY2VudAtjb21tYWFjY2VudBFjb21tYWFjY2VudHJvdGF0ZQx6ZXJvc3VwZXJpb3IMZm91cnN1cGVyaW9yDGZpdmVzdXBlcmlvcgtzaXhzdXBlcmlvcg1zZXZlbnN1cGVyaW9yDWVpZ2h0c3VwZXJpb3IMbmluZXN1cGVyaW9yB3VuaTIwMDAHdW5pMjAwMQd1bmkyMDAyB3VuaTIwMDMHdW5pMjAwNAd1bmkyMDA1B3VuaTIwMDYHdW5pMjAwNwd1bmkyMDA4B3VuaTIwMDkHdW5pMjAwQQd1bmkyMDBCB3VuaUZFRkYHdW5pRkZGQwd1bmlGRkZEB3VuaTAxRjAHdW5pMDJCQwd1bmkwM0QxB3VuaTAzRDIHdW5pMDNENgd1bmkxRTNFB3VuaTFFM0YHdW5pMUUwMAd1bmkxRTAxB3VuaTFGNEQHdW5pMDJGMwlkYXNpYW94aWEHdW5pRkIwMwd1bmlGQjA0BU9ob3JuBW9ob3JuBVVob3JuBXVob3JuB3VuaTAzMDAHdW5pMDMwMQd1bmkwMzAzBGhvb2sIZG90YmVsb3cHdW5pMDQwMAd1bmkwNDBEB3VuaTA0NTAHdW5pMDQ1RAd1bmkwNDYwB3VuaTA0NjEHdW5pMDQ2Mgd1bmkwNDYzB3VuaTA0NjQHdW5pMDQ2NQd1bmkwNDY2B3VuaTA0NjcHdW5pMDQ2OAd1bmkwNDY5B3VuaTA0NkEHdW5pMDQ2Qgd1bmkwNDZDB3VuaTA0NkQHdW5pMDQ2RQd1bmkwNDZGB3VuaTA0NzAHdW5pMDQ3MQd1bmkwNDcyB3VuaTA0NzMHdW5pMDQ3NAd1bmkwNDc1B3VuaTA0NzYHdW5pMDQ3Nwd1bmkwNDc4B3VuaTA0NzkHdW5pMDQ3QQd1bmkwNDdCB3VuaTA0N0MHdW5pMDQ3RAd1bmkwNDdFB3VuaTA0N0YHdW5pMDQ4MAd1bmkwNDgxB3VuaTA0ODIHdW5pMDQ4Mwd1bmkwNDg0B3VuaTA0ODUHdW5pMDQ4Ngd1bmkwNDg4B3VuaTA0ODkHdW5pMDQ4QQd1bmkwNDhCB3VuaTA0OEMHdW5pMDQ4RAd1bmkwNDhFB3VuaTA0OEYHdW5pMDQ5Mgd1bmkwNDkzB3VuaTA0OTQHdW5pMDQ5NQd1bmkwNDk2B3VuaTA0OTcHdW5pMDQ5OAd1bmkwNDk5B3VuaTA0OUEHdW5pMDQ5Qgd1bmkwNDlDB3VuaTA0OUQHdW5pMDQ5RQd1bmkwNDlGB3VuaTA0QTAHdW5pMDRBMQd1bmkwNEEyB3VuaTA0QTMHdW5pMDRBNAd1bmkwNEE1B3VuaTA0QTYHdW5pMDRBNwd1bmkwNEE4B3VuaTA0QTkHdW5pMDRBQQd1bmkwNEFCB3VuaTA0QUMHdW5pMDRBRAd1bmkwNEFFB3VuaTA0QUYHdW5pMDRCMAd1bmkwNEIxB3VuaTA0QjIHdW5pMDRCMwd1bmkwNEI0B3VuaTA0QjUHdW5pMDRCNgd1bmkwNEI3B3VuaTA0QjgHdW5pMDRCOQd1bmkwNEJBB3VuaTA0QkIHdW5pMDRCQwd1bmkwNEJEB3VuaTA0QkUHdW5pMDRCRgt1bmkwNEMwLmFsdAd1bmkwNEMxB3VuaTA0QzIHdW5pMDRDMwd1bmkwNEM0B3VuaTA0QzUHdW5pMDRDNgd1bmkwNEM3B3VuaTA0QzgHdW5pMDRDOQd1bmkwNENBB3VuaTA0Q0IHdW5pMDRDQwd1bmkwNENEB3VuaTA0Q0ULdW5pMDRDRi5hbHQHdW5pMDREMAd1bmkwNEQxB3VuaTA0RDIHdW5pMDREMwd1bmkwNEQ0B3VuaTA0RDUHdW5pMDRENgd1bmkwNEQ3B3VuaTA0RDgHdW5pMDREOQd1bmkwNERBB3VuaTA0REIHdW5pMDREQwd1bmkwNEREB3VuaTA0REUHdW5pMDRERgd1bmkwNEUwB3VuaTA0RTEHdW5pMDRFMgd1bmkwNEUzB3VuaTA0RTQHdW5pMDRFNQd1bmkwNEU2B3VuaTA0RTcHdW5pMDRFOAd1bmkwNEU5B3VuaTA0RUEHdW5pMDRFQgd1bmkwNEVDB3VuaTA0RUQHdW5pMDRFRQd1bmkwNEVGB3VuaTA0RjAHdW5pMDRGMQd1bmkwNEYyB3VuaTA0RjMHdW5pMDRGNAd1bmkwNEY1B3VuaTA0RjYHdW5pMDRGNwd1bmkwNEY4B3VuaTA0RjkHdW5pMDRGQQd1bmkwNEZCB3VuaTA0RkMHdW5pMDRGRAd1bmkwNEZFB3VuaTA0RkYHdW5pMDUwMAd1bmkwNTAxB3VuaTA1MDIHdW5pMDUwMwd1bmkwNTA0B3VuaTA1MDUHdW5pMDUwNgd1bmkwNTA3B3VuaTA1MDgHdW5pMDUwOQd1bmkwNTBBB3VuaTA1MEIHdW5pMDUwQwd1bmkwNTBEB3VuaTA1MEUHdW5pMDUwRgd1bmkwNTEwB3VuaTA1MTEHdW5pMDUxMgd1bmkwNTEzB3VuaTFFQTAHdW5pMUVBMQd1bmkxRUEyB3VuaTFFQTMHdW5pMUVBNAd1bmkxRUE1B3VuaTFFQTYHdW5pMUVBNwd1bmkxRUE4B3VuaTFFQTkHdW5pMUVBQQd1bmkxRUFCB3VuaTFFQUMHdW5pMUVBRAd1bmkxRUFFB3VuaTFFQUYHdW5pMUVCMAd1bmkxRUIxB3VuaTFFQjIHdW5pMUVCMwd1bmkxRUI0B3VuaTFFQjUHdW5pMUVCNgd1bmkxRUI3B3VuaTFFQjgHdW5pMUVCOQd1bmkxRUJBB3VuaTFFQkIHdW5pMUVCQwd1bmkxRUJEB3VuaTFFQkUHdW5pMUVCRgd1bmkxRUMwB3VuaTFFQzEHdW5pMUVDMgd1bmkxRUMzB3VuaTFFQzQHdW5pMUVDNQd1bmkxRUM2B3VuaTFFQzcLdW5pMUVDOC5hbHQHdW5pMUVDOQt1bmkxRUNBLmFsdAd1bmkxRUNCB3VuaTFFQ0MHdW5pMUVDRAd1bmkxRUNFB3VuaTFFQ0YHdW5pMUVEMAd1bmkxRUQxB3VuaTFFRDIHdW5pMUVEMwd1bmkxRUQ0B3VuaTFFRDUHdW5pMUVENgd1bmkxRUQ3B3VuaTFFRDgHdW5pMUVEOQd1bmkxRURBB3VuaTFFREIHdW5pMUVEQwd1bmkxRUREB3VuaTFFREUHdW5pMUVERgd1bmkxRUUwB3VuaTFFRTEHdW5pMUVFMgd1bmkxRUUzB3VuaTFFRTQHdW5pMUVFNQd1bmkxRUU2B3VuaTFFRTcHdW5pMUVFOAd1bmkxRUU5B3VuaTFFRUEHdW5pMUVFQgd1bmkxRUVDB3VuaTFFRUQHdW5pMUVFRQd1bmkxRUVGB3VuaTFFRjAHdW5pMUVGMQd1bmkxRUY0B3VuaTFFRjUHdW5pMUVGNgd1bmkxRUY3B3VuaTFFRjgHdW5pMUVGOQd1bmkyMEFCB3VuaTAzMEYTY2lyY3VtZmxleGFjdXRlY29tYhNjaXJjdW1mbGV4Z3JhdmVjb21iEmNpcmN1bWZsZXhob29rY29tYhNjaXJjdW1mbGV4dGlsZGVjb21iDmJyZXZlYWN1dGVjb21iDmJyZXZlZ3JhdmVjb21iDWJyZXZlaG9va2NvbWIOYnJldmV0aWxkZWNvbWIQY3lyaWxsaWNob29rbGVmdBFjeXJpbGxpY2JpZ2hvb2tVQxFjeXJpbGxpY2JpZ2hvb2tMQwhvbmUucG51bQd6ZXJvLm9zBm9uZS5vcwZ0d28ub3MIdGhyZWUub3MHZm91ci5vcwdmaXZlLm9zBnNpeC5vcwhzZXZlbi5vcwhlaWdodC5vcwduaW5lLm9zAmZmB3VuaTIxMjAIVGNlZGlsbGEIdGNlZGlsbGEFZy5hbHQPZ2NpcmN1bWZsZXguYWx0CmdicmV2ZS5hbHQIZ2RvdC5hbHQQZ2NvbW1hYWNjZW50LmFsdAZJdGlsZGUHSW1hY3JvbgZJYnJldmUHSW9nb25lawJJSglJb3RhdG9ub3MESW90YQxJb3RhZGllcmVzaXMJYWZpaTEwMDU1CWFmaWkxMDA1Ngd1bmkwNEMwB3VuaTA0Q0YHdW5pMUVDOAd1bmkxRUNBAAABAAMACAAKAA0AB///AA8AAQAAAAwAAAAAAAAAAgAFAAACNQABAjcCNwABAjsCWwABAl0DdgABA4IDqQABAAAAAQAAAAoADAAOAAAAAAAAAAEAAAAKAG4BWgABbGF0bgAIABAAAk1PTCAAKFJPTSAAQgAA//8ACQADAAgACwAAAA4AEQAUABcAGgAA//8ACgAEAAYACQAMAAEADwASABUAGAAbAAD//wAKAAUABwAKAA0AAgAQABMAFgAZABwAHWxpZ2EAsGxpZ2EAsGxpZ2EAsGxudW0AtmxudW0AtmxudW0AtmxvY2wAvGxvY2wAvG9udW0Awm9udW0Awm9udW0AwnBudW0AynBudW0AynBudW0AynNhbHQA0HNhbHQA0HNhbHQA0HNzMDEA0HNzMDEA0HNzMDEA0HNzMDIA2HNzMDIA2HNzMDIA2HNzMDMA3nNzMDMA3nNzMDMA3nRudW0A5HRudW0A5HRudW0A5AAAAAEACQAAAAEABwAAAAEACAAAAAIAAgADAAAAAQAEAAAAAgAAAAEAAAABAAAAAAABAAEAAAACAAUABgAKABYAPAB8AJQAzADgAO4BAgEuAVAAAQAAAAEACAACABAABQORA5IDkwOUA5UAAQAFAEoA3wDhAOMA5QABAAAAAQAIAAIALgAUACwAjgCPAJAAkQDqAOwA7gDwAPIA9AFaAWcBdwGhAaICyQLYA0UDRwACAAEDlgOpAAAAAQAAAAEACAABAAYDcAACAAEAEwAcAAAAAQAAAAEACAACABoACgODA4UDhgOHA4gDiQOKA4sDjAOEAAIAAwATABMAAAAVABwAAQOCA4IACQABAAAAAQAIAAEABgNuAAEAAQAUAAEAAAABAAgAAQA8/JAAAQAAAAEACAABAAb8kgABAAEDggABAAAAAQAIAAIAGgAKABMDggAVABYAFwAYABkAGgAbABwAAgABA4MDjAAAAAEAAAABAAgAAgAOAAQDjwOQASABIQABAAQBJAElAUkBSgAEAAAAAQAIAAEANgABAAgABQAMABQAHAAiACgCXgADAEkATwJdAAMASQBMA40AAgBJAjUAAgBPAjQAAgBMAAEAAQBJAAA=") format("truetype");font-weight:400;font-style:normal}.w2ui-reset{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;-o-box-sizing:border-box;box-sizing:border-box;font-family:OpenSans;font-size:12px}.w2ui-reset *{color:default;line-height:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;-o-box-sizing:border-box;box-sizing:border-box;margin:0;padding:0}.w2ui-reset table{max-width:none;background-color:transparent;border-collapse:separate;border-spacing:0;border:none}.w2ui-reset table tr td,.w2ui-reset table tr th{font-family:OpenSans;font-size:12px}.w2ui-reset input:not([type=button]):not([type=submit]):not([type=checkbox]):not([type=radio]),.w2ui-reset select,.w2ui-reset textarea{display:inline-block;width:auto;height:auto;vertical-align:baseline;padding:6px;margin:0;font-size:12px;background-color:#f8fafa;border:1px solid #e0e0e0}.w2ui-reset input:not([type=button]):not([type=submit]):not([type=checkbox]):not([type=radio]):focus,.w2ui-reset select:focus,.w2ui-reset textarea:focus{background-color:#fff}.w2ui-reset select{padding:5px;height:26px;font-size:12px}.w2ui-centered{position:absolute;left:0;right:0;top:0;bottom:0;display:flex;flex-wrap:wrap;align-items:center;justify-content:center;text-align:center;padding:10px}.w2ui-disabled,.w2ui-readonly{background-color:#f1f1f1;color:#777}div[contenteditable].w2ui-focus,input.w2ui-focus:not(button),select.w2ui-focus,textarea.w2ui-focus{outline-style:auto;outline-color:#72b2ff}div.w2ui-input:focus,select.w2ui-input:focus{outline-color:#72b2ff}input:not([type=button]):not([type=submit]).w2ui-input,textarea.w2ui-input{padding:6px;border:1px solid #e0e0e0;border-radius:3px;color:#000;background-color:#f8fafa;line-height:normal}input:not([type=button]):not([type=submit]).w2ui-input:focus,textarea.w2ui-input:focus{outline-color:#72b2ff;background-color:#fff}input:not([type=button]):not([type=submit]).w2ui-input:disabled,input:not([type=button]):not([type=submit]).w2ui-input[readonly],textarea.w2ui-input:disabled,textarea.w2ui-input[readonly]{background-color:#f1f1f1;color:#777}select.w2ui-input{color:#000;padding:0 20px 0 7px;line-height:1.8;border-radius:3px;border:1px solid #e0e0e0;-webkit-appearance:none;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAALCAQAAACnzwd+AAAAcklEQVR4AcXMsQFBQQDG4P9tAgC0gJYRQJZgKQMwCqCku6vVAAAA+NJHP4KHOk0aV2pRw61n4BBmyOxKQ8I4ehZeuhd3HTx6DQEGZ7sBfr2OOOOj3Yi43kMKs9sZknofOexqZ8npMygwWZTX51CipP+YA1OiZJbYYg9lAAAAAElFTkSuQmCC),linear-gradient(to bottom,#f8f8f8 20%,#f8f8f8 50%,#f8f8f8 52%,#f8f8f8 100%);background-size:17px 6px,100% 100%;background-position:right center,left top;background-repeat:no-repeat,no-repeat}.w2ui-icon-expand:before{position:relative;top:1px;left:1px;content:' ';width:5px;height:5px;border:2px solid rgba(150,150,150,.8);border-bottom:0;border-left:0;transform:rotateZ(45deg)}.w2ui-icon-collapse:before{position:relative;top:-1px;left:3px;content:' ';width:5px;height:5px;border:2px solid rgba(150,150,150,.8);border-bottom:0;border-left:0;transform:rotateZ(135deg)}input[type=checkbox].w2ui-toggle{position:absolute;opacity:0;width:46px;height:22px;padding:0;margin:0;margin-left:2px}input[type=checkbox].w2ui-toggle:focus{box-shadow:0 0 1px 2px #a8cfff}input[type=checkbox].w2ui-toggle+div{display:inline-block;width:46px;height:22px;border:1px solid #bbb;border-radius:30px;background-color:#eee;transition-duration:.3s;transition-property:background-color,box-shadow;box-shadow:inset 0 0 0 0 rgba(0,0,0,.4);margin-left:2px}input[type=checkbox].w2ui-toggle.w2ui-small+div{width:30px;height:16px}input[type=checkbox].w2ui-toggle:focus+div{box-shadow:0 0 3px 2px #91baed}input[type=checkbox].w2ui-toggle:disabled+div{opacity:.3}input[type=checkbox].w2ui-toggle+div>div{float:left;width:22px;height:22px;border-radius:inherit;background:#f5f5f5;transition-duration:.3s;transition-property:transform,background-color,box-shadow;box-shadow:0 0 1px #323232,0 0 0 1px rgba(200,200,200,.6);pointer-events:none;margin-top:-1px;margin-left:-1px}input[type=checkbox].w2ui-toggle.w2ui-small+div>div{width:16px;height:16px}input[type=checkbox].w2ui-toggle:checked+div>div{transform:translate3d(24px,0,0);background-color:#fff}input[type=checkbox].w2ui-toggle.w2ui-small:checked+div>div{transform:translate3d(14px,0,0)}input[type=checkbox].w2ui-toggle:focus{outline:0}input[type=checkbox].w2ui-toggle:checked+div{border:1px solid #206fad;box-shadow:inset 0 0 0 12px #35a6eb}input[type=checkbox].w2ui-toggle:checked:focus+div{box-shadow:0 0 3px 2px #91baed,inset 0 0 0 12px #35a6eb}input[type=checkbox].w2ui-toggle:checked+div>div{box-shadow:0 2px 5px rgba(0,0,0,.3),0 0 0 1px #206fad}input[type=checkbox].w2ui-toggle.green:checked+div{border:1px solid #00a23f;box-shadow:inset 0 0 0 12px #54b350}input[type=checkbox].w2ui-toggle.green:checked:focus+div{box-shadow:0 0 3px 2px #91baed,inset 0 0 0 12px #54b350}input[type=checkbox].w2ui-toggle.green:checked+div>div{box-shadow:0 2px 5px rgba(0,0,0,.3),0 0 0 1px #00a23f}.w2ui-marker{background-color:rgba(214,161,252,.5)}.w2ui-spinner{display:inline-block;background-size:100%;background-repeat:no-repeat;background-image:url(data:image/gif;base64,R0lGODlhgACAAKIAAP///93d3bu7u5mZmQAA/wAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQFBQAEACwCAAIAfAB8AAAD/0i63P4wygYqmDjrzbtflvWNZGliYXiubKuloivPLlzReD7al+7/Eh5wSFQIi8hHYBkwHUmD6CD5YTJLz49USuVYraRsZ7vtar7XnQ1Kjpoz6LRHvGlz35O4nEPP2O94EnpNc2sef1OBGIOFMId/inB6jSmPdpGScR19EoiYmZobnBCIiZ95k6KGGp6ni4wvqxilrqBfqo6skLW2YBmjDa28r6Eosp27w8Rov8ekycqoqUHODrTRvXsQwArC2NLF29UM19/LtxO5yJd4Au4CK7DUNxPebG4e7+8n8iv2WmQ66BtoYpo/dvfacBjIkITBE9DGlMvAsOIIZjIUAixliv9ixYZVtLUos5GjwI8gzc3iCGghypQqrbFsme8lwZgLZtIcYfNmTJ34WPTUZw5oRxdD9w0z6iOpO15MgTh1BTTJUKos39jE+o/KS64IFVmsFfYT0aU7capdy7at27dw48qdS7eu3bt480I02vUbX2F/JxYNDImw4GiGE/P9qbhxVpWOI/eFKtlNZbWXuzlmG1mv58+gQ4seTbq06dOoU6vGQZJy0FNlMcV+czhQ7SQmYd8eMhPs5BxVdfcGEtV3buDBXQ+fURxx8oM6MT9P+Fh6dOrH2zavc13u9JXVJb520Vp8dvC76wXMuN5Sepm/1WtkEZHDefnzR9Qvsd9+/wi8+en3X0ntYVcSdAE+UN4zs7ln24CaLagghIxBaGF8kFGoIYV+Ybghh841GIyI5ICIFoklJsigihmimJOLEbLYIYwxSgigiZ+8l2KB+Ml4oo/w8dijjcrouCORKwIpnJIjMnkkksalNeR4fuBIm5UEYImhIlsGCeWNNJphpJdSTlkml1jWeOY6TnaRpppUctcmFW9mGSaZceYopH9zkjnjUe59iR5pdapWaGqHopboaYua1qije67GJ6CuJAAAIfkEBQUABAAsCgACAFcAMAAAA/9Iutz+ML5Ag7w46z0r5WAoSp43nihXVmnrdusrv+s332dt4Tyo9yOBUJD6oQBIQGs4RBlHySSKyczVTtHoidocPUNZaZAr9F5FYbGI3PWdQWn1mi36buLKFJvojsHjLnshdhl4L4IqbxqGh4gahBJ4eY1kiX6LgDN7fBmQEJI4jhieD4yhdJ2KkZk8oiSqEaatqBekDLKztBG2CqBACq4wJRi4PZu1sA2+v8C6EJexrBAD1AOBzsLE0g/V1UvYR9sN3eR6lTLi4+TlY1wz6Qzr8u1t6FkY8vNzZTxaGfn6mAkEGFDgL4LrDDJDyE4hEIbdHB6ESE1iD4oVLfLAqPETIsOODwmCDJlv5MSGJklaS6khAQAh+QQFBQAEACwfAAIAVwAwAAAD/0i63P5LSAGrvTjrNuf+YKh1nWieIumhbFupkivPBEzR+GnnfLj3ooFwwPqdAshAazhEGUXJJIrJ1MGOUamJ2jQ9QVltkCv0XqFh5IncBX01afGYnDqD40u2z76JK/N0bnxweC5sRB9vF34zh4gjg4uMjXobihWTlJUZlw9+fzSHlpGYhTminKSepqebF50NmTyor6qxrLO0L7YLn0ALuhCwCrJAjrUqkrjGrsIkGMW/BMEPJcphLgDaABjUKNEh29vdgTLLIOLpF80s5xrp8ORVONgi8PcZ8zlRJvf40tL8/QPYQ+BAgjgMxkPIQ6E6hgkdjoNIQ+JEijMsasNY0RQix4gKP+YIKXKkwJIFF6JMudFEAgAh+QQFBQAEACw8AAIAQgBCAAAD/kg0PPowykmrna3dzXvNmSeOFqiRaGoyaTuujitv8Gx/661HtSv8gt2jlwIChYtc0XjcEUnMpu4pikpv1I71astytkGh9wJGJk3QrXlcKa+VWjeSPZHP4Rtw+I2OW81DeBZ2fCB+UYCBfWRqiQp0CnqOj4J1jZOQkpOUIYx/m4oxg5cuAaYBO4Qop6c6pKusrDevIrG2rkwptrupXB67vKAbwMHCFcTFxhLIt8oUzLHOE9Cy0hHUrdbX2KjaENzey9Dh08jkz8Tnx83q66bt8PHy8/T19vf4+fr6AP3+/wADAjQmsKDBf6AOKjS4aaHDgZMeSgTQcKLDhBYPEswoA1BBAgAh+QQFBQAEACxOAAoAMABXAAAD7Ei6vPOjyUkrhdDqfXHm4OZ9YSmNpKmiqVqykbuysgvX5o2HcLxzup8oKLQQix0UcqhcVo5ORi+aHFEn02sDeuWqBGCBkbYLh5/NmnldxajX7LbPBK+PH7K6narfO/t+SIBwfINmUYaHf4lghYyOhlqJWgqDlAuAlwyBmpVnnaChoqOkpaanqKmqKgGtrq+wsbA1srW2ry63urasu764Jr/CAb3Du7nGt7TJsqvOz9DR0tPU1TIA2ACl2dyi3N/aneDf4uPklObj6OngWuzt7u/d8fLY9PXr9eFX+vv8+PnYlUsXiqC3c6PmUUgAACH5BAUFAAQALE4AHwAwAFcAAAPpSLrc/m7IAau9bU7MO9GgJ0ZgOI5leoqpumKt+1axPJO1dtO5vuM9yi8TlAyBvSMxqES2mo8cFFKb8kzWqzDL7Xq/4LB4TC6bz1yBes1uu9uzt3zOXtHv8xN+Dx/x/wJ6gHt2g3Rxhm9oi4yNjo+QkZKTCgGWAWaXmmOanZhgnp2goaJdpKGmp55cqqusrZuvsJays6mzn1m4uRAAvgAvuBW/v8GwvcTFxqfIycA3zA/OytCl0tPPO7HD2GLYvt7dYd/ZX99j5+Pi6tPh6+bvXuTuzujxXens9fr7YPn+7egRI9PPHrgpCQAAIfkEBQUABAAsPAA8AEIAQgAAA/lIutz+UI1Jq7026h2x/xUncmD5jehjrlnqSmz8vrE8u7V5z/m5/8CgcEgsGo/IpHLJbDqf0Kh0ShBYBdTXdZsdbb/Yrgb8FUfIYLMDTVYz2G13FV6Wz+lX+x0fdvPzdn9WeoJGAYcBN39EiIiKeEONjTt0kZKHQGyWl4mZdREAoQAcnJhBXBqioqSlT6qqG6WmTK+rsa1NtaGsuEu6o7yXubojsrTEIsa+yMm9SL8osp3PzM2cStDRykfZ2tfUtS/bRd3ewtzV5pLo4eLjQuUp70Hx8t9E9eqO5Oku5/ztdkxi90qPg3x2EMpR6IahGocPCxp8AGtigwQAIfkEBQUABAAsHwBOAFcAMAAAA/9Iutz+MMo36pg4682J/V0ojs1nXmSqSqe5vrDXunEdzq2ta3i+/5DeCUh0CGnF5BGULC4tTeUTFQVONYAs4CfoCkZPjFar83rBx8l4XDObSUL1Ott2d1U4yZwcs5/xSBB7dBMBhgEYfncrTBGDW4WHhomKUY+QEZKSE4qLRY8YmoeUfkmXoaKInJ2fgxmpqqulQKCvqRqsP7WooriVO7u8mhu5NacasMTFMMHCm8qzzM2RvdDRK9PUwxzLKdnaz9y/Kt8SyR3dIuXmtyHpHMcd5+jvWK4i8/TXHff47SLjQvQLkU+fG29rUhQ06IkEG4X/Rryp4mwUxSgLL/7IqFETB8eONT6ChCFy5ItqJomES6kgAQAh+QQFBQAEACwKAE4AVwAwAAAD/0i63A4QuEmrvTi3yLX/4MeNUmieITmibEuppCu3sDrfYG3jPKbHveDktxIaF8TOcZmMLI9NyBPanFKJp4A2IBx4B5lkdqvtfb8+HYpMxp3Pl1qLvXW/vWkli16/3dFxTi58ZRcChwIYf3hWBIRchoiHiotWj5AVkpIXi4xLjxiaiJR/T5ehoomcnZ+EGamqq6VGoK+pGqxCtaiiuJVBu7yaHrk4pxqwxMUzwcKbyrPMzZG90NGDrh/JH8t72dq3IN1jfCHb3L/e5ebh4ukmxyDn6O8g08jt7tf26ybz+m/W9GNXzUQ9fm1Q/APoSWAhhfkMAmpEbRhFKwsvCsmosRIHx444PoKcIXKkjIImjTzjkQAAIfkEBQUABAAsAgA8AEIAQgAAA/VIBNz+8KlJq72Yxs1d/uDVjVxogmQqnaylvkArT7A63/V47/m2/8CgcEgsGo/IpHLJbDqf0Kh0Sj0FroGqDMvVmrjgrDcTBo8v5fCZki6vCW33Oq4+0832O/at3+f7fICBdzsChgJGeoWHhkV0P4yMRG1BkYeOeECWl5hXQ5uNIAOjA1KgiKKko1CnqBmqqk+nIbCkTq20taVNs7m1vKAnurtLvb6wTMbHsUq4wrrFwSzDzcrLtknW16tI2tvERt6pv0fi48jh5h/U6Zs77EXSN/BE8jP09ZFA+PmhP/xvJgAMSGBgQINvEK5ReIZhQ3QEMTBLAAAh+QQFBQAEACwCAB8AMABXAAAD50i6DA4syklre87qTbHn4OaNYSmNqKmiqVqyrcvBsazRpH3jmC7yD98OCBF2iEXjBKmsAJsWHDQKmw571l8my+16v+CweEwum8+hgHrNbrvbtrd8znbR73MVfg838f8BeoB7doN0cYZvaIuMjY6PkJGSk2gClgJml5pjmp2YYJ6dX6GeXaShWaeoVqqlU62ir7CXqbOWrLafsrNctjIDwAMWvC7BwRWtNsbGFKc+y8fNsTrQ0dK3QtXAYtrCYd3eYN3c49/a5NVj5eLn5u3s6e7x8NDo9fbL+Mzy9/T5+tvUzdN3Zp+GBAAh+QQJBQAEACwCAAIAfAB8AAAD/0i63P4wykmrvTjrzbv/YCiOZGmeaKqubOu+cCzPdArcQK2TOL7/nl4PSMwIfcUk5YhUOh3M5nNKiOaoWCuWqt1Ou16l9RpOgsvEMdocXbOZ7nQ7DjzTaeq7zq6P5fszfIASAYUBIYKDDoaGIImKC4ySH3OQEJKYHZWWi5iZG0ecEZ6eHEOio6SfqCaqpaytrpOwJLKztCO2jLi1uoW8Ir6/wCHCxMG2x7muysukzb230M6H09bX2Nna29zd3t/g4cAC5OXm5+jn3Ons7eba7vHt2fL16tj2+QL0+vXw/e7WAUwnrqDBgwgTKlzIsKHDh2gGSBwAccHEixAvaqTYcFCjRoYeNyoM6REhyZIHT4o0qPIjy5YTTcKUmHImx5cwE85cmJPnSYckK66sSAAj0aNIkypdyrSp06dQo0qdSrWq1atYs2rdyrWr169gwxZJAAA7)}.w2ui-icon{background-repeat:no-repeat;height:16px;width:16px;overflow:hidden;margin:2px 2px;display:inline-block}.w2ui-icon.icon-folder{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAGrSURBVDjLxZO7ihRBFIa/6u0ZW7GHBUV0UQQTZzd3QdhMQxOfwMRXEANBMNQX0MzAzFAwEzHwARbNFDdwEd31Mj3X7a6uOr9BtzNjYjKBJ6nicP7v3KqcJFaxhBVtZUAK8OHlld2st7Xl3DJPVONP+zEUV4HqL5UDYHr5xvuQAjgl/Qs7TzvOOVAjxjlC+ePSwe6DfbVegLVuT4r14eTr6zvA8xSAoBLzx6pvj4l+DZIezuVkG9fY2H7YRQIMZIBwycmzH1/s3F8AapfIPNF3kQk7+kw9PWBy+IZOdg5Ug3mkAATy/t0usovzGeCUWTjCz0B+Sj0ekfdvkZ3abBv+U4GaCtJ1iEm6ANQJ6fEzrG/engcKw/wXQvEKxSEKQxRGKE7Izt+DSiwBJMUSm71rguMYhQKrBygOIRStf4TiFFRBvbRGKiQLWP29yRSHKBTtfdBmHs0BUpgvtgF4yRFR+NUKi0XZcYjCeCG2smkzLAHkbRBmP0/Uk26O5YnUActBp1GsAI+S5nRJJJal5K1aAMrq0d6Tm9uI6zjyf75dAe6tx/SsWeD//o2/Ab6IH3/h25pOAAAAAElFTkSuQmCC) no-repeat center}.w2ui-icon.icon-page{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAINSURBVBgZBcG/r55zGAfg6/4+z3va01NHlYgzEfE7MdCIGISFgS4Gk8ViYyM2Mdlsko4GSf8Do0FLRCIkghhYJA3aVBtEz3nP89wf11VJvPDepdd390+8Nso5nESBQoq0pfvXm9fzWf19453LF85vASqJlz748vInb517dIw6EyYBIIG49u+xi9/c9MdvR//99MPPZ7+4cP4IZhhTPbwzT2d+vGoaVRRp1rRliVvHq+cfvM3TD82+7mun0o/ceO7NT+/4/KOXjwZU1ekk0840bAZzMQ2mooqh0A72d5x/6sB9D5zYnff3PoYBoWBgFKPKqDKqjCpjKr//dcu9p489dra88cydps30KswACfNEKanSaxhlntjJ8Mv12Paie+vZ+0+oeSwwQ0Iw1xAR1CiFNJkGO4wu3ZMY1AAzBI0qSgmCNJsJUEOtJSMaCTBDLyQ0CknAGOgyTyFFiLI2awMzdEcSQgSAAKVUmAeNkxvWJWCGtVlDmgYQ0GFtgg4pNtOwbBcwQy/Rife/2yrRRVI0qYCEBly8Z+P4qMEMy7JaVw72N568e+iwhrXoECQkfH91kY7jwwXMsBx1L93ZruqrK6uuiAIdSnTIKKPLPFcvay8ww/Hh+ufeznTXu49v95IMoQG3784gYXdTqvRmqn/Wpa/ADFX58MW3L71SVU9ETgEIQQQIOOzub+fhIvwPRDgeVjWDahIAAAAASUVORK5CYII=) no-repeat center}.w2ui-lock{display:none;position:absolute;z-index:1400;top:0;left:0;width:100%;height:100%;opacity:.15;background-color:#333}.w2ui-lock-msg{display:none;position:absolute;z-index:1400;top:50%;left:50%;transform:translateX(-50%) translateY(-50%);min-width:100px;max-width:95%;padding:30px;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;font-size:13px;font-family:OpenSans;opacity:.8;background-color:#555;color:#fff;text-align:center;border-radius:5px;border:2px solid #444}.w2ui-lock-msg .w2ui-spinner{display:inline-block;width:24px;height:24px;margin:-3px 8px -7px -10px}.w2ui-scroll-wrapper{overflow:hidden}.w2ui-scroll-left,.w2ui-scroll-right{top:0;width:18px;height:100%;cursor:default;z-index:10;display:none;position:absolute}.w2ui-scroll-left:hover,.w2ui-scroll-right:hover{background-color:#ddd}.w2ui-scroll-left{left:0;box-shadow:0 0 7px #5f5f5f;background:#f7f7f7 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAQAAADZc7J/AAAAzklEQVR4Ae2THRDEMBCFzy1ucatb3eJ2uhi3uNUtbnGrW9zi1rOdNzdvdl7nDpvYt/9/r7+/51myZZf/zXkD2iMHHRSb0x3oskwMieK05PwEXqP4ExSL0wp0ROao2OOuMPOMdUL6XU1/oGLcFWb+NqyTd2W/P/2qTr9h+nFXhOkHXRHiNyjrgp/U/V+WaQcaNY13zZI0A1JvcVqAnrGDTdtDtZUHjHIJhxxVLN0iqXgCP1l/7h8U9kc6abyJ4/eNWPpGdBv+XdUK0K8cnvcBly2rDr7C1HQAAAAASUVORK5CYII=) center center no-repeat;background-size:15px 12px}.w2ui-scroll-right{right:0;box-shadow:0 0 7px #5f5f5f;background:#f7f7f7 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAQAAADZc7J/AAAAz0lEQVR4Ae2UG7TGMBCEr1vd4la3uMUtuli3utWtbnGLW9zi9l/bDMzJG7u12cfJfLunf1+UEC9Bv0vVQwJ8hjRCaZafflb1C9RQf4OD0gSDE+i+PiJAabFhQc1y1AYYsJGLY3lgxM17uWPO56yPiFDqVPWgRtpIHSd1zPnwkBsdI58OlNwx4fP2X0TgfMTOoHSdKOXkpyNvEyQh7ul+4swxJSTQuwNDxz68l/ukVNbu0Neen5Z+KvzWxBAqHds349uPFJ/jVOrPjxUq++OLf+20q5+noXo0AAAAAElFTkSuQmCC) center center no-repeat;background-size:15px 13px}#w2ui-notify{position:absolute;display:flex;flex-direction:column;align-items:center;left:0;right:0;bottom:15px;z-index:10000;overflow:hidden}#w2ui-notify>div{position:relative;background-color:#292828ba;color:#fff;padding:8px 44px 8px 16px;border-radius:4px;box-shadow:3px 3px 10px #9c9c9c;max-height:76px;min-width:100px;max-width:800px;font-size:16px;text-shadow:1px 0 0 #000}#w2ui-notify>div a{color:#6cd0e8;text-decoration:none;cursor:pointer}#w2ui-notify>div a:hover{color:#a2f0ff}#w2ui-notify>div span.w2ui-notify-close{padding:6px 6px;border-radius:3px;font-size:13px;color:#c3c3c3;position:absolute;right:5px;top:5px}#w2ui-notify>div span.w2ui-notify-close:hover{background-color:#807e7e;color:#fff}#w2ui-notify>div.w2ui-notify-error{text-shadow:none;background-color:rgba(255,0,0,.8)}#w2ui-notify>div.w2ui-notify-error .w2ui-notify-close{color:#fff}#w2ui-notify>div.w2ui-notify-error .w2ui-notify-close:hover{background-color:#fcadad;color:rgba(255,0,0,.8)}button.w2ui-btn,input[type=button].w2ui-btn{position:relative;display:inline-block;border-radius:14px;margin:0 3px;padding:6px 12px;color:#666;font-size:12px;border:1px solid transparent;background-image:linear-gradient(#e8e8ee 0,#e8e8ee 100%);outline:0;box-shadow:0 1px 0 #fff;cursor:default;min-width:75px;line-height:110%;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}button.w2ui-btn:hover,input[type=button].w2ui-btn:hover{text-decoration:none;background-image:linear-gradient(#ddd 0,#ddd 100%);color:#333}button.w2ui-btn.clicked,button.w2ui-btn:active,input[type=button].w2ui-btn.clicked,input[type=button].w2ui-btn:active{background-image:linear-gradient(#ccc 0,#ccc 100%);text-shadow:1px 1px 1px #eee}button.w2ui-btn:focus:before,input[type=button].w2ui-btn:focus:before{content:"";border:1px dashed #aaa;border-radius:15px;position:absolute;top:2px;bottom:2px;left:2px;right:2px;pointer-events:none}button.w2ui-btn-blue,input[type=button].w2ui-btn-blue{color:#fff;background-image:linear-gradient(#269df0 0,#269df0 100%);border:1px solid #269df0;text-shadow:0 0 1px #111}button.w2ui-btn-blue:hover,input[type=button].w2ui-btn-blue:hover{color:#fff;background-image:linear-gradient(#2391dd 0,#2391dd 100%);border:1px solid #2391dd;text-shadow:0 0 1px #111}button.w2ui-btn-blue.clicked,button.w2ui-btn-blue:active,input[type=button].w2ui-btn-blue.clicked,input[type=button].w2ui-btn-blue:active{color:#fff;background-image:linear-gradient(#1e83c9 0,#1e83c9 100%);border:1px solid #1268a6;text-shadow:0 0 1px #111}button.w2ui-btn-blue:focus:before,input[type=button].w2ui-btn-blue:focus:before{border:1px dashed #e8e8e8}button.w2ui-btn-green,input[type=button].w2ui-btn-green{color:#fff;background-image:linear-gradient(#52a452 0,#52a452 100%);border:1px solid #52a452;text-shadow:0 0 1px #111}button.w2ui-btn-green:hover,input[type=button].w2ui-btn-green:hover{color:#fff;background-image:linear-gradient(#3f8f3d 0,#3f8f3d 100%);border:1px solid #3f8f3d;text-shadow:0 0 1px #111}button.w2ui-btn-green.clicked,button.w2ui-btn-green:active,input[type=button].w2ui-btn-green.clicked,input[type=button].w2ui-btn-green:active{color:#fff;background-image:linear-gradient(#377d36 0,#377d36 100%);border:1px solid #555;text-shadow:0 0 1px #111}button.w2ui-btn-green:focus:before,input[type=button].w2ui-btn-green:focus:before{border:1px dashed #e8e8e8}button.w2ui-btn-orange,input[type=button].w2ui-btn-orange{color:#fff;background-image:linear-gradient(#fb8822 0,#fb8822 100%);border:1px solid #fb8822;text-shadow:0 0 1px #111}button.w2ui-btn-orange:hover,input[type=button].w2ui-btn-orange:hover{color:#fff;background-image:linear-gradient(#f1731f 0,#f1731f 100%);border:1px solid #f1731f;text-shadow:0 0 1px #111}button.w2ui-btn-orange.clicked,button.w2ui-btn-orange:active,input[type=button].w2ui-btn-orange.clicked,input[type=button].w2ui-btn-orange:active{color:#fff;border:1px solid #666;background-image:linear-gradient(#b98747 0,#b98747 100%);text-shadow:0 0 1px #111}button.w2ui-btn-orange:focus:before,input[type=button].w2ui-btn-orange:focus:before{border:1px dashed #f9f9f9}button.w2ui-btn-red,input[type=button].w2ui-btn-red{color:#fff;background-image:linear-gradient(#f9585a 0,#f9585a 100%);border:1px solid #f9585a;text-shadow:0 0 1px #111}button.w2ui-btn-red:hover,input[type=button].w2ui-btn-red:hover{color:#fff;background-image:linear-gradient(#de4446 0,#de4446 100%);border:1px solid #de4446;text-shadow:0 0 1px #111}button.w2ui-btn-red.clicked,button.w2ui-btn-red:active,input[type=button].w2ui-btn-red.clicked,input[type=button].w2ui-btn-red:active{color:#fff;border:1px solid #861c1e;background-image:linear-gradient(#9c2123 0,#9c2123 100%);text-shadow:0 0 1px #111}button.w2ui-btn-red:focus:before,input[type=button].w2ui-btn-red:focus:before{border:1px dashed #ddd}button.w2ui-btn-small,input[type=button].w2ui-btn-small{padding:5px;border-radius:4px;margin:0;min-width:0}button.w2ui-btn-small:focus:before,input[type=button].w2ui-btn-small:focus:before{border-radius:2px;top:2px;bottom:2px;left:2px;right:2px}button.w2ui-btn:disabled,input[type=button].w2ui-btn:disabled{border:1px solid #e6e6e6;background:#f7f7f7;color:#bdbcbc;text-shadow:none}.w2ui-overlay{--tip-size:8px;position:fixed;z-index:1700;opacity:0;transition:opacity .1s;border-radius:4px}.w2ui-overlay *{box-sizing:border-box}.w2ui-overlay .w2ui-overlay-body{display:inline-block;border:1px solid #474747;border-radius:4px;padding:4px 8px;margin:0;font-size:12px;font-family:OpenSans;color:#fff;text-shadow:0 1px 1px #4a4a4a;background-color:#777;line-height:1.4;letter-spacing:.1px;overflow:auto}.w2ui-overlay .w2ui-overlay-body.w2ui-light{color:#3c3c3c;text-shadow:none;background-color:#fffde9;border:1px solid #d2d2d2;box-shadow:0 1px 1px 1px #fff}.w2ui-overlay .w2ui-overlay-body.w2ui-white{color:#3c3c3c;text-shadow:none;background-color:#fafafa;border:1px solid #cccace;box-shadow:0 0 1px 1px #fff}.w2ui-overlay .w2ui-overlay-body.w2ui-arrow-right:before{content:"";position:absolute;left:calc(var(--tip-size,8px) * -.5 - 1px);top:calc(50% - 1px);transform:rotate(-45deg) translateY(-50%);transform-origin:top center;margin:0;border:inherit;border-color:inherit;background-color:inherit;width:var(--tip-size,8px);height:var(--tip-size,8px);border-bottom-right-radius:200px;border-bottom-width:0;border-right-width:0}.w2ui-overlay .w2ui-overlay-body.w2ui-arrow-left:after{content:"";position:absolute;right:calc(var(--tip-size,8px) * -.5 - 1px);top:calc(50% - 1px);transform:rotate(135deg) translateY(-50%);transform-origin:top center;margin:0;border:inherit;border-color:inherit;background-color:inherit;width:var(--tip-size,8px);height:var(--tip-size,8px);border-bottom-right-radius:200px;border-bottom-width:0;border-right-width:0}.w2ui-overlay .w2ui-overlay-body.w2ui-arrow-top:before{content:"";position:absolute;bottom:calc(var(--tip-size,8px) * -.5 + 3px);left:50%;transform-origin:center left;transform:rotate(-135deg) translateX(-50%);margin:0;border:inherit;border-color:inherit;background-color:inherit;width:var(--tip-size,8px);height:var(--tip-size,8px);border-bottom-right-radius:200px;border-bottom-width:0;border-right-width:0}.w2ui-overlay .w2ui-overlay-body.w2ui-arrow-bottom:after{content:"";position:absolute;top:calc(var(--tip-size,8px) * -.5);left:50%;transform:rotate(45deg) translateX(-50%);transform-origin:center left;margin:0;border:inherit;border-color:inherit;background-color:inherit;width:var(--tip-size,8px);height:var(--tip-size,8px);border-bottom-right-radius:200px;border-bottom-width:0;border-right-width:0}.w2ui-colors{padding:8px;padding-bottom:0;background-color:#fff;border-radius:3px;overflow:hidden;width:270px;height:240px}.w2ui-colors *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;-o-box-sizing:border-box;box-sizing:border-box}.w2ui-colors .w2ui-color-tabs{display:flex;background-color:#f7f7f7;height:34px;margin:14px -8px 0 -8px;border-top:1px solid #d6d6d6}.w2ui-colors .w2ui-color-tabs .w2ui-color-tab{display:inline-block;width:65px;height:32px;border:0;border-top:2px solid transparent;border-radius:1px;margin:-1.5px 4px;text-align:center;font-size:15px;padding-top:4px;color:#7b7b7b}.w2ui-colors .w2ui-color-tabs .w2ui-color-tab:hover{background-color:#e1e1e1}.w2ui-colors .w2ui-color-tabs .w2ui-color-tab.w2ui-selected{border-top-color:#0175ff}.w2ui-colors .w2ui-color-tabs .w2ui-color-tab .w2ui-icon{padding-top:1px;width:30px}.w2ui-colors .w2ui-tab-content.tab-1 .w2ui-color-row{display:flex}.w2ui-colors .w2ui-tab-content.tab-1 .w2ui-color-row .w2ui-color{cursor:default;text-align:center;display:inline-block;width:18px;height:18px;padding:6px;margin:1.5px;border:1px solid transparent}.w2ui-colors .w2ui-tab-content.tab-1 .w2ui-color-row .w2ui-color:hover{outline:1px solid #666;border:1px solid #fff}.w2ui-colors .w2ui-tab-content.tab-1 .w2ui-color-row .w2ui-color.w2ui-no-color{border:1px solid #efefef;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABlBMVEX/////TgCFoIUYAAAAGUlEQVR42uXHIQEAAACDsNO/NJ4Kn9uC8wsJkAARUrXAjwAAAABJRU5ErkJggg==) 15px 15px}.w2ui-colors .w2ui-tab-content.tab-1 .w2ui-color-row .w2ui-color.w2ui-selected:before{content:'\2022';position:relative;left:-1px;top:-8px;color:#fff;font-size:14px;text-shadow:0 0 2px #222}.w2ui-colors .w2ui-tab-content.tab-2{height:184px;padding:1px 2px}.w2ui-colors .w2ui-tab-content.tab-2 .palette{position:relative;width:150px;height:125px;outline:1px solid #d2d2d2}.w2ui-colors .w2ui-tab-content.tab-2 .palette .palette-bg{height:100%;background-image:linear-gradient(0deg,#000,rgba(204,154,129,0));pointer-events:none}.w2ui-colors .w2ui-tab-content.tab-2 .rainbow{position:relative;width:150px;height:12px;margin:10px 0 0 0;background:linear-gradient(90deg,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red 100%)}.w2ui-colors .w2ui-tab-content.tab-2 .alpha{position:relative;width:150px;height:12px;margin:20px 0 0 0;background-color:#fff;background-image:linear-gradient(45deg,#bbb 25%,transparent 25%,transparent 75%,#bbb 75%,#bbb),linear-gradient(45deg,#bbb 25%,transparent 25%,transparent 75%,#bbb 75%,#bbb);background-size:12px 12px;background-position:0 0,6px 6px}.w2ui-colors .w2ui-tab-content.tab-2 .alpha .alpha-bg{height:100%;background-image:linear-gradient(90deg,rgba(80,80,80,0) 0,#505050 100%);pointer-events:none}.w2ui-colors .w2ui-tab-content.tab-2 .value1{pointer-events:none;position:absolute;top:0;display:inline-block;width:8px;height:8px;border-radius:10px;border:1px solid #999;outline:1px solid #bbb;background-color:transparent;box-shadow:0 0 1px #fff;transform:translateX(-3px) translateY(-3px)}.w2ui-colors .w2ui-tab-content.tab-2 .value2{pointer-events:none;position:absolute;top:-2px;display:inline-block;width:8px;height:16px;border-radius:2px;border:1px solid #696969;background-color:#fff;box-shadow:0 0 1px #fff;transform:translateX(-1px)}.w2ui-colors .w2ui-tab-content.tab-2 .color-info{float:right;margin-right:-5px}.w2ui-colors .w2ui-tab-content.tab-2 .color-info .color-preview-bg{box-shadow:0 0 1px #c3c3c3;height:40px;background-color:#fff;background-image:linear-gradient(45deg,#bbb 25%,transparent 25%,transparent 75%,#bbb 75%,#bbb),linear-gradient(45deg,#bbb 25%,transparent 25%,transparent 75%,#bbb 75%,#bbb);background-size:16px 16px;background-position:0 0,8px 8px;margin-bottom:10px}.w2ui-colors .w2ui-tab-content.tab-2 .color-info .color-original,.w2ui-colors .w2ui-tab-content.tab-2 .color-info .color-preview{height:40px;width:50px;float:left}.w2ui-colors .w2ui-tab-content.tab-2 .color-info .color-part{padding-top:7px}.w2ui-colors .w2ui-tab-content.tab-2 .color-info .color-part span{display:inline-block;width:8px;margin:2px 1px 2px 5px;color:#666}.w2ui-colors .w2ui-tab-content.tab-2 .color-info .color-part input{font-size:12px;border-radius:2px;border:1px solid #ccc;width:30px;text-align:right;padding:4px;color:#333}.w2ui-colors .w2ui-tab-content.tab-2 .color-info .color-part.opacity{margin:11px 0 0 8px}.w2ui-colors .w2ui-tab-content.tab-2 .color-info .color-part.opacity span{width:42px}.w2ui-colors .w2ui-tab-content.tab-2 .color-info .color-part.opacity input{width:38px;text-align:center}.w2ui-menu-search,.w2ui-menu-top{position:sticky;top:0;background-color:#fff;border-bottom:1px dotted silver}.w2ui-menu-search{padding:6px 4px}.w2ui-menu-search .w2ui-icon{position:absolute;top:11px;left:6px;color:#90819c;font-size:14px}.w2ui-menu-search #menu-search{width:100%;padding:5px 5px 5px 25px}.w2ui-menu{display:block;color:#000;padding:5px 0;border-radius:5px;overflow-x:hidden;cursor:default}.w2ui-menu .w2ui-menu-item{display:flex;align-content:stretch;padding:8px 5px;user-select:none}.w2ui-menu .w2ui-menu-item.w2ui-even{color:inherit;background-color:#fff}.w2ui-menu .w2ui-menu-item.w2ui-odd{color:inherit;background-color:#fbfbfb}.w2ui-menu .w2ui-menu-item:hover{background-color:#f0f3ff}.w2ui-menu .w2ui-menu-item.w2ui-selected{background-color:#e1e7ff}.w2ui-menu .w2ui-menu-item.w2ui-disabled{opacity:.4;color:inherit;background-color:transparent}.w2ui-menu .w2ui-menu-item .menu-icon{flex:none;width:26px;height:16px;padding:0;margin:0}.w2ui-menu .w2ui-menu-item .menu-icon span{width:18px;font-size:14px;color:#8d99a7;display:inline-block;padding-top:1px}.w2ui-menu .w2ui-menu-item .menu-text{flex-grow:1;white-space:nowrap}.w2ui-menu .w2ui-menu-item .menu-extra{flex:none;min-width:10px}.w2ui-menu .w2ui-menu-item .menu-extra span{border:1px solid #f6fcf4;border-radius:20px;width:auto;height:18px;padding:2px 7px;margin:0 0 0 10px;background-color:#f2f8f0;color:#666;box-shadow:0 0 2px #474545;text-shadow:1px 1px 0 #fff}.w2ui-menu .w2ui-menu-item .menu-extra span.hotkey{border:none;border-radius:0;background-color:transparent;color:#888;box-shadow:none;text-shadow:none}.w2ui-menu .w2ui-menu-item .menu-extra span.remove{background-color:transparent;border-color:transparent;box-shadow:none;padding:0 5px;border-radius:3px;position:relative;margin-top:-3px;display:block;height:20px;width:20px;text-align:center;user-select:none}.w2ui-menu .w2ui-menu-item .menu-extra span.remove:hover{background-color:#f9e7e7;color:red}.w2ui-menu .w2ui-menu-item .menu-extra span.remove:active{background-color:#ffd1d1}.w2ui-menu .w2ui-menu-divider{padding:5px}.w2ui-menu .w2ui-menu-divider .line{border-top:1px dotted silver}.w2ui-menu .w2ui-menu-divider.has-text{height:26px;background-color:#fafafa;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;text-align:center}.w2ui-menu .w2ui-menu-divider.has-text .line{display:block;margin-top:7px}.w2ui-menu .w2ui-menu-divider.has-text .text{display:inline-block;position:relative;top:-10px;background-color:#fafafa;padding:0 7px;color:#a9a9a9}.w2ui-menu .w2ui-no-items{padding:5px 15px;text-align:center;color:gray}.w2ui-menu .w2ui-no-items .w2ui-spinner{position:relative;left:-2px;margin-bottom:-5px;width:18px;height:18px}.w2ui-menu .w2ui-sub-menu-box{background-color:#fafafd;border-top:1px solid #d6e2e6;border-bottom:1px solid #d6e2e6;padding:0 3px}.w2ui-menu .collapsed .menu-extra span,.w2ui-menu .expanded .menu-extra span{position:relative;border-color:transparent;background-color:transparent;box-shadow:none;padding:0 6px;border-radius:0;margin-left:5px}.w2ui-menu .collapsed .menu-extra span:after,.w2ui-menu .expanded .menu-extra span:after{content:"";position:absolute;border-left:5px solid grey;border-top:5px solid transparent;border-bottom:5px solid transparent;transform:rotateZ(-90deg);pointer-events:none;margin-left:-2px;margin-top:3px}.w2ui-menu .collapsed .menu-extra span:hover,.w2ui-menu .expanded .menu-extra span:hover{border-color:transparent;background-color:transparent}.w2ui-menu .collapsed .menu-extra span:after{transform:rotateZ(90deg)}.w2ui-calendar{margin:0;line-height:1.1;user-select:none}.w2ui-calendar.w2ui-overlay-body{border:1px solid #cccace;color:#3c3c3c;text-shadow:none;background-color:#fff;box-shadow:0 1px 6px 1px #ebeaec}.w2ui-calendar .w2ui-cal-title,.w2ui-calendar .w2ui-time-title{margin:0;padding:7px 2px;background-color:#fafafa;border-top:1px solid #fefefe;border-bottom:1px solid #ddd;color:#555;text-align:center;text-shadow:1px 1px 1px #eee;font-size:16px;cursor:pointer}.w2ui-calendar .w2ui-cal-title .arrow-down,.w2ui-calendar .w2ui-time-title .arrow-down{position:relative;top:-3px;left:5px;opacity:.6}.w2ui-calendar .w2ui-cal-next,.w2ui-calendar .w2ui-cal-previous{width:30px;height:30px;color:#666;border:1px solid transparent;border-radius:3px;padding:7px 5px;margin:-4px 1px 0 1px;cursor:default}.w2ui-calendar .w2ui-cal-next:hover,.w2ui-calendar .w2ui-cal-previous:hover{color:#000;border:1px solid #f5f5f5;background-color:#f9f7f7}.w2ui-calendar .w2ui-cal-next:active,.w2ui-calendar .w2ui-cal-previous:active{color:#000;background-color:#f2f1f4;border:1px solid #e6dbfb}.w2ui-calendar .w2ui-cal-next>div,.w2ui-calendar .w2ui-cal-previous>div{position:absolute;border-left:4px solid #888;border-top:4px solid #888;border-right:4px solid transparent;border-bottom:4px solid transparent;width:0;height:0;padding:0;margin:3px 0 0 0}.w2ui-calendar .w2ui-cal-previous{float:left}.w2ui-calendar .w2ui-cal-previous>div{-webkit-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-ms-transform:rotate(-45deg);-o-transform:rotate(-45deg);transform:rotate(-45deg);margin-left:6px}.w2ui-calendar .w2ui-cal-next{float:right}.w2ui-calendar .w2ui-cal-next>div{-webkit-transform:rotate(135deg);-moz-transform:rotate(135deg);-ms-transform:rotate(135deg);-o-transform:rotate(135deg);transform:rotate(135deg);margin-left:2px;margin-right:2px}.w2ui-calendar .w2ui-cal-jump{display:flex;background-color:#fdfdfd}.w2ui-calendar .w2ui-cal-jump .w2ui-jump-month,.w2ui-calendar .w2ui-cal-jump .w2ui-jump-year{cursor:default;text-align:center;border:1px solid transparent;border-radius:3px;font-size:14px}.w2ui-calendar .w2ui-cal-jump #w2ui-jump-month{width:186px;padding:10px 5px 4px 3px;border-right:1px solid #efefef;display:grid;grid-template-columns:repeat(3,1fr);grid-template-rows:repeat(4,52px);grid-gap:4px}.w2ui-calendar .w2ui-cal-jump #w2ui-jump-month .w2ui-jump-month{padding:15px 0 0 0}.w2ui-calendar .w2ui-cal-jump #w2ui-jump-year{width:90px;height:240px;overflow-x:hidden;overflow-y:auto;margin:0 2px;display:flex;flex-wrap:wrap}.w2ui-calendar .w2ui-cal-jump #w2ui-jump-year .w2ui-jump-year{width:95%;height:30px;padding:5px 0;margin:1px 0}.w2ui-calendar .w2ui-cal-jump .w2ui-jump-month:hover,.w2ui-calendar .w2ui-cal-jump .w2ui-jump-year:hover{color:#000;border:1px solid #f5f5f5;background-color:#f9f7f7}.w2ui-calendar .w2ui-cal-jump .w2ui-jump-month.w2ui-selected,.w2ui-calendar .w2ui-cal-jump .w2ui-jump-year.w2ui-selected{color:#000;background-color:#f2f1f4;border:1px solid #e6dbfb}.w2ui-calendar .w2ui-cal-now{cursor:default;padding:3px;text-align:center;background-color:#f4f4f4;margin:5px;border:1px solid #e5e5e5;border-radius:4px}.w2ui-calendar .w2ui-cal-now:hover{color:#28759e;border:1px solid #c3d6df}.w2ui-calendar .w2ui-cal-days{width:280px;height:240px;padding:2px;display:grid;grid-template-columns:repeat(7,1fr)}.w2ui-calendar .w2ui-cal-days .w2ui-day{border:1px solid #fff;border-radius:3px;color:#000;background-color:#f7f7f7;padding:8px 0 0 0;cursor:default;text-align:center}.w2ui-calendar .w2ui-cal-days .w2ui-day.w2ui-saturday,.w2ui-calendar .w2ui-cal-days .w2ui-day.w2ui-sunday{border:1px solid #fff;color:#c8493b;background-color:#f7f7f7}.w2ui-calendar .w2ui-cal-days .w2ui-day.w2ui-today{background-color:#e2f7cd}.w2ui-calendar .w2ui-cal-days .w2ui-day:hover{background-color:#f2f1f4;border:1px solid #e6dbfb}.w2ui-calendar .w2ui-cal-days .w2ui-day:active{background-color:#eeebf3;border:1px solid #cec2e5}.w2ui-calendar .w2ui-cal-days .w2ui-day.w2ui-selected{border:1px solid #8cb067}.w2ui-calendar .w2ui-cal-days .w2ui-day.w2ui-weekday{text-align:center;background-color:#fff;color:#a99cc2}.w2ui-calendar .w2ui-cal-days .w2ui-day.w2ui-weekday:hover{border:1px solid #fff;background-color:#fff}.w2ui-calendar .w2ui-cal-days .w2ui-day.outside{color:#b5b5b5;background-color:#fff}.w2ui-calendar .w2ui-cal-days .w2ui-day.w2ui-blocked{color:#555;background-color:#fff;border:1px solid #fff}.w2ui-calendar .w2ui-cal-days .w2ui-day.w2ui-blocked:after{content:" ";position:absolute;color:#b3b3b378;font-size:27px;padding:0;font-family:verdana;transform:translate(-15px,15px) rotate(-36deg);border-top:1px solid #c9c2c2;width:24px;transform-origin:top left}.w2ui-cal-time{display:grid;grid-template-columns:repeat(3,1fr);background-color:#fff;cursor:default}.w2ui-cal-time .w2ui-cal-column{width:90px;display:flex;flex-wrap:wrap;padding:4px}.w2ui-cal-time .w2ui-cal-column:nth-child(even){background-color:#fafafa}.w2ui-cal-time .w2ui-cal-column span{width:100%;padding:8px;margin:1px;text-align:center;border:1px solid transparent;border-radius:2px;white-space:nowrap}.w2ui-cal-time .w2ui-cal-column span:hover{background-color:#f2f1f4;border:1px solid #e6dbfb}.w2ui-cal-time .w2ui-cal-column span:active{background-color:#eeebf3;border:1px solid #cec2e5}.w2ui-cal-time .w2ui-cal-column span.w2ui-blocked{pointer-events:none;text-decoration:line-through;color:silver}.w2ui-form{position:relative;color:#000;background-color:#fcfcfb;border:1px solid #e1e1e1;border-radius:3px;padding:0;overflow:hidden}.w2ui-form>.w2ui-form-box{position:absolute;overflow:hidden;top:0;bottom:0;left:0;right:0}.w2ui-form .w2ui-form-header{position:absolute;top:0;left:0;right:0;height:36px;padding:10px;overflow:hidden;font-size:16px;color:#444;background-color:#fff;border-top-left-radius:2px;border-top-right-radius:2px;border-bottom:1px solid #f1f1f1}.w2ui-form .w2ui-form-toolbar{position:absolute;left:0;right:0;margin:0;padding:2px;border-top-left-radius:3px;border-top-right-radius:3px;border-bottom:1px solid #f1f1f1}.w2ui-form .w2ui-form-tabs{position:absolute;left:0;right:0;margin:0;padding:0;height:32px;border-top-left-radius:3px;border-top-right-radius:3px;padding-top:4px;background-color:#fff}.w2ui-form .w2ui-form-tabs .w2ui-tab.active{background-color:#fcfcfb}.w2ui-form .w2ui-page{position:absolute;left:0;right:0;overflow:auto;padding:10px 5px 0 5px;border-left:1px solid inherit;border-right:1px solid inherit;background-color:inherit;border-radius:3px}.w2ui-form .w2ui-column-container{display:flex;padding:0}.w2ui-form .w2ui-column-container .w2ui-column{width:100%}.w2ui-form .w2ui-column-container .w2ui-column.col-0,.w2ui-form .w2ui-column-container .w2ui-column.col-1,.w2ui-form .w2ui-column-container .w2ui-column.col-10,.w2ui-form .w2ui-column-container .w2ui-column.col-2,.w2ui-form .w2ui-column-container .w2ui-column.col-3,.w2ui-form .w2ui-column-container .w2ui-column.col-4,.w2ui-form .w2ui-column-container .w2ui-column.col-5,.w2ui-form .w2ui-column-container .w2ui-column.col-6,.w2ui-form .w2ui-column-container .w2ui-column.col-7,.w2ui-form .w2ui-column-container .w2ui-column.col-8,.w2ui-form .w2ui-column-container .w2ui-column.col-9{padding:0;padding-left:10px}.w2ui-form .w2ui-column-container .w2ui-column.col-0{padding-left:0}.w2ui-form .w2ui-buttons{position:absolute;left:0;right:0;bottom:0;text-align:center;border-top:1px solid #f1f1f1;border-bottom:0 solid #f1f1f1;background-color:#fff;padding:15px 0;border-bottom-left-radius:3px;border-bottom-right-radius:3px}.w2ui-form .w2ui-buttons button,.w2ui-form .w2ui-buttons input[type=button]{min-width:80px;margin-right:5px}.w2ui-form input[type=checkbox]:not(.w2ui-toggle),.w2ui-form input[type=radio]{margin-top:4px;margin-bottom:4px;width:14px;height:14px}.w2ui-group-title{padding:5px 2px 0 5px;color:#656164cc;text-shadow:1px 1px 2px #fdfdfd;font-size:120%}.w2ui-group-fields{background-color:#fff;margin:5px 0 14px 0;padding:10px 5px;border-top:1px dotted #e1e1e1;border-bottom:1px dotted #e1e1e1}.w2ui-field>label{display:block;float:left;margin-top:10px;margin-bottom:0;width:120px;padding:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:right;min-height:20px;color:#666}.w2ui-field>div{margin-bottom:3px;margin-left:128px;padding:4px;min-height:28px;float:none}.w2ui-field.w2ui-required>div{position:relative}.w2ui-field.w2ui-required:not(.w2ui-field-inline)>div::before{content:'*';position:absolute;margin-top:7px;margin-left:-8px;color:red}.w2ui-field.w2ui-required.w2ui-field-inline>div::before{content:''!important}.w2ui-field.w2ui-disabled{opacity:.45;background-color:transparent!important}.w2ui-field.w2ui-disabled input:not([type=button]):not([type=submit]):not([type=checkbox]):not([type=radio]),.w2ui-field.w2ui-disabled select,.w2ui-field.w2ui-disabled textarea{border:1px solid #bdc0c3!important;background-color:#f5f5f5!important}.w2ui-field.w2ui-span-none>label{margin:0;padding:5px 12px 0 4px;display:block;width:98%;text-align:left}.w2ui-field.w2ui-span-none>div{margin-left:0}.w2ui-field.w2ui-span0>label{display:none}.w2ui-field.w2ui-span0>div{margin-left:0}.w2ui-field.w2ui-span1>label{width:20px}.w2ui-field.w2ui-span1>div{margin-left:28px}.w2ui-field.w2ui-span2>label{width:40px}.w2ui-field.w2ui-span2>div{margin-left:48px}.w2ui-field.w2ui-span3>label{width:60px}.w2ui-field.w2ui-span3>div{margin-left:68px}.w2ui-field.w2ui-span4>label{width:80px}.w2ui-field.w2ui-span4>div{margin-left:88px}.w2ui-field.w2ui-span5>label{width:100px}.w2ui-field.w2ui-span5>div{margin-left:108px}.w2ui-field.w2ui-span6>label{width:120px}.w2ui-field.w2ui-span6>div{margin-left:128px}.w2ui-field.w2ui-span7>label{width:140px}.w2ui-field.w2ui-span7>div{margin-left:148px}.w2ui-field.w2ui-span8>label{width:160px}.w2ui-field.w2ui-span8>div{margin-left:168px}.w2ui-field.w2ui-span9>label{width:180px}.w2ui-field.w2ui-span9>div{margin-left:188px}.w2ui-field.w2ui-span10>label{width:200px}.w2ui-field.w2ui-span10>div{margin-left:208px}.w2ui-field.w2ui-field-inline{display:inline}.w2ui-field.w2ui-field-inline>div{display:inline;margin:0;padding:0}.w2ui-field .w2ui-box-label{user-select:none;vertical-align:middle}.w2ui-field .w2ui-box-label input,.w2ui-field .w2ui-box-label span{display:inline-block;vertical-align:middle}.w2ui-field .w2ui-box-label span{padding-left:3px}.w2ui-field .w2ui-box-label input{margin:4px 0 3px 0}input:not([type=button]):not([type=submit]):not([type=checkbox]):not([type=radio]).w2ui-error,textarea.w2ui-error{border:1px solid #ffa8a8;background-color:#fff4eb}.w2field{padding:3px;border-radius:3px;border:1px solid silver}.w2ui-field-helper{position:absolute;display:inline-block;line-height:100%;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.w2ui-field-helper .w2ui-field-up{position:absolute;top:0;padding:2px 3px;cursor:pointer;pointer-events:all}.w2ui-field-helper .w2ui-field-down{position:absolute;bottom:0;padding:2px 3px;cursor:pointer;pointer-events:all}.w2ui-field-helper .arrow-up:hover{border-bottom-color:#81c6ff}.w2ui-field-helper .arrow-down:hover{border-top-color:#81c6ff}.w2ui-field-helper .w2ui-icon-search{position:absolute;margin:8px 0 0 -2px;display:none;color:#777;width:21px!important;font-size:13px}.w2ui-field-helper .w2ui-icon-search.show-search{display:block}.w2ui-field-helper.w2ui-list{color:inherit;position:absolute;padding:0;margin:0;min-height:28px;overflow:auto;border:1px solid #e0e0e0;border-radius:3px;font-size:6px;line-height:100%;box-sizing:border-box;pointer-events:all;background-color:#f7fafa}.w2ui-field-helper.w2ui-list.has-focus,.w2ui-field-helper.w2ui-list:focus-within{outline:auto #72b2ff;background-color:#fff}.w2ui-field-helper.w2ui-list input[type=text]{-webkit-box-shadow:none;-moz-box-shadow:none;-ms-box-shadow:none;-o-box-shadow:none;box-shadow:none}.w2ui-field-helper.w2ui-list .w2ui-multi-items{position:absolute;display:inline-block;margin:0;padding:0;pointer-events:none}.w2ui-field-helper.w2ui-list .w2ui-multi-items .li-item{pointer-events:all;float:left;margin:3px 0 0 5px;border-radius:15px;width:auto;padding:3px 24px 1px 12px;border:1px solid #b4d0de;background-color:#eff3f5;white-space:nowrap;cursor:default;font-family:OpenSans;font-size:11px;line-height:100%;height:20px;overflow:hidden;text-overflow:ellipsis;box-sizing:border-box}.w2ui-field-helper.w2ui-list .w2ui-multi-items .li-item:hover{background-color:#d0dbe1}.w2ui-field-helper.w2ui-list .w2ui-multi-items .li-item:last-child{border-radius:0;border:1px solid transparent;background-color:transparent}.w2ui-field-helper.w2ui-list .w2ui-multi-items .li-item:last-child input{padding:1px;padding-top:0;margin:0;border:0;outline:0;height:auto;line-height:100%;font-size:inherit;font-family:inherit;background-color:transparent}.w2ui-field-helper.w2ui-list .w2ui-multi-items .li-item .w2ui-icon{float:left;color:#828aa7;margin:1px 2px 0 -6px}.w2ui-field-helper.w2ui-list .w2ui-multi-items .li-item .w2ui-list-remove{float:right;width:16px;height:16px;margin:-2px -20px 0 0;border-radius:2px;font-size:12px;border:1px solid transparent}.w2ui-field-helper.w2ui-list .w2ui-multi-items .li-item .w2ui-list-remove:hover{background-color:#f6e5e5;border:1px solid #fac2c2;color:red;opacity:1}.w2ui-field-helper.w2ui-list .w2ui-multi-items .li-item .w2ui-list-remove:before{position:relative;display:inline-block;left:4px;opacity:.7;content:'x';line-height:1}.w2ui-field-helper.w2ui-list .w2ui-multi-items .li-item>span.file-size{pointer-events:none;color:#777}.w2ui-field-helper.w2ui-list .w2ui-multi-items .li-search{float:left;margin:0;padding:0}.w2ui-field-helper.w2ui-list .w2ui-multi-items .li-search input[type=text]{pointer-events:all;width:0;height:20px;padding:3px 0 3px 0;margin:3px 0 0 5px;border:0;background-color:transparent}.w2ui-field-helper.w2ui-list .w2ui-multi-items .li-search input[type=text]:focus{outline:0;border:0}.w2ui-field-helper.w2ui-list .w2ui-multi-file{position:absolute;left:0;right:0;top:0;bottom:0}.w2ui-field-helper.w2ui-list.w2ui-readonly .w2ui-multi-items>.li-item:hover{background-color:#eff3f5}.w2ui-field-helper.w2ui-list.w2ui-file-dragover{background-color:#e4ffda;border:1px solid #93e07d}.w2ui-field-helper.w2ui-list .w2ui-enum-placeholder{display:inline;position:absolute;pointer-events:none;color:#999;box-sizing:border-box}.w2ui-overlay .w2ui-file-preview{padding:1px;background-color:#fff}.w2ui-overlay .w2ui-file-info{display:grid;grid-template-columns:1fr 2fr;color:#fff;padding:6px 0}.w2ui-overlay .w2ui-file-info .file-caption{text-align:right;color:silver;padding-right:10px}.w2ui-overlay .w2ui-file-info .file-value{color:#fff}.w2ui-overlay .w2ui-file-info .file-type{max-width:200px;display:block-inline;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.arrow-up{background:0 0;width:0;height:0;border-left:4px solid transparent;border-right:4px solid transparent;border-bottom:5px solid #777;font-size:0;line-height:0}.arrow-down{background:0 0;width:0;height:0;border-left:4px solid transparent;border-right:4px solid transparent;border-top:5px solid #777;font-size:0;line-height:0}.arrow-left{background:0 0;width:0;height:0;border-bottom:4px solid transparent;border-top:4px solid transparent;border-right:5px solid #777;font-size:0;line-height:0}.arrow-right{background:0 0;width:0;height:0;border-bottom:4px solid transparent;border-top:4px solid transparent;border-left:5px solid #777;font-size:0;line-height:0}.w2ui-select{cursor:default;color:#000!important;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAALCAQAAACnzwd+AAAAcklEQVR4AcXMsQFBQQDG4P9tAgC0gJYRQJZgKQMwCqCku6vVAAAA+NJHP4KHOk0aV2pRw61n4BBmyOxKQ8I4ehZeuhd3HTx6DQEGZ7sBfr2OOOOj3Yi43kMKs9sZknofOexqZ8npMygwWZTX51CipP+YA1OiZJbYYg9lAAAAAElFTkSuQmCC);background-size:17px 6px;background-position:right center;background-repeat:no-repeat}.w2ui-select.has-focus{outline:auto #72b2ff;background-color:#fff!important}.w2ui-select[disabled],.w2ui-select[readonly]{background-image:none;background-color:#f1f1f1!important;color:#777!important}.w2ui-layout{position:relative;overflow:hidden}.w2ui-layout>div{position:absolute;overflow:hidden;left:0;top:0;right:0;bottom:0}.w2ui-layout>div .w2ui-panel{display:none;position:absolute;z-index:120}.w2ui-layout>div .w2ui-panel .w2ui-panel-title{position:absolute;left:0;top:0;right:0;padding:5px;background-color:#fff;color:#656164cc;border:1px solid #efefef;border-bottom:1px solid #f5f5f5}.w2ui-layout>div .w2ui-panel .w2ui-panel-tabs{position:absolute;left:0;top:0;right:0;z-index:2;display:none;overflow:hidden;background-color:#fff;padding:0}.w2ui-layout>div .w2ui-panel .w2ui-panel-tabs>.w2ui-tab.active{background-color:#fcfcfc}.w2ui-layout>div .w2ui-panel .w2ui-panel-toolbar{position:absolute;left:0;top:0;right:0;z-index:2;display:none;overflow:hidden;background-color:#fafafa;border-bottom:1px solid #efefef;padding:2px}.w2ui-layout>div .w2ui-panel .w2ui-panel-content{position:absolute;left:0;top:0;right:0;bottom:0;z-index:1;color:inherit;background-color:#fcfcfc}.w2ui-layout>div .w2ui-resizer{display:none;position:absolute;z-index:121;background-color:transparent}.w2ui-layout>div .w2ui-resizer.active,.w2ui-layout>div .w2ui-resizer:hover{background-color:#c8cad1}.w2ui-grid{position:relative;border:1px solid #e1e1e1;border-radius:2px;overflow:hidden!important}.w2ui-grid>.w2ui-grid-box{position:absolute;overflow:hidden;left:0;top:0;right:0;bottom:0}.w2ui-grid .w2ui-grid-header{position:absolute;top:0;left:0;right:0;height:36px;padding:10px;overflow:hidden;font-size:16px;color:#444;background-color:#fff;border-top-left-radius:2px;border-top-right-radius:2px;border-bottom:1px solid #e1e1e1!important}.w2ui-grid .w2ui-grid-toolbar{position:absolute;border-bottom:1px solid #efefef;background-color:#fafafa;height:52px;padding:9px 3px 0 3px;margin:0;box-shadow:0 1px 2px #f5f5f5}.w2ui-grid .w2ui-grid-toolbar .w2ui-tb-button .w2ui-tb-icon{margin:3px 0 0 0!important}.w2ui-grid .w2ui-grid-toolbar .w2ui-grid-search-input{position:relative;width:300px;left:0;top:-4px}.w2ui-grid .w2ui-grid-toolbar .w2ui-grid-search-input .w2ui-search-down{position:absolute;top:7px;left:4px;color:#8c99a7;font-size:13px}.w2ui-grid .w2ui-grid-toolbar .w2ui-grid-search-input .w2ui-grid-search-name{position:absolute;margin:5px 0 0 3px;padding:4px 27px 4px 10px;background-color:#fbfbfb;border:1px solid #b9b9b9;border-radius:15px;pointer-events:none}.w2ui-grid .w2ui-grid-toolbar .w2ui-grid-search-input .w2ui-grid-search-name .name-icon{position:absolute;margin-left:-6px;color:#8c99a7}.w2ui-grid .w2ui-grid-toolbar .w2ui-grid-search-input .w2ui-grid-search-name .name-text{padding-left:14px}.w2ui-grid .w2ui-grid-toolbar .w2ui-grid-search-input .w2ui-grid-search-name .name-cross{position:absolute;margin-top:-4px;margin-left:7px;padding:4px 5px;pointer-events:all}.w2ui-grid .w2ui-grid-toolbar .w2ui-grid-search-input .w2ui-grid-search-name .name-cross:hover{color:red}.w2ui-grid .w2ui-grid-toolbar .w2ui-grid-search-input .w2ui-search-all{outline:0!important;border-radius:4px!important;line-height:normal!important;height:30px!important;width:300px!important;border:1px solid #e1e1e1!important;color:#000!important;background-color:#f1f1f1!important;padding:1px 28px 0 28px!important;margin:0!important;margin-top:1px!important;font-size:13px!important}.w2ui-grid .w2ui-grid-toolbar .w2ui-grid-search-input .w2ui-search-all:focus{border:1px solid #007cff!important;background-color:#fff!important}.w2ui-grid .w2ui-grid-toolbar .w2ui-grid-search-input .w2ui-search-drop{position:absolute;right:2px;top:3px;height:26px;width:26px;font-size:16px;color:#a4adb1;cursor:pointer;padding:7px 2px 7px 2px;border-radius:4px;background-color:transparent}.w2ui-grid .w2ui-grid-toolbar .w2ui-grid-search-input .w2ui-search-drop span.w2ui-icon-drop{position:relative;top:-2px}.w2ui-grid .w2ui-grid-toolbar .w2ui-grid-search-input .w2ui-search-drop.checked,.w2ui-grid .w2ui-grid-toolbar .w2ui-grid-search-input .w2ui-search-drop:hover{color:#fff;background-color:#56a1e2}.w2ui-grid .w2ui-grid-toolbar .w2ui-grid-searches{display:flex;flex-direction:row;flex-wrap:nowrap;border-top:1px solid #ececec;border-bottom:1px solid #ececec;background-color:#fcfdff;margin:7px -20px 0 -20px;padding:6px 50px 6px 20px;height:36px}.w2ui-grid .w2ui-grid-toolbar .w2ui-grid-searches>div{white-space:nowrap}.w2ui-grid .w2ui-grid-toolbar .w2ui-grid-searches>span{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;border:1px solid #88c3f7;border-radius:15px;padding:4px 12px;margin:0 4px;color:#4c9ad6;font-size:12px;font-weight:700;background-color:#f5f9fe}.w2ui-grid .w2ui-grid-toolbar .w2ui-grid-searches>span>span{font-size:9px;position:relative;top:-1px;left:2px}.w2ui-grid .w2ui-grid-toolbar .w2ui-grid-searches .grid-search-line{border-left:1px solid #ececec;width:11px;height:22px;margin-left:7px;margin-top:1px}.w2ui-grid .w2ui-grid-toolbar .w2ui-grid-searches .w2ui-grid-search-logic{border:1px solid #c8c9ca!important;color:#676767!important}.w2ui-grid .w2ui-grid-toolbar .w2ui-grid-searches button.grid-search-btn{margin:0 3px;padding:0;height:24px;font-size:11px}.w2ui-grid .w2ui-grid-toolbar .w2ui-grid-searches button.grid-search-btn.btn-remove{min-width:26px;position:absolute;left:calc(100% - 35px)}.w2ui-grid .w2ui-grid-toolbar .w2ui-grid-searches .grid-search-count{background-color:#4cb1fd;border-radius:10px;color:#fff;padding:0 6px 1px 6px;font-size:11px!important;position:relative!important;top:0!important}.w2ui-grid .w2ui-grid-toolbar .w2ui-grid-searches .grid-search-list li{padding:5px}.w2ui-grid .w2ui-grid-toolbar .w2ui-grid-searches .grid-search-list input{position:relative;top:2px;left:-3px}.w2ui-grid .w2ui-grid-save-search{padding-top:30px;text-align:center}.w2ui-grid .w2ui-grid-save-search span{width:280px;display:inline-block;text-align:left;padding-bottom:4px}.w2ui-grid .w2ui-grid-save-search .search-name{width:280px!important}.w2ui-grid .w2ui-grid-body{position:absolute;overflow:hidden;padding:0;background-color:#fff;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.w2ui-grid .w2ui-grid-body input,.w2ui-grid .w2ui-grid-body select,.w2ui-grid .w2ui-grid-body textarea{-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;-o-user-select:text;user-select:text}.w2ui-grid .w2ui-grid-body .w2ui-grid-columns,.w2ui-grid .w2ui-grid-body .w2ui-grid-fcolumns{overflow:hidden;position:absolute;left:0;top:0;right:0;box-shadow:0 1px 4px #efefef;height:auto}.w2ui-grid .w2ui-grid-body .w2ui-grid-columns table,.w2ui-grid .w2ui-grid-body .w2ui-grid-fcolumns table{height:auto}.w2ui-grid .w2ui-grid-body .w2ui-grid-columns .w2ui-resizer,.w2ui-grid .w2ui-grid-body .w2ui-grid-fcolumns .w2ui-resizer{position:absolute;z-index:1000;display:block;background-image:none;background-color:rgba(0,0,0,0);padding:0;margin:0;width:6px;height:12px;cursor:ew-resize}.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords,.w2ui-grid .w2ui-grid-body .w2ui-grid-records{position:absolute;left:0;right:0;top:0;bottom:0}.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords table tr.w2ui-odd,.w2ui-grid .w2ui-grid-body .w2ui-grid-records table tr.w2ui-odd{color:inherit;background-color:#fff;border-bottom:1px solid #f5f5f5}.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords table tr.w2ui-odd.w2ui-record-hover,.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords table tr.w2ui-odd:hover,.w2ui-grid .w2ui-grid-body .w2ui-grid-records table tr.w2ui-odd.w2ui-record-hover,.w2ui-grid .w2ui-grid-body .w2ui-grid-records table tr.w2ui-odd:hover{color:inherit;background-color:#f3f3f3}.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords table tr.w2ui-odd.w2ui-empty-record:hover,.w2ui-grid .w2ui-grid-body .w2ui-grid-records table tr.w2ui-odd.w2ui-empty-record:hover{background-color:#fff}.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords table tr.w2ui-even,.w2ui-grid .w2ui-grid-body .w2ui-grid-records table tr.w2ui-even{color:inherit;background-color:#fbfbfb;border-bottom:1px dotted #f5f5f5}.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords table tr.w2ui-even.w2ui-record-hover,.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords table tr.w2ui-even:hover,.w2ui-grid .w2ui-grid-body .w2ui-grid-records table tr.w2ui-even.w2ui-record-hover,.w2ui-grid .w2ui-grid-body .w2ui-grid-records table tr.w2ui-even:hover{color:inherit;background-color:#f3f3f3}.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords table tr.w2ui-even.w2ui-empty-record:hover,.w2ui-grid .w2ui-grid-body .w2ui-grid-records table tr.w2ui-even.w2ui-empty-record:hover{background-color:#fbfbfb}.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords table tr td.w2ui-selected,.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords table tr.w2ui-selected,.w2ui-grid .w2ui-grid-body .w2ui-grid-records table tr td.w2ui-selected,.w2ui-grid .w2ui-grid-body .w2ui-grid-records table tr.w2ui-selected{color:#000!important;background-color:#d9eaff!important;border-bottom:1px solid transparent}.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords table tr td.w2ui-inactive,.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords table tr.w2ui-inactive,.w2ui-grid .w2ui-grid-body .w2ui-grid-records table tr td.w2ui-inactive,.w2ui-grid .w2ui-grid-body .w2ui-grid-records table tr.w2ui-inactive{background-color:#e8edf5!important}.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords .w2ui-expanded1,.w2ui-grid .w2ui-grid-body .w2ui-grid-records .w2ui-expanded1{height:0;border-bottom:1px solid #b2bac0}.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords .w2ui-expanded1>div,.w2ui-grid .w2ui-grid-body .w2ui-grid-records .w2ui-expanded1>div{height:0;border:0;transition:height .3s,opacity .3s}.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords .w2ui-expanded2,.w2ui-grid .w2ui-grid-body .w2ui-grid-records .w2ui-expanded2{height:0;border-radius:0;border-bottom:1px solid #b2bac0}.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords .w2ui-expanded2>div,.w2ui-grid .w2ui-grid-body .w2ui-grid-records .w2ui-expanded2>div{height:0;border:0;transition:height .3s,opacity .3s}.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords .w2ui-load-more,.w2ui-grid .w2ui-grid-body .w2ui-grid-records .w2ui-load-more{cursor:pointer;background-color:rgba(233,237,243,.5);border-right:1px solid #f1f1f1;height:43px}.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords .w2ui-load-more>div,.w2ui-grid .w2ui-grid-body .w2ui-grid-records .w2ui-load-more>div{text-align:center;color:#777;background-color:rgba(233,237,243,.5);padding:10px 0 15px 0;height:43px;border-top:1px dashed #d6d5d7;border-bottom:1px dashed #d6d5d7;font-size:12px}.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords .w2ui-load-more>div:hover,.w2ui-grid .w2ui-grid-body .w2ui-grid-records .w2ui-load-more>div:hover{color:#438ba2;background-color:#f3f3f3}.w2ui-grid .w2ui-grid-body .w2ui-grid-frecords .w2ui-reoder-empty,.w2ui-grid .w2ui-grid-body .w2ui-grid-records .w2ui-reoder-empty{background-color:#eee;border-bottom:1px dashed #aaa;border-top:1px dashed #aaa}.w2ui-grid .w2ui-grid-body table{border-spacing:0;border-collapse:collapse;table-layout:fixed;width:1px}.w2ui-grid .w2ui-grid-body table .w2ui-head{margin:0;padding:0;border-right:1px solid #dcdcdc;border-bottom:1px solid #dcdcdc;color:#656164;background-image:linear-gradient(#fff,#f9f9f9)}.w2ui-grid .w2ui-grid-body table .w2ui-head>div{padding:7px 6px;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;position:relative}.w2ui-grid .w2ui-grid-body table td{border-right:1px solid #f1f1f1;border-bottom:0 solid #d6d5d7;cursor:default;overflow:hidden}.w2ui-grid .w2ui-grid-body table td.w2ui-soft-hidden,.w2ui-grid .w2ui-grid-body table td.w2ui-soft-span{border-right-color:transparent}.w2ui-grid .w2ui-grid-body table td.w2ui-grid-data{margin:0;padding:0}.w2ui-grid .w2ui-grid-body table td.w2ui-grid-data .w2ui-info{position:relative;top:2px;left:-1px;font-size:13px;color:#8d99a7;cursor:pointer;width:18px;display:inline-block;margin-right:3px;text-align:center}.w2ui-grid .w2ui-grid-body table td.w2ui-grid-data .w2ui-clipboard-copy{float:right;margin-top:-15px;width:20px;height:16px;padding:0;text-align:center;cursor:pointer;font-size:13px;color:#8d98a7}.w2ui-grid .w2ui-grid-body table td.w2ui-grid-data .w2ui-clipboard-copy:hover{color:#545961}.w2ui-grid .w2ui-grid-body table td.w2ui-grid-data>div{padding:5px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.w2ui-grid .w2ui-grid-body table td.w2ui-grid-data>div.flexible-record{height:auto;overflow:visible;white-space:normal}.w2ui-grid .w2ui-grid-body table td.w2ui-grid-data .w2ui-show-children{width:16px;height:10px;display:inline-block;position:relative;top:-1px;cursor:pointer}.w2ui-grid .w2ui-grid-body table td:last-child{border-right:0}.w2ui-grid .w2ui-grid-body table td:last-child div{text-overflow:clip}.w2ui-grid .w2ui-grid-body table .w2ui-col-number{width:34px;color:#777;background-color:rgba(233,237,243,.5)}.w2ui-grid .w2ui-grid-body table .w2ui-col-number div{padding:0 7px 0 3px;text-align:right}.w2ui-grid .w2ui-grid-body table .w2ui-col-number.w2ui-head{cursor:pointer}.w2ui-grid .w2ui-grid-body table .w2ui-col-select{width:26px}.w2ui-grid .w2ui-grid-body table .w2ui-col-select div{padding:0 0;text-align:center;overflow:hidden}.w2ui-grid .w2ui-grid-body table .w2ui-col-select div input[type=checkbox]{margin-top:3px;margin-bottom:0;position:relative}.w2ui-grid .w2ui-grid-body table .w2ui-col-expand{width:26px}.w2ui-grid .w2ui-grid-body table .w2ui-col-expand div{padding:0 0;text-align:center;font-weight:700}.w2ui-grid .w2ui-grid-body table .w2ui-col-order{width:26px}.w2ui-grid .w2ui-grid-body table .w2ui-col-order.w2ui-grid-data div{cursor:move;height:18px;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxyZWN0IHN0eWxlPSJmaWxsOiAjYWFhOyIgeD0iMCIgeT0iNCIgaGVpZ2h0PSIzIiB3aWR0aD0iMTYiPjwvcmVjdD4KICA8cmVjdCBzdHlsZT0iZmlsbDogI2FhYTsiIHg9IjAiIHk9IjkiIGhlaWdodD0iMyIgd2lkdGg9IjE2Ij48L3JlY3Q+Cjwvc3ZnPg==);background-position:5px 2px;background-size:14px 12px;background-repeat:no-repeat}.w2ui-grid .w2ui-grid-body table .w2ui-col-selected{background-color:#d1d1d1!important}.w2ui-grid .w2ui-grid-body table .w2ui-row-selected{background-color:#e2e2e2!important}.w2ui-grid .w2ui-grid-body .w2ui-intersection-marker{position:absolute;top:0;left:0;margin-left:-5px;height:26px;width:10px}.w2ui-grid .w2ui-grid-body .w2ui-intersection-marker.left{left:0;margin-left:-5px}.w2ui-grid .w2ui-grid-body .w2ui-intersection-marker.right{right:0;margin-right:5px}.w2ui-grid .w2ui-grid-body .w2ui-intersection-marker .top-marker{position:absolute;top:0;height:0;width:0;border-top:5px solid #72b2ff;border-left:5px solid transparent;border-right:5px solid transparent}.w2ui-grid .w2ui-grid-body .w2ui-intersection-marker .bottom-marker{position:absolute;bottom:0;height:0;width:0;border-bottom:5px solid #72b2ff;border-left:5px solid transparent;border-right:5px solid transparent}.w2ui-grid .w2ui-grid-body div.w2ui-col-header{height:auto!important;width:100%;overflow:hidden;padding-right:10px!important}.w2ui-grid .w2ui-grid-body div.w2ui-col-header>div.w2ui-sort-up{border:4px solid transparent;border-bottom:5px solid #8d99a7;margin-top:-2px;margin-right:-7px;float:right}.w2ui-grid .w2ui-grid-body div.w2ui-col-header>div.w2ui-sort-down{border:4px solid transparent;border-top:5px solid #8d99a7;margin-top:2px;margin-right:-7px;float:right}.w2ui-grid .w2ui-grid-body .w2ui-col-group{text-align:center}.w2ui-grid .w2ui-grid-body .w2ui-grid-scroll1{position:absolute;left:0;bottom:0;border-top:1px solid #ddd;border-right:1px solid #ddd;background-color:#fafafa}.w2ui-grid .w2ui-grid-empty-msg{position:absolute;top:27px;left:0;right:0;bottom:0;background-color:rgba(255,255,255,.65)}.w2ui-grid .w2ui-grid-empty-msg>div{position:absolute;left:0;right:0;top:45%;transform:translateY(-45%);text-align:center;font-size:13px;color:#666}.w2ui-grid .w2ui-changed{background:url(data:image/gif;base64,R0lGODlhCgAKAJEAALAABf///wAAAAAAACH5BAEAAAIALAAAAAAKAAoAAAIPlI8Hy8mbxIsSUnup3rQAADs=) no-repeat top right}.w2ui-grid .w2ui-edit-box{position:absolute;z-index:1001;border:1.5px solid #6299da;pointer-events:auto;padding:2px!important;margin:0!important;background-color:#fff}.w2ui-grid .w2ui-edit-box .w2ui-editable div.w2ui-input{outline:0;padding:.5px 1.5px!important}.w2ui-grid .w2ui-edit-box .w2ui-editable input{top:-2px!important;padding:1.5px!important}.w2ui-grid .w2ui-editable{overflow:hidden;height:100%!important;margin:0!important;padding:3.5px 2px 2px 2px!important}.w2ui-grid .w2ui-editable input{top:-1px;border:0!important;border-radius:0!important;border-color:transparent!important;padding:3px!important;display:inline-block;width:100%!important;height:100%!important;pointer-events:auto!important}.w2ui-grid .w2ui-editable div.w2ui-input{position:relative;top:-.5px;border:0 transparent;border-radius:0!important;margin:0!important;padding:5px 3px!important;display:inline-block;width:100%!important;height:100%!important;pointer-events:auto!important;background-color:#fff;white-space:pre;overflow:hidden;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;-o-user-select:text;user-select:text}.w2ui-grid .w2ui-grid-summary{position:absolute;border-top:1px solid #dcdcdc;box-shadow:0 -1px 4px #f0eeee}.w2ui-grid .w2ui-grid-summary table{color:inherit}.w2ui-grid .w2ui-grid-summary table .w2ui-odd{background-color:#fff}.w2ui-grid .w2ui-grid-summary table .w2ui-even{background-color:#fbfbfb}.w2ui-grid .w2ui-grid-footer{position:absolute;bottom:0;left:0;right:0;margin:0;padding:0;text-align:center;font-size:11px;height:24px;overflow:hidden;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;-o-user-select:text;user-select:text;box-shadow:0 -1px 4px #f5f5f5;color:#444;background-color:#f8f8f8;border-top:1px solid #e4e4e4;border-bottom-left-radius:2px;border-bottom-right-radius:2px}.w2ui-grid .w2ui-grid-footer .w2ui-footer-left{float:left;padding-top:5px;padding-left:5px}.w2ui-grid .w2ui-grid-footer .w2ui-footer-right{float:right;padding-top:5px;padding-right:5px}.w2ui-grid .w2ui-grid-footer .w2ui-footer-center{padding:2px;text-align:center}.w2ui-grid .w2ui-grid-footer .w2ui-footer-center .w2ui-footer-nav{width:110px;margin:0 auto;padding:0;text-align:center}.w2ui-grid .w2ui-grid-footer .w2ui-footer-center .w2ui-footer-nav input[type=text]{padding:1px 2px 2px 2px;border-radius:3px;width:40px;text-align:center}.w2ui-grid .w2ui-grid-footer .w2ui-footer-center .w2ui-footer-nav a.w2ui-footer-btn{display:inline-block;border-radius:3px;cursor:pointer;font-size:11px;line-height:16px;padding:1px 5px;width:30px;height:18px;margin-top:-1px;color:#000;background-color:transparent}.w2ui-grid .w2ui-grid-footer .w2ui-footer-center .w2ui-footer-nav a.w2ui-footer-btn:hover{color:#000;background-color:#aec8ff}.w2ui-grid .w2ui-grid-focus-input{position:absolute;top:0;right:0;z-index:-1;opacity:0;overflow:hidden;padding:0;margin:0;width:1px;height:1px;resize:none;border:0}.w2ui-ss .w2ui-grid-body .w2ui-grid-records table tr td.w2ui-selected{background-color:#eef4fe!important}.w2ui-ss .w2ui-grid-body .w2ui-grid-records table tr td.w2ui-inactive{background-color:#f4f6f9!important}.w2ui-ss .w2ui-grid-body .w2ui-grid-records table td{border-right-width:1px;border-bottom:1px solid #efefef}.w2ui-ss .w2ui-grid-body .w2ui-grid-records table tr.w2ui-even,.w2ui-ss .w2ui-grid-body .w2ui-grid-records table tr.w2ui-even:hover,.w2ui-ss .w2ui-grid-body .w2ui-grid-records table tr.w2ui-odd,.w2ui-ss .w2ui-grid-body .w2ui-grid-records table tr.w2ui-odd:hover{background-color:inherit}.w2ui-ss .w2ui-grid-body .w2ui-grid-records table tr:first-child td{border-top:0;border-bottom:0}.w2ui-ss .w2ui-grid-body .w2ui-grid-frecords table tr td.w2ui-selected{background-color:#eef4fe!important}.w2ui-ss .w2ui-grid-body .w2ui-grid-frecords table tr td.w2ui-inactive{background-color:#f4f6f9!important}.w2ui-ss .w2ui-grid-body .w2ui-grid-frecords table td{border-right-width:1px;border-bottom:1px solid #efefef}.w2ui-ss .w2ui-grid-body .w2ui-grid-frecords table tr.w2ui-even,.w2ui-ss .w2ui-grid-body .w2ui-grid-frecords table tr.w2ui-even:hover,.w2ui-ss .w2ui-grid-body .w2ui-grid-frecords table tr.w2ui-odd,.w2ui-ss .w2ui-grid-body .w2ui-grid-frecords table tr.w2ui-odd:hover{background-color:inherit}.w2ui-ss .w2ui-grid-body .w2ui-grid-frecords table tr:first-child td{border-bottom:0}.w2ui-ss .w2ui-grid-body .w2ui-selection{position:absolute;z-index:1000;border:1.5px solid #6299da;pointer-events:none}.w2ui-ss .w2ui-grid-body .w2ui-selection .w2ui-selection-resizer{cursor:crosshair;position:absolute;bottom:0;right:0;width:6px;height:6px;margin-right:-3px;margin-bottom:-3px;background-color:#457fc2;border:.5px solid #fff;outline:1px solid #fff;pointer-events:auto}.w2ui-ss .w2ui-grid-body .w2ui-selection.w2ui-inactive{border:1.5px solid #c0c2c5}.w2ui-ss .w2ui-grid-body .w2ui-selection.w2ui-inactive .w2ui-selection-resizer{background-color:#b0b0b0}.w2ui-ss .w2ui-grid-body .w2ui-soft-range{position:absolute;pointer-events:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.w2ui-ss .w2ui-grid-body .w2ui-changed{background:inherit}.w2ui-ss .w2ui-grid-body .w2ui-editable input{outline:0!important}.w2ui-info-bubble table{font-family:OpenSans;font-size:12px;color:#fff;text-shadow:1px 1px solid #999}.w2ui-info-bubble table tr td:first-child{white-space:nowrap;padding:2px;padding-right:10px;color:#ddd;vertical-align:top}.w2ui-info-bubble table tr td:last-child{white-space:pre;padding:2px}.w2ui-overlay .w2ui-grid-search-suggest{border-top-left-radius:5px;border-top-right-radius:5px;padding:10px;background-color:#fff;border-bottom:1px solid #e6e6e6;color:#444}.w2ui-overlay .w2ui-grid-search-single{font-size:12px;padding-top:10px}.w2ui-overlay .w2ui-grid-search-single .field{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;border:1px solid #a9b6c2;border-radius:4px;padding:4px 12px;margin:0 2px;color:#4295d4;background-color:#f5f9fe}.w2ui-overlay .w2ui-grid-search-single .operator{display:inline-block;color:#000;background-color:#e6e6e6;border-radius:4px;margin:0 4px;padding:6px 10px}.w2ui-overlay .w2ui-grid-search-single .value{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;border:1px solid #a9b6c2;border-radius:4px;margin:0 2px;padding:4px 12px}.w2ui-overlay .w2ui-grid-search-single .buttons{text-align:left;padding:15px 10px 10px 0}.w2ui-overlay .w2ui-grid-search-advanced{text-align:left;padding:0;background-color:#fff;text-shadow:none;border:1px solid #cdcdd8;box-shadow:0 3px 14px 1px #e8e8e8}.w2ui-overlay .w2ui-grid-search-advanced .search-title{padding:20px 0 9px 20px;font-size:17px;font-weight:700;color:#555}.w2ui-overlay .w2ui-grid-search-advanced .search-title .search-logic{float:right;padding-right:10px}.w2ui-overlay .w2ui-grid-search-advanced table{color:#5f5f5f;font-size:13px;padding:12px 4px 0 4px}.w2ui-overlay .w2ui-grid-search-advanced table td{padding:4px;min-height:40px}.w2ui-overlay .w2ui-grid-search-advanced table td.caption{text-align:right;padding-right:5px;padding-left:20px}.w2ui-overlay .w2ui-grid-search-advanced table td.operator{text-align:left;padding:5px}.w2ui-overlay .w2ui-grid-search-advanced table td.operator select{width:100%;color:#000}.w2ui-overlay .w2ui-grid-search-advanced table td.value{padding-right:5px;padding-left:5px}.w2ui-overlay .w2ui-grid-search-advanced table td.value input[type=text]{border-radius:3px;padding:5px;margin-right:3px;height:28px}.w2ui-overlay .w2ui-grid-search-advanced table td.value select{padding:0 20px 5px 5px;margin-right:3px;height:28px}.w2ui-overlay .w2ui-grid-search-advanced table td.actions:nth-child(1){padding:25px 10px 10px 10px;text-align:left}.w2ui-overlay .w2ui-grid-search-advanced table td.actions:nth-child(2){padding:25px 10px 10px 10px;text-align:right;background-color:#fff}.w2ui-grid-skip{width:50px;margin:-6px 3px;padding:3px!important}.w2ui-popup{position:fixed;z-index:1600;overflow:hidden;font-family:OpenSans;border-radius:6px;padding:0;margin:0;border:1px solid #777;background-color:#fafafa;box-shadow:0 0 25px #555}.w2ui-popup,.w2ui-popup *{box-sizing:border-box}.w2ui-popup.w2ui-anim-open{opacity:0;transform:scale(.8)}.w2ui-popup.w2ui-anim-close{opacity:0;transform:scale(.9)}.w2ui-popup .w2ui-popup-title-btns{float:right;margin:10px 10px 0 0;font-size:17px}.w2ui-popup .w2ui-popup-title-btns .w2ui-popup-button{float:right;width:25px;height:23px;cursor:pointer;color:#888;margin:0 0 0 2px;z-index:301;position:relative}.w2ui-popup .w2ui-popup-title-btns .w2ui-popup-button span.w2ui-icon{width:24px;height:23px}.w2ui-popup .w2ui-popup-title-btns .w2ui-popup-button.w2ui-popup-close:hover{color:#222}.w2ui-popup .w2ui-popup-title-btns .w2ui-popup-button.w2ui-popup-max:hover{color:#222}.w2ui-popup .w2ui-popup-title{padding:10px;border-radius:6px 6px 0 0;background-color:#fff;border-bottom:1px solid #eee;position:absolute;overflow:hidden;height:42px;left:0;right:0;top:0;text-overflow:ellipsis;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;cursor:move;font-size:17px;color:#555;z-index:300}.w2ui-popup .w2ui-box,.w2ui-popup .w2ui-box-temp{position:absolute;left:0;right:0;top:42px;bottom:58px;z-index:100}.w2ui-popup .w2ui-popup-body{font-size:12px;line-height:130%;padding:0 7px 7px 7px;color:#000;background-color:#fafafa;position:absolute;overflow:auto;width:100%;height:100%}.w2ui-popup .w2ui-popup-buttons{font-size:11px;padding:14px;border-radius:0 0 6px 6px;border-top:1px solid #eee;background-color:#fff;text-align:center;position:absolute;overflow:hidden;height:56px;left:0;right:0;bottom:0;z-index:200}.w2ui-popup .w2ui-popup-no-title{border-top-left-radius:6px;border-top-right-radius:6px;top:0}.w2ui-popup .w2ui-popup-no-buttons{border-bottom-left-radius:6px;border-bottom-right-radius:6px;bottom:0}.w2ui-popup .w2ui-msg-text{font-size:14px;line-height:1.5}.w2ui-popup .w2ui-prompt{font-size:12px;padding:0 10px}.w2ui-popup .w2ui-prompt.textarea{margin-top:20px}.w2ui-popup .w2ui-prompt>div{margin-bottom:5px}.w2ui-popup .w2ui-prompt>label{margin-right:5px}.w2ui-popup .w2ui-prompt input{width:230px}.w2ui-popup .w2ui-prompt textarea{width:100%;height:50px;resize:none}.w2ui-message{font-size:12px;position:absolute;z-index:250;background-color:#fcfcfc;border:1px solid #999;box-shadow:0 0 15px #aaa;box-sizing:border-box;border-top:0;border-radius:0 0 6px 6px;overflow:auto}.w2ui-message .w2ui-msg-text{font-size:14px;line-height:1.5}.w2ui-message .w2ui-message-body{position:absolute;top:0;bottom:45px;left:0;right:0;overflow:auto}.w2ui-message .w2ui-message-body .w2ui-centered{line-height:1.5}.w2ui-message .w2ui-message-buttons{position:absolute;height:45px;bottom:0;left:0;right:0;border-top:1px solid #efefef;background-color:#fff;text-align:center;padding:8px}.w2ui-sidebar{position:relative;cursor:default;overflow:hidden;background-color:#fbfbfb;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;-o-box-sizing:border-box;box-sizing:border-box}.w2ui-sidebar *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;-o-box-sizing:border-box;box-sizing:border-box}.w2ui-sidebar>div{position:absolute;overflow:hidden}.w2ui-sidebar .w2ui-sidebar-top{position:absolute;z-index:2;top:0;left:0;right:0}.w2ui-sidebar .w2ui-sidebar-top .w2ui-flat-left,.w2ui-sidebar .w2ui-sidebar-top .w2ui-flat-right{position:absolute;right:2px;top:2px;height:24px;padding:5px;border-radius:2px;background-size:16px 12px;background-position:center center;background-repeat:no-repeat;background-color:#fbfbfb}.w2ui-sidebar .w2ui-sidebar-top .w2ui-flat-left:hover,.w2ui-sidebar .w2ui-sidebar-top .w2ui-flat-right:hover{background-color:#f1f1f1}.w2ui-sidebar .w2ui-sidebar-top .w2ui-flat-left{left:auto;width:25px;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAQAAADZc7J/AAAAzklEQVR4Ae2THRDEMBCFzy1ucatb3eJ2uhi3uNUtbnGrW9zi1rOdNzdvdl7nDpvYt/9/r7+/51myZZf/zXkD2iMHHRSb0x3oskwMieK05PwEXqP4ExSL0wp0ROao2OOuMPOMdUL6XU1/oGLcFWb+NqyTd2W/P/2qTr9h+nFXhOkHXRHiNyjrgp/U/V+WaQcaNY13zZI0A1JvcVqAnrGDTdtDtZUHjHIJhxxVLN0iqXgCP1l/7h8U9kc6abyJ4/eNWPpGdBv+XdUK0K8cnvcBly2rDr7C1HQAAAAASUVORK5CYII=)}.w2ui-sidebar .w2ui-sidebar-top .w2ui-flat-right{left:2px;width:auto;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAQAAADZc7J/AAAAz0lEQVR4Ae2UG7TGMBCEr1vd4la3uMUtuli3utWtbnGLW9zi9l/bDMzJG7u12cfJfLunf1+UEC9Bv0vVQwJ8hjRCaZafflb1C9RQf4OD0gSDE+i+PiJAabFhQc1y1AYYsJGLY3lgxM17uWPO56yPiFDqVPWgRtpIHSd1zPnwkBsdI58OlNwx4fP2X0TgfMTOoHSdKOXkpyNvEyQh7ul+4swxJSTQuwNDxz68l/ukVNbu0Neen5Z+KvzWxBAqHds349uPFJ/jVOrPjxUq++OLf+20q5+noXo0AAAAAElFTkSuQmCC)}.w2ui-sidebar .w2ui-sidebar-bottom{position:absolute;z-index:2;bottom:0;left:0;right:0}.w2ui-sidebar .w2ui-sidebar-body{position:absolute;z-index:1;overflow:auto;top:0;bottom:0;left:0;right:0;padding:2px 0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none}.w2ui-sidebar .w2ui-sidebar-body .w2ui-node{position:relative;border-radius:4px;margin:0 3px;padding:1px 0;border:1px solid transparent}.w2ui-sidebar .w2ui-sidebar-body .w2ui-node .w2ui-node-text{color:#000;text-shadow:0 0 0 #fff;pointer-events:none}.w2ui-sidebar .w2ui-sidebar-body .w2ui-node .w2ui-node-text:hover{color:inherit}.w2ui-sidebar .w2ui-sidebar-body .w2ui-node .w2ui-node-image>span{color:#737485}.w2ui-sidebar .w2ui-sidebar-body .w2ui-node .w2ui-node-handle{display:inline-block;padding:0;margin:0;height:100%;position:absolute}.w2ui-sidebar .w2ui-sidebar-body .w2ui-node:hover{background-color:#f1f1f1}.w2ui-sidebar .w2ui-sidebar-body .w2ui-node .w2ui-node-image{width:22px;text-align:center;pointer-events:none}.w2ui-sidebar .w2ui-sidebar-body .w2ui-node .w2ui-node-image>span{color:#888}.w2ui-sidebar .w2ui-sidebar-body .w2ui-node.w2ui-disabled,.w2ui-sidebar .w2ui-sidebar-body .w2ui-node.w2ui-disabled:hover{background:0 0}.w2ui-sidebar .w2ui-sidebar-body .w2ui-node.w2ui-disabled .w2ui-node-image,.w2ui-sidebar .w2ui-sidebar-body .w2ui-node.w2ui-disabled .w2ui-node-image>span,.w2ui-sidebar .w2ui-sidebar-body .w2ui-node.w2ui-disabled .w2ui-node-text,.w2ui-sidebar .w2ui-sidebar-body .w2ui-node.w2ui-disabled:hover .w2ui-node-image,.w2ui-sidebar .w2ui-sidebar-body .w2ui-node.w2ui-disabled:hover .w2ui-node-image>span,.w2ui-sidebar .w2ui-sidebar-body .w2ui-node.w2ui-disabled:hover .w2ui-node-text{opacity:.4;color:#000;text-shadow:0 0 0 #fff}.w2ui-sidebar .w2ui-sidebar-body .w2ui-node button,.w2ui-sidebar .w2ui-sidebar-body .w2ui-node input{pointer-events:auto}.w2ui-sidebar .w2ui-sidebar-body .w2ui-selected,.w2ui-sidebar .w2ui-sidebar-body .w2ui-selected:hover{background-color:#f3f5ff;position:relative;border:1px solid #dee1ff}.w2ui-sidebar .w2ui-sidebar-body .w2ui-selected .w2ui-node-image,.w2ui-sidebar .w2ui-sidebar-body .w2ui-selected .w2ui-node-image>span,.w2ui-sidebar .w2ui-sidebar-body .w2ui-selected .w2ui-node-text,.w2ui-sidebar .w2ui-sidebar-body .w2ui-selected:hover .w2ui-node-image,.w2ui-sidebar .w2ui-sidebar-body .w2ui-selected:hover .w2ui-node-image>span,.w2ui-sidebar .w2ui-sidebar-body .w2ui-selected:hover .w2ui-node-text{color:inherit;text-shadow:0 0 0 #fff}.w2ui-sidebar .w2ui-sidebar-body .w2ui-selected:before{content:"";border:1px dashed transparent;border-radius:4px;position:absolute;top:-1px;bottom:-1px;left:-1px;right:-1px;pointer-events:none}.w2ui-sidebar .w2ui-sidebar-body .w2ui-node-text{white-space:nowrap;padding:5px 0 5px 3px;margin:1px 0 1px 22px;position:relative;z-index:1;font-size:12px}.w2ui-sidebar .w2ui-sidebar-body .w2ui-node-group{white-space:nowrap;overflow:hidden;padding:10px 0 10px 10px;margin:0;cursor:default;color:#6a5e88;background-color:transparent}.w2ui-sidebar .w2ui-sidebar-body .w2ui-node-group :nth-child(1){margin-right:10px;float:right;color:transparent}.w2ui-sidebar .w2ui-sidebar-body .w2ui-node-group :nth-child(2){font-weight:400;text-transform:uppercase}.w2ui-sidebar .w2ui-sidebar-body .w2ui-node-sub{overflow:hidden}.w2ui-sidebar .w2ui-sidebar-body .w2ui-node-data{padding:2px}.w2ui-sidebar .w2ui-sidebar-body .w2ui-node-data .w2ui-node-image{padding:3px 0 0 0;float:left}.w2ui-sidebar .w2ui-sidebar-body .w2ui-node-data .w2ui-node-image>span{font-size:16px;color:#737485;text-shadow:0 0 0 #fff}.w2ui-sidebar .w2ui-sidebar-body .w2ui-node-data .w2ui-node-image.w2ui-icon{margin-top:3px}.w2ui-sidebar .w2ui-sidebar-body .w2ui-node-data .w2ui-node-count{float:right;border:1px solid #f6fcf4;border-radius:20px;width:auto;padding:2px 7px;margin:3px 4px -2px 0;background-color:#f2f8f0;color:#666;box-shadow:0 0 2px #474545;text-shadow:1px 1px 0 #fff;position:relative;z-index:2}.w2ui-sidebar .w2ui-sidebar-body .w2ui-node-data .w2ui-collapsed,.w2ui-sidebar .w2ui-sidebar-body .w2ui-node-data .w2ui-expanded{float:right;width:auto;height:18px;position:relative;z-index:2}.w2ui-sidebar .w2ui-sidebar-body .w2ui-node-data .w2ui-collapsed span,.w2ui-sidebar .w2ui-sidebar-body .w2ui-node-data .w2ui-expanded span{border-color:transparent;background-color:transparent;box-shadow:none;padding:2px 5px;border-radius:0}.w2ui-sidebar .w2ui-sidebar-body .w2ui-node-data .w2ui-collapsed span:after,.w2ui-sidebar .w2ui-sidebar-body .w2ui-node-data .w2ui-expanded span:after{content:"";position:absolute;border-left:5px solid grey;border-top:5px solid transparent;border-bottom:5px solid transparent;transform:rotateZ(-90deg);pointer-events:none;margin-left:-4px;margin-top:7px}.w2ui-sidebar .w2ui-sidebar-body .w2ui-node-data .w2ui-collapsed span:hover,.w2ui-sidebar .w2ui-sidebar-body .w2ui-node-data .w2ui-expanded span:hover{border-color:transparent;background-color:transparent}.w2ui-sidebar .w2ui-sidebar-body .w2ui-node-data .w2ui-collapsed span:after{transform:rotateZ(90deg)}.w2ui-sidebar .w2ui-sidebar-body .w2ui-node-flat{display:block;padding:2px 0;text-align:center}.w2ui-sidebar .w2ui-sidebar-body .w2ui-node-flat .w2ui-node-image{float:none;text-align:center;width:auto;padding:1px 0}.w2ui-sidebar .w2ui-sidebar-body .w2ui-node-flat .w2ui-node-image>span{font-size:16px;color:#737485;text-shadow:0 0 0 #fff}.w2ui-sidebar .w2ui-sidebar-body .w2ui-node-flat .w2ui-node-image.w2ui-icon{width:21px}.w2ui-tabs{cursor:default;overflow:hidden;position:relative;background-color:#fff;min-height:28px;padding:0;margin:0}.w2ui-tabs .w2ui-tabs-line{position:absolute;left:0;right:0;bottom:0;z-index:1;border:0;height:1px;background-color:#e2e2e2}.w2ui-tabs .w2ui-scroll-left,.w2ui-tabs .w2ui-scroll-right{z-index:30;display:flex}.w2ui-tabs .w2ui-scroll-wrapper{display:flex;flex-direction:row;flex-wrap:nowrap;justify-content:flex-start;align-content:flex-start;padding:0 2px}.w2ui-tabs .w2ui-scroll-wrapper .w2ui-tab{height:28px;position:relative;z-index:20;padding:7px 20px 4px 20px;text-align:center;color:#000;background-color:transparent;border:2px solid transparent;white-space:nowrap;margin:0 1px;border-radius:0;cursor:default;user-select:none}.w2ui-tabs .w2ui-scroll-wrapper .w2ui-tab.active{color:#0175ff;background-color:transparent;border:2px solid transparent;border-bottom:2px solid #0175ff;margin-bottom:0}.w2ui-tabs .w2ui-scroll-wrapper .w2ui-tab:hover{background-color:#dfe1e630}.w2ui-tabs .w2ui-scroll-wrapper .w2ui-tab.moving{color:inherit;background-color:#eee;border:2px solid transparent;border-radius:0;margin-bottom:0}.w2ui-tabs .w2ui-scroll-wrapper .w2ui-tab.closable{padding:6px 28px 6px 20px}.w2ui-tabs .w2ui-scroll-wrapper .w2ui-tab .w2ui-tab-close{position:absolute;right:3px;top:5px;color:#555;float:right;margin-top:-3px;padding:2px 4px;width:20px;height:20px;opacity:.6;border:0;border-top:3px solid transparent;border-radius:3px}.w2ui-tabs .w2ui-scroll-wrapper .w2ui-tab .w2ui-tab-close:hover{background-color:#f9e7e7;color:red;opacity:1;font-weight:700}.w2ui-tabs .w2ui-scroll-wrapper .w2ui-tab .w2ui-tab-close:active{background-color:#ffd1d1}.w2ui-tabs .w2ui-scroll-wrapper .w2ui-tab .w2ui-tab-close:before{position:relative;top:-2px;left:0;color:inherit;text-shadow:inherit;content:'x'}.w2ui-tabs .w2ui-scroll-wrapper .w2ui-tabs-right{padding:8px 2px;width:100%;text-align:right;white-space:nowrap}.w2ui-tabs.w2ui-tabs-up .w2ui-tabs-line{top:0;bottom:auto}.w2ui-tabs.w2ui-tabs-up .w2ui-scroll-wrapper .w2ui-tab{border:2px solid transparent;border-top:2px solid transparent;border-radius:0 0 4px 4px}.w2ui-tabs.w2ui-tabs-up .w2ui-scroll-wrapper .w2ui-tab.active{border:2px solid transparent;border-top:2px solid #0175ff;margin-top:0}.w2ui-toolbar{background-color:#f5f5f5;user-select:none;padding:2px}.w2ui-toolbar .w2ui-tb-line{overflow:hidden;position:relative;min-height:28px;padding:2px;margin:0}.w2ui-toolbar .disabled{opacity:.3}.w2ui-toolbar .w2ui-scroll-left,.w2ui-toolbar .w2ui-scroll-right{z-index:30;display:flex}.w2ui-toolbar .w2ui-tb-line:nth-child(2),.w2ui-toolbar .w2ui-tb-line:nth-child(3),.w2ui-toolbar .w2ui-tb-line:nth-child(4){border-top:1px solid #e7e7e7;padding-top:4px;margin:0}.w2ui-toolbar .w2ui-scroll-wrapper{display:flex;flex-direction:row;flex-wrap:nowrap;justify-content:flex-start;align-content:flex-start;padding:0}.w2ui-toolbar .w2ui-scroll-wrapper .w2ui-tb-button{position:relative;z-index:20;height:30px;min-width:30px;padding:2px;border:1px solid transparent;border-radius:4px;background-color:transparent;white-space:nowrap;margin:0 1px;cursor:default;user-select:none;flex-shrink:0}.w2ui-toolbar .w2ui-scroll-wrapper .w2ui-tb-button .w2ui-tb-icon{float:left;width:22px;margin:4px 0 0 1px;text-align:center}.w2ui-toolbar .w2ui-scroll-wrapper .w2ui-tb-button .w2ui-tb-icon>span{font-size:15px;color:#8d99a7}.w2ui-toolbar .w2ui-scroll-wrapper .w2ui-tb-button .w2ui-tb-text{margin-left:20px;color:#000;padding:5px}.w2ui-toolbar .w2ui-scroll-wrapper .w2ui-tb-button .w2ui-tb-text .w2ui-tb-color-box{display:inline-block;height:13px;width:13px;margin:0 -1px -2px 0;border-radius:1px;border:1px solid #fff;box-shadow:0 0 1px #555}.w2ui-toolbar .w2ui-scroll-wrapper .w2ui-tb-button .w2ui-tb-text .w2ui-tb-count{padding:0 0 0 4px}.w2ui-toolbar .w2ui-scroll-wrapper .w2ui-tb-button .w2ui-tb-text .w2ui-tb-count>span{border:1px solid #f6fcf4;border-radius:11px;width:auto;height:18px;padding:0 6px 1px 6px;background-color:#f2f8f0;color:#666;box-shadow:0 0 2px #474545;text-shadow:1px 1px 0 #fff}.w2ui-toolbar .w2ui-scroll-wrapper .w2ui-tb-button .w2ui-tb-text .w2ui-tb-down{display:inline-block;width:10px}.w2ui-toolbar .w2ui-scroll-wrapper .w2ui-tb-button .w2ui-tb-text .w2ui-tb-down>span{display:inline-block;position:relative;top:3px;left:3px;border:4px solid transparent;border-top:5px solid #8d99a7}.w2ui-toolbar .w2ui-scroll-wrapper .w2ui-tb-button.over{border:1px solid transparent;background-color:#eaeaed}.w2ui-toolbar .w2ui-scroll-wrapper .w2ui-tb-button.over .w2ui-tb-text{color:#000}.w2ui-toolbar .w2ui-scroll-wrapper .w2ui-tb-button.checked{border:1px solid #d2d2d2;background-color:#fff}.w2ui-toolbar .w2ui-scroll-wrapper .w2ui-tb-button.checked .w2ui-tb-text{color:#000}.w2ui-toolbar .w2ui-scroll-wrapper .w2ui-tb-button.down{border:1px solid #ccc;background-color:#eaeaed}.w2ui-toolbar .w2ui-scroll-wrapper .w2ui-tb-button.down .w2ui-tb-text{color:#666}.w2ui-toolbar .w2ui-scroll-wrapper .w2ui-tb-button.no-icon .w2ui-tb-text{margin-left:0}.w2ui-toolbar .w2ui-scroll-wrapper .w2ui-tb-right{width:100%;text-align:right;white-space:nowrap}.w2ui-toolbar .w2ui-scroll-wrapper .w2ui-tb-break{background-image:linear-gradient(to bottom,rgba(153,153,153,.1) 0,#999 40%,#999 60%,rgba(153,153,153,.1) 100%);width:1px;height:24px;padding:0;margin:3px 6px}.w2ui-toolbar .w2ui-scroll-wrapper .w2ui-tb-html{white-space:nowrap}.w2ui-toolbar .w2ui-scroll-wrapper .w2ui-tb-spacer{width:100%} \ No newline at end of file diff --git a/src/resources/w2ui-2.0/w2ui-2.0.min.js b/src/resources/w2ui-2.0/w2ui-2.0.min.js new file mode 100644 index 0000000..07dcd20 --- /dev/null +++ b/src/resources/w2ui-2.0/w2ui-2.0.min.js @@ -0,0 +1,486 @@ +/* w2ui 2.0.0 (4/26/2023, 10:40:17 AM) (c) http://w2ui.com, vitmalina@gmail.com */ +class w2event{constructor(e,t){Object.assign(this,{type:t.type??null,detail:t,owner:e,target:t.target??null,phase:t.phase??"before",object:t.object??null,execute:null,isStopped:!1,isCancelled:!1,onComplete:null,listeners:[]}),delete t.type,delete t.target,delete t.object,this.complete=new Promise((e,t)=>{this._resolve=e,this._reject=t}),this.complete.catch(()=>{})}finish(e){e&&w2utils.extend(this.detail,e),this.phase="after",this.owner.trigger.call(this.owner,this)}done(e){this.listeners.push(e)}preventDefault(){this._reject(),this.isCancelled=!0}stopPropagation(){this.isStopped=!0}}class w2base{constructor(e){if(this.activeEvents=[],this.listeners=[],void 0!==e){if(!w2utils.checkName(e))return;w2ui[e]=this}this.debug=!1}on(e,r){return(e="string"==typeof e?e.split(/[,\s]+/):[e]).forEach(e=>{var t,i,s,l="string"==typeof e?e:e.type+":"+e.execute+"."+e.scope;"string"==typeof e&&([i,t]=e.split("."),[i,s]=i.replace(":complete",":after").replace(":done",":after").split(":"),e={type:i,execute:s??"before",scope:t}),(e=w2utils.extend({type:null,execute:"before",onComplete:null},e)).type?r?(Array.isArray(this.listeners)||(this.listeners=[]),this.listeners.push({name:l,edata:e,handler:r}),this.debug&&console.log("w2base: add event",{name:l,edata:e,handler:r})):console.log("ERROR: You must specify event handler function when calling .on() method of "+this.name):console.log("ERROR: You must specify event type when calling .on() method of "+this.name)}),this}off(e,r){return(e="string"==typeof e?e.split(/[,\s]+/):[e]).forEach(i=>{var e,t,s,l="string"==typeof i?i:i.type+":"+i.execute+"."+i.scope;if("string"==typeof i&&([t,e]=i.split("."),[t,s]=t.replace(":complete",":after").replace(":done",":after").split(":"),i={type:t||"*",execute:s||"",scope:e||""}),(i=w2utils.extend({type:null,execute:null,onComplete:null},i)).type||i.scope){r=r||null;let t=0;this.listeners=this.listeners.filter(e=>"*"!==i.type&&i.type!==e.edata.type||""!==i.execute&&i.execute!==e.edata.execute||""!==i.scope&&i.scope!==e.edata.scope||null!=i.handler&&i.handler!==e.edata.handler||(t++,!1)),this.debug&&console.log(`w2base: remove event (${t})`,{name:l,edata:i,handler:r})}else console.log("ERROR: You must specify event type when calling .off() method of "+this.name)}),this}trigger(e,i){if(1==arguments.length?i=e:(i.type=e,i.target=i.target??this),w2utils.isPlainObject(i)&&"after"==i.phase){if(!(i=this.activeEvents.find(e=>e.type==i.type&&e.target==i.target)))return void console.log(`ERROR: Cannot find even handler for "${i.type}" on "${i.target}".`);console.log("NOTICE: This syntax \"edata.trigger({ phase: 'after' })\" is outdated. Use edata.finish() instead.")}else i instanceof w2event||(i=new w2event(this,i),this.activeEvents.push(i));let s,t,l;Array.isArray(this.listeners)||(this.listeners=[]),this.debug&&console.log(`w2base: trigger "${i.type}:${i.phase}"`,i);for(let e=this.listeners.length-1;0<=e;e--){let t=this.listeners[e];if(!(null==t||t.edata.type!==i.type&&"*"!==t.edata.type||t.edata.target!==i.target&&null!=t.edata.target||t.edata.execute!==i.phase&&"*"!==t.edata.execute&&"*"!==t.edata.phase)&&(Object.keys(t.edata).forEach(e=>{null==i[e]&&null!=t.edata[e]&&(i[e]=t.edata[e])}),s=[],l=new RegExp(/\((.*?)\)/).exec(String(t.handler).split("=>")[0]),2===(s=l?l[1].split(/\s*,\s*/):s).length?(t.handler.call(this,i.target,i),this.debug&&console.log(" - call (old)",t.handler)):(t.handler.call(this,i),this.debug&&console.log(" - call",t.handler)),!0===i.isStopped||!0===i.stop))return i}e="on"+i.type.substr(0,1).toUpperCase()+i.type.substr(1);if(!("before"===i.phase&&"function"==typeof this[e]&&(t=this[e],s=[],l=new RegExp(/\((.*?)\)/).exec(String(t).split("=>")[0]),2===(s=l?l[1].split(/\s*,\s*/):s).length?(t.call(this,i.target,i),this.debug&&console.log(" - call: on[Event] (old)",t)):(t.call(this,i),this.debug&&console.log(" - call: on[Event]",t)),!0===i.isStopped||!0===i.stop)||null!=i.object&&"before"===i.phase&&"function"==typeof i.object[e]&&(t=i.object[e],s=[],l=new RegExp(/\((.*?)\)/).exec(String(t).split("=>")[0]),2===(s=l?l[1].split(/\s*,\s*/):s).length?(t.call(this,i.target,i),this.debug&&console.log(" - call: edata.object (old)",t)):(t.call(this,i),this.debug&&console.log(" - call: edata.object",t)),!0===i.isStopped||!0===i.stop)||"after"!==i.phase)){"function"==typeof i.onComplete&&i.onComplete.call(this,i);for(let e=0;e{this[t]=e})}static _fragment(e){let i=document.createElement("template");return i.innerHTML=e,i.content.childNodes.forEach(e=>{var t=Query._scriptConvert(e);t!=e&&i.content.replaceChild(t,e)}),i.content}static _scriptConvert(e){let t=e=>{var t=e.ownerDocument.createElement("script"),i=(t.text=e.text,e.attributes);for(let e=0;e{e.parentNode.replaceChild(t(e),e)}),e}static _fixProp(e){var t={cellpadding:"cellPadding",cellspacing:"cellSpacing",class:"className",colspan:"colSpan",contenteditable:"contentEditable",for:"htmlFor",frameborder:"frameBorder",maxlength:"maxLength",readonly:"readOnly",rowspan:"rowSpan",tabindex:"tabIndex",usemap:"useMap"};return t[e]||e}_insert(l,i){let r=[],n=this.length;if(!(n<1)){let e=this;if("string"==typeof i)this.each(e=>{var t=Query._fragment(i);r.push(...t.childNodes),e[l](t)});else if(i instanceof Query){let s=1==n;i.each(i=>{this.each(e=>{var t=s?i:i.cloneNode(!0);r.push(t),e[l](t),Query._scriptConvert(t)})}),s||i.remove()}else{if(!(i instanceof Node))throw new Error(`Incorrect argument for "${l}(html)". It expects one string argument.`);this.each(e=>{var t=1===n?i:Query._fragment(i.outerHTML);r.push(...1===n?[i]:t.childNodes),e[l](t)}),1{e=Array.from(e.querySelectorAll(t));0{(e===t||"string"==typeof t&&e.matches&&e.matches(t)||"function"==typeof t&&t(e))&&i.push(e)}),new Query(i,this.context,this)}next(){let t=[];return this.each(e=>{e=e.nextElementSibling;e&&t.push(e)}),new Query(t,this.context,this)}prev(){let t=[];return this.each(e=>{e=e.previousElementSibling;e&&t.push(e)}),new Query(t,this.context,this)}shadow(e){let t=[];this.each(e=>{e.shadowRoot&&t.push(e.shadowRoot)});var i=new Query(t,this.context,this);return e?i.find(e):i}closest(t){let i=[];return this.each(e=>{e=e.closest(t);e&&i.push(e)}),new Query(i,this.context,this)}host(t){let i=[],s=e=>e.parentNode?s(e.parentNode):e,l=e=>{e=s(e);i.push(e.host||e),e.host&&t&&l(e.host)};return this.each(e=>{l(e)}),new Query(i,this.context,this)}parent(e){return this.parents(e,!0)}parents(e,t){let i=[],s=e=>{if(-1==i.indexOf(e)&&i.push(e),!t&&e.parentNode)return s(e.parentNode)};this.each(e=>{e.parentNode&&s(e.parentNode)});var l=new Query(i,this.context,this);return e?l.filter(e):l}add(e){e=e instanceof Query?e.nodes:Array.isArray(e)?e:[e];return new Query(this.nodes.concat(e),this.context,this)}each(i){return this.nodes.forEach((e,t)=>{i(e,t,this)}),this}append(e){return this._insert("append",e)}prepend(e){return this._insert("prepend",e)}after(e){return this._insert("after",e)}before(e){return this._insert("before",e)}replace(e){return this._insert("replaceWith",e)}remove(){return this.each(e=>{e.remove()}),this}css(e,t){let s=e;var i,l=arguments.length;return 0===l||1===l&&"string"==typeof e?this[0]?(l=this[0].style,"string"==typeof e?(i=l.getPropertyPriority(e),l.getPropertyValue(e)+(i?"!"+i:"")):Object.fromEntries(this[0].style.cssText.split(";").filter(e=>!!e).map(e=>e.split(":").map(e=>e.trim())))):void 0:("object"!=typeof e&&((s={})[e]=t),this.each((i,e)=>{Object.keys(s).forEach(e=>{var t=String(s[e]).toLowerCase().includes("!important")?"important":"";i.style.setProperty(e,String(s[e]).replace(/\!important/i,""),t)})}),this)}addClass(e){return this.toggleClass(e,!0),this}removeClass(e){return this.toggleClass(e,!1),this}toggleClass(t,s){return"string"==typeof t&&(t=t.split(/[,\s]+/)),this.each(i=>{let e=t;(e=null==e&&!1===s?Array.from(i.classList):e).forEach(t=>{if(""!==t){let e=null!=s?s?"add":"remove":"toggle";i.classList[e](t)}})}),this}hasClass(e){if(null==(e="string"==typeof e?e.split(/[,\s]+/):e)&&0{i=i||e.every(e=>Array.from(t.classList??[]).includes(e))}),i}on(e,s,l){"function"==typeof s&&(l=s,s=void 0);let r;return s?.delegate&&(r=s.delegate,delete s.delegate),(e=e.split(/[,\s]+/)).forEach(e=>{let[t,i]=String(e).toLowerCase().split(".");if(r){let i=l;l=e=>{var t=query(e.target).parents(r);0{this._save(e,"events",[{event:t,scope:i,callback:l,options:s}]),e.addEventListener(t,l,s)})}),this}off(e,t,r){return"function"==typeof t&&(r=t,t=void 0),(e=(e??"").split(/[,\s]+/)).forEach(e=>{let[s,l]=String(e).toLowerCase().split(".");this.each(t=>{if(Array.isArray(t._mQuery?.events))for(let e=t._mQuery.events.length-1;0<=e;e--){var i=t._mQuery.events[e];null==l||""===l?i.event!=s&&""!==s||i.callback!=r&&null!=r||(t.removeEventListener(i.event,i.callback,i.options),t._mQuery.events.splice(e,1)):i.event!=s&&""!==s||i.scope!=l||(t.removeEventListener(i.event,i.callback,i.options),t._mQuery.events.splice(e,1))}})}),this}trigger(e,t){let i;return i=e instanceof Event||e instanceof CustomEvent?e:new(["click","dblclick","mousedown","mouseup","mousemove"].includes(e)?MouseEvent:["keydown","keyup","keypress"].includes(e)?KeyboardEvent:Event)(e,t),this.each(e=>{e.dispatchEvent(i)}),this}attr(t,i){if(void 0===i&&"string"==typeof t)return this[0]?this[0].getAttribute(t):void 0;{let e={};return"object"==typeof t?e=t:e[t]=i,this.each(i=>{Object.entries(e).forEach(([e,t])=>{i.setAttribute(e,t)})}),this}}removeAttr(){return this.each(t=>{Array.from(arguments).forEach(e=>{t.removeAttribute(e)})}),this}prop(t,i){if(void 0===i&&"string"==typeof t)return this[0]?this[0][t]:void 0;{let e={};return"object"==typeof t?e=t:e[t]=i,this.each(i=>{Object.entries(e).forEach(([e,t])=>{e=Query._fixProp(e);i[e]=t,"innerHTML"==e&&Query._scriptConvert(i)})}),this}}removeProp(){return this.each(t=>{Array.from(arguments).forEach(e=>{delete t[Query._fixProp(e)]})}),this}data(i,t){if(i instanceof Object)Object.entries(i).forEach(e=>{this.data(e[0],e[1])});else{if(i&&-1!=i.indexOf("-")&&console.error(`Key "${i}" contains "-" (dash). Dashes are not allowed in property names. Use camelCase instead.`),!(arguments.length<2))return this.each(e=>{null!=t?e.dataset[i]=t instanceof Object?JSON.stringify(t):t:delete e.dataset[i]}),this;if(this[0]){let t=Object.assign({},this[0].dataset);return Object.keys(t).forEach(e=>{if(t[e].startsWith("[")||t[e].startsWith("{"))try{t[e]=JSON.parse(t[e])}catch(e){}}),i?t[i]:t}}}removeData(e){return"string"==typeof e&&(e=e.split(/[,\s]+/)),this.each(t=>{e.forEach(e=>{delete t.dataset[e]})}),this}show(){return this.toggle(!0)}hide(){return this.toggle(!1)}toggle(r){return this.each(e=>{var t,i=e.style.display,s=getComputedStyle(e).display,l="none"==i||"none"==s;!l||null!=r&&!0!==r||(t=e instanceof HTMLTableRowElement?"table-row":e instanceof HTMLTableCellElement?"table-cell":"block",e.style.display=e._mQuery?.prevDisplay??(i==s&&"none"!=s?"":t),this._save(e,"prevDisplay",null)),l||null!=r&&!1!==r||("none"!=s&&this._save(e,"prevDisplay",s),e.style.setProperty("display","none"))})}empty(){return this.html("")}html(e){return this.prop("innerHTML",e)}text(e){return this.prop("textContent",e)}val(e){return this.prop("value",e)}change(){return this.trigger("change")}click(){return this.trigger("click")}}let query=function(e,t){if("function"!=typeof e)return new Query(e,t);"complete"==document.readyState?e():window.addEventListener("load",e)},w2ui=(query.html=e=>{e=Query._fragment(e);return query(e.children,e)},query.version=Query.version,{});class Utils{constructor(){this.version="2.0.x",this.tmp={},this.settings=this.extend({},{dataType:"HTTPJSON",dateStartYear:1950,dateEndYear:2030,macButtonOrder:!1,warnNoPhrase:!1},w2locale,{phrases:null}),this.i18nCompare=Intl.Collator().compare,this.hasLocalStorage=function(){var e="w2ui_test";try{return localStorage.setItem(e,e),localStorage.removeItem(e),!0}catch(e){return!1}}(),this.isMac=/Mac/i.test(navigator.platform),this.isMobile=/(iphone|ipod|ipad|mobile|android)/i.test(navigator.userAgent),this.isIOS=/(iphone|ipod|ipad)/i.test(navigator.platform),this.isAndroid=/(android)/i.test(navigator.userAgent),this.isSafari=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),this.formatters={number(e,t){return 20'+w2utils.formatDate(i,t)+""},datetime(e,t){if(""===t&&(t=w2utils.settings.datetimeFormat),null==e||0===e||""===e)return"";let i=w2utils.isDateTime(e,t,!0);return''+w2utils.formatDateTime(i,t)+""},time(e,t){if(""===t&&(t=w2utils.settings.timeFormat),null==e||0===e||""===e)return"";let i=w2utils.isDateTime(e,t="h24"===(t="h12"===t?"hh:mi pm":t)?"h24:mi":t,!0);return''+w2utils.formatTime(e,t)+""},timestamp(e,t){if(""===t&&(t=w2utils.settings.datetimeFormat),null==e||0===e||""===e)return"";let i=w2utils.isDateTime(e,t,!0);return(i=!1===i?w2utils.isDate(e,t,!0):i).toString?i.toString():""},gmt(e,t){if(""===t&&(t=w2utils.settings.datetimeFormat),null==e||0===e||""===e)return"";let i=w2utils.isDateTime(e,t,!0);return(i=!1===i?w2utils.isDate(e,t,!0):i).toUTCString?i.toUTCString():""},age(e,t){if(null==e||0===e||""===e)return"";let i=w2utils.isDateTime(e,null,!0);return''+w2utils.age(e)+(t?" "+t:"")+""},interval(e,t){return null==e||0===e||""===e?"":w2utils.interval(e)+(t?" "+t:"")},toggle(e,t){return e?"Yes":""},password(t,e){let i="";for(let e=0;ei||!this.isInt(e[0])||2'+(r=l==e?this.lang("Yesterday"):r)+""}formatSize(e){var t;return this.isFloat(e)&&""!==e?0===(e=parseFloat(e))?0:(t=parseInt(Math.floor(Math.log(e)/Math.log(1024))),(Math.floor(e/Math.pow(1024,t)*10)/10).toFixed(0===t?0:1)+" "+(["Bt","KB","MB","GB","TB","PB","EB","ZB"][t]||"??")):""}formatNumber(e,t,i){return null==e||""===e||"object"==typeof e?"":(i={minimumFractionDigits:parseInt(t),maximumFractionDigits:parseInt(t),useGrouping:!!i},(null==t||t<0)&&(i.minimumFractionDigits=0,i.maximumFractionDigits=20),parseFloat(e).toLocaleString(this.settings.locale,i))}formatDate(e,t){if(t=t||this.settings.dateFormat,""===e||null==e||"object"==typeof e&&!e.getMonth)return"";let i=new Date(e);var s,l;return this.isInt(e)&&(i=new Date(Number(e))),"Invalid Date"===String(i)?"":(e=i.getFullYear(),s=i.getMonth(),l=i.getDate(),t.toLowerCase().replace("month",this.settings.fullmonths[s]).replace("mon",this.settings.shortmonths[s]).replace(/yyyy/g,("000"+e).slice(-4)).replace(/yyy/g,("000"+e).slice(-4)).replace(/yy/g,("0"+e).slice(-2)).replace(/(^|[^a-z$])y/g,"$1"+e).replace(/mm/g,("0"+(s+1)).slice(-2)).replace(/dd/g,("0"+l).slice(-2)).replace(/th/g,1==l?"st":"th").replace(/th/g,2==l?"nd":"th").replace(/th/g,3==l?"rd":"th").replace(/(^|[^a-z$])m/g,"$1"+(s+1)).replace(/(^|[^a-z$])d/g,"$1"+l))}formatTime(e,t){if(t=t||this.settings.timeFormat,""===e||null==e||"object"==typeof e&&!e.getMonth)return"";let i=new Date(e);if(this.isInt(e)&&(i=new Date(Number(e))),this.isTime(e)&&(e=this.isTime(e,!0),(i=new Date).setHours(e.hours),i.setMinutes(e.minutes)),"Invalid Date"===String(i))return"";let s="am",l=i.getHours();e=i.getHours();let r=i.getMinutes(),n=i.getSeconds();return r<10&&(r="0"+r),n<10&&(n="0"+n),-1===t.indexOf("am")&&-1===t.indexOf("pm")||(12<=l&&(s="pm"),12{i[t]=this.stripSpaces(e)}):(i=this.extend({},i),Object.keys(i).forEach(e=>{i[e]=this.stripSpaces(i[e])}))}return i}stripTags(i){if(null!=i)switch(typeof i){case"number":break;case"string":i=String(i).replace(/<(?:[^>=]|='[^']*'|="[^"]*"|=[^'"][^\s>]*)*>/gi,"");break;case"object":Array.isArray(i)?(i=this.extend([],i)).forEach((e,t)=>{i[t]=this.stripTags(e)}):(i=this.extend({},i),Object.keys(i).forEach(e=>{i[e]=this.stripTags(i[e])}))}return i}encodeTags(i){if(null!=i)switch(typeof i){case"number":break;case"string":i=String(i).replace(/&/g,"&").replace(/>/g,">").replace(/{i[t]=this.encodeTags(e)}):(i=this.extend({},i),Object.keys(i).forEach(e=>{i[e]=this.encodeTags(i[e])}))}return i}decodeTags(i){if(null!=i)switch(typeof i){case"number":break;case"string":i=String(i).replace(/>/g,">").replace(/</g,"<").replace(/"/g,'"').replace(/&/g,"&");break;case"object":Array.isArray(i)?(i=this.extend([],i)).forEach((e,t)=>{i[t]=this.decodeTags(e)}):(i=this.extend({},i),Object.keys(i).forEach(e=>{i[e]=this.decodeTags(i[e])}))}return i}escapeId(e){return""===e||null==e?"":(e+"").replace(/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,(e,t)=>t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e)}unescapeId(e){return""===e||null==e?"":e.replace(/\\[\da-fA-F]{1,6}[\x20\t\r\n\f]?|\\([^\r\n\f])/g,(e,t)=>{e="0x"+e.slice(1)-65536;return t||(e<0?String.fromCharCode(65536+e):String.fromCharCode(e>>10|55296,1023&e|56320))})}base64encode(e){return btoa(e)}base64decode(e){return atob(e)}async sha256(e){e=(new TextEncoder).encode(e);return crypto.subtle.digest("SHA-256",e).then(e=>{return Array.from(new Uint8Array(e)).map(e=>e.toString(16).padStart(2,"0")).join("")})}transition(r,n,a,o){return new Promise((e,t)=>{var i=getComputedStyle(r);let s=parseInt(i.width),l=parseInt(i.height);if(r&&n){switch(r.parentNode.style.cssText+="perspective: 900px; overflow: hidden;",r.style.cssText+="; position: absolute; z-index: 1019; backface-visibility: hidden",n.style.cssText+="; position: absolute; z-index: 1020; backface-visibility: hidden",a){case"slide-left":r.style.cssText+="overflow: hidden; transform: translate3d(0, 0, 0)",n.style.cssText+="overflow: hidden; transform: translate3d("+s+"px, 0, 0)",query(n).show(),setTimeout(()=>{n.style.cssText+="transition: 0.5s; transform: translate3d(0, 0, 0)",r.style.cssText+="transition: 0.5s; transform: translate3d(-"+s+"px, 0, 0)"},1);break;case"slide-right":r.style.cssText+="overflow: hidden; transform: translate3d(0, 0, 0)",n.style.cssText+="overflow: hidden; transform: translate3d(-"+s+"px, 0, 0)",query(n).show(),setTimeout(()=>{n.style.cssText+="transition: 0.5s; transform: translate3d(0px, 0, 0)",r.style.cssText+="transition: 0.5s; transform: translate3d("+s+"px, 0, 0)"},1);break;case"slide-down":r.style.cssText+="overflow: hidden; z-index: 1; transform: translate3d(0, 0, 0)",n.style.cssText+="overflow: hidden; z-index: 0; transform: translate3d(0, 0, 0)",query(n).show(),setTimeout(()=>{n.style.cssText+="transition: 0.5s; transform: translate3d(0, 0, 0)",r.style.cssText+="transition: 0.5s; transform: translate3d(0, "+l+"px, 0)"},1);break;case"slide-up":r.style.cssText+="overflow: hidden; transform: translate3d(0, 0, 0)",n.style.cssText+="overflow: hidden; transform: translate3d(0, "+l+"px, 0)",query(n).show(),setTimeout(()=>{n.style.cssText+="transition: 0.5s; transform: translate3d(0, 0, 0)",r.style.cssText+="transition: 0.5s; transform: translate3d(0, 0, 0)"},1);break;case"flip-left":r.style.cssText+="overflow: hidden; transform: rotateY(0deg)",n.style.cssText+="overflow: hidden; transform: rotateY(-180deg)",query(n).show(),setTimeout(()=>{n.style.cssText+="transition: 0.5s; transform: rotateY(0deg)",r.style.cssText+="transition: 0.5s; transform: rotateY(180deg)"},1);break;case"flip-right":r.style.cssText+="overflow: hidden; transform: rotateY(0deg)",n.style.cssText+="overflow: hidden; transform: rotateY(180deg)",query(n).show(),setTimeout(()=>{n.style.cssText+="transition: 0.5s; transform: rotateY(0deg)",r.style.cssText+="transition: 0.5s; transform: rotateY(-180deg)"},1);break;case"flip-down":r.style.cssText+="overflow: hidden; transform: rotateX(0deg)",n.style.cssText+="overflow: hidden; transform: rotateX(180deg)",query(n).show(),setTimeout(()=>{n.style.cssText+="transition: 0.5s; transform: rotateX(0deg)",r.style.cssText+="transition: 0.5s; transform: rotateX(-180deg)"},1);break;case"flip-up":r.style.cssText+="overflow: hidden; transform: rotateX(0deg)",n.style.cssText+="overflow: hidden; transform: rotateX(-180deg)",query(n).show(),setTimeout(()=>{n.style.cssText+="transition: 0.5s; transform: rotateX(0deg)",r.style.cssText+="transition: 0.5s; transform: rotateX(180deg)"},1);break;case"pop-in":r.style.cssText+="overflow: hidden; transform: translate3d(0, 0, 0)",n.style.cssText+="overflow: hidden; transform: translate3d(0, 0, 0); transform: scale(.8); opacity: 0;",query(n).show(),setTimeout(()=>{n.style.cssText+="transition: 0.5s; transform: scale(1); opacity: 1;",r.style.cssText+="transition: 0.5s;"},1);break;case"pop-out":r.style.cssText+="overflow: hidden; transform: translate3d(0, 0, 0); transform: scale(1); opacity: 1;",n.style.cssText+="overflow: hidden; transform: translate3d(0, 0, 0); opacity: 0;",query(n).show(),setTimeout(()=>{n.style.cssText+="transition: 0.5s; opacity: 1;",r.style.cssText+="transition: 0.5s; transform: scale(1.7); opacity: 0;"},1);break;default:r.style.cssText+="overflow: hidden; transform: translate3d(0, 0, 0)",n.style.cssText+="overflow: hidden; translate3d(0, 0, 0); opacity: 0;",query(n).show(),setTimeout(()=>{n.style.cssText+="transition: 0.5s; opacity: 1;",r.style.cssText+="transition: 0.5s"},1)}setTimeout(()=>{"slide-down"===a&&(query(r).css("z-index","1019"),query(n).css("z-index","1020")),n&&query(n).css({opacity:"1"}).css({transition:"",transform:""}),r&&query(r).css({opacity:"1"}).css({transition:"",transform:""}),"function"==typeof o&&o(),e()},500)}else console.log("ERROR: Cannot do transition when one of the divs is null")})}lock(l,r={}){if(null!=l){"string"==typeof r&&(r={msg:r}),arguments[2]&&(r.spinner=arguments[2]),r=this.extend({spinner:!1},r),l?.[0]instanceof Node&&(l=Array.isArray(l)?l:l.get()),r.msg||0===r.msg||(r.msg=""),this.unlock(l);var n=query(l).get(0);let e=n.scrollWidth,t=n.scrollHeight,i=("BODY"==n.tagName&&(e
    `+'
    '),query(l).find(".w2ui-lock"));n=query(l).find(".w2ui-lock-msg"),l=(r.msg||n.css({"background-color":"transparent","background-image":"none",border:"0px","box-shadow":"none"}),!0===r.spinner&&(r.msg=`
    `+r.msg),r.msg?n.html(r.msg).css("display","block"):n.remove(),null!=r.opacity&&i.css("opacity",r.opacity),i.css({display:"block"}),r.bgColor&&i.css({"background-color":r.bgColor}),getComputedStyle(i.get(0)));let s=l.opacity??.15;i.on("mousedown",function(){"function"==typeof r.onClick?r.onClick():i.css({transition:".2s",opacity:1.5*s})}).on("mouseup",function(){"function"!=typeof r.onClick&&i.css({transition:".2s",opacity:s})}).on("mousewheel",function(e){e&&(e.stopPropagation(),e.preventDefault())})}}unlock(e,t){var i;null!=e&&(clearTimeout(e._prevUnlock),e?.[0]instanceof Node&&(e=Array.isArray(e)?e:e.get()),this.isInt(t)&&0{query(e).find(".w2ui-lock").remove()},t)):query(e).find(".w2ui-lock").remove(),query(e).find(".w2ui-lock-msg").remove())}message(r,s){let e,t,l;var i=()=>{var e=query(r?.box).find(".w2ui-message");0!=e.length&&"function"==typeof(s=e.get(0)._msg_options||{})?.close&&s.close()};let n=e=>{var t,i=e.box._msg_prevFocus;query(r.box).find(".w2ui-message").length<=1?r.owner?r.owner.unlock(r.param,150):this.unlock(r.box,150):query(r.box).find(`#w2ui-message-${r.owner?.name}-`+(e.msgIndex-1)).css("z-index",1500),i?0<(t=query(i).closest(".w2ui-message")).length?t.get(0)._msg_options.setFocus(i):i.focus():"function"==typeof r.owner?.focus&&r.owner.focus(),query(e.box).remove(),0===e.msgIndex&&(c.css("z-index",e.tmp.zIndex),query(r.box).css("overflow",e.tmp.overflow)),e.trigger&&l.finish()};if("object"!=typeof(s="string"!=typeof s&&"number"!=typeof s?s:{width:String(s).length<300?350:550,height:String(s).length<300?170:250,text:String(s)}))return void i();null!=s.text&&(s.body=`
    ${s.text}
    `),null==s.width&&(s.width=350),null==s.height&&(s.height=170),null==s.hideOn&&(s.hideOn=["esc"]),null==s.on&&(h=s,s=new w2base,w2utils.extend(s,h)),s.on("open",e=>{w2utils.bindEvents(query(s.box).find(".w2ui-eaction"),s),query(e.detail.box).find("button, input, textarea, [name=hidden-first]").off(".message").on("keydown.message",function(e){27==e.keyCode&&s.hideOn.includes("esc")&&(s.cancelAction?s.action(s.cancelAction):s.close())}),setTimeout(()=>s.setFocus(s.focus),300)}),s.off(".prom");let a={self:s,action(e){return s.on("action.prom",e),a},close(e){return s.on("close.prom",e),a},open(e){return s.on("open.prom",e),a},then(e){return s.on("open:after.prom",e),a}},o=(null==s.actions&&null==s.buttons&&null==s.html&&(s.actions={Ok(e){e.detail.self.close()}}),s.off(".buttons"),null!=s.actions&&(s.buttons="",Object.keys(s.actions).forEach(e=>{var t=s.actions[e];let i=e;"function"==typeof t&&(s.buttons+=``),"object"==typeof t&&(s.buttons+=``,i=Array.isArray(s.actions)?t.text:e),"string"==typeof t&&(s.buttons+=``,i=t),"string"==typeof i&&(i=i[0].toLowerCase()+i.substr(1).replace(/\s+/g,"")),a[i]=function(t){return s.on("action.buttons",e=>{e.detail.action[0].toLowerCase()+e.detail.action.substr(1).replace(/\s+/g,"")==i&&t(e)}),a}})),Array("html","body","buttons").forEach(e=>{s[e]=String(s[e]??"").trim()}),""===s.body&&""===s.buttons||(s.html=` +
    ${s.body||""}
    +
    ${s.buttons||""}
    + `),getComputedStyle(query(r.box).get(0)));var h=parseFloat(o.width),d=parseFloat(o.height);let u=0,c=(0h&&(s.width=h-10),s.height>d-u&&(s.height=d-10-u),s.originalWidth=s.width,s.originalHeight=s.height,parseInt(s.width)<0&&(s.width=h+s.width),parseInt(s.width)<10&&(s.width=10),parseInt(s.height)<0&&(s.height=d+s.height-u),parseInt(s.height)<10&&(s.height=10),s.originalHeight<0&&(s.height=d+s.originalHeight-u),s.originalWidth<0&&(s.width=h+2*s.originalWidth),query(r.box).find(r.after));return s.tmp||(s.tmp={zIndex:c.css("z-index"),overflow:o.overflow}),""===s.html&&""===s.body&&""===s.buttons?i():(s.msgIndex=query(r.box).find(".w2ui-message").length,0===s.msgIndex&&"function"==typeof this.lock&&(query(r.box).css("overflow","hidden"),r.owner?r.owner.lock(r.param):this.lock(r.box)),query(r.box).find(".w2ui-message").css("z-index",1390),c.css("z-index",1501),d=` +
    + + ${s.html} + +
    `,0{!0===(l=s.trigger("open",{target:this.name,box:s.box,self:s})).isCancelled?(query(r.box).find(`#w2ui-message-${r.owner?.name}-`+s.msgIndex).remove(),0===s.msgIndex&&(c.css("z-index",s.tmp.zIndex),query(r.box).css("overflow",s.tmp.overflow))):query(s.box).css({transition:"0.3s",transform:"translateY(0px)"})},0),t=setTimeout(()=>{query(r.box).find(`#w2ui-message-${r.owner?.name}-`+s.msgIndex).removeClass("animating").css({transition:"0s"}),l.finish()},300)),s.action=(e,t)=>{let i=s.actions[e];i instanceof Object&&i.onClick&&(i=i.onClick);e=s.trigger("action",{target:this.name,action:e,self:s,originalEvent:t,value:s.input?s.input.value:null});!0!==e.isCancelled&&("function"==typeof i&&i(e),e.finish())},s.close=()=>{!0!==(l=s.trigger("close",{target:"self",box:s.box,self:s})).isCancelled&&(clearTimeout(t),query(s.box).hasClass("animating")?(clearTimeout(e),n(s)):(query(s.box).addClass("w2ui-closing animating").css({transition:"0.15s",transform:"translateY(-"+s.height+"px)"}),0!==s.msgIndex&&query(r.box).find(`#w2ui-message-${r.owner?.name}-`+(s.msgIndex-1)).css("z-index",1499),e=setTimeout(()=>{n(s)},150)))},s.setFocus=e=>{var t=query(r.box).find(".w2ui-message").length-1;let s=query(r.box).find(`#w2ui-message-${r.owner?.name}-`+t),l="input, button, select, textarea, [contentEditable], .w2ui-input";(null!=e?isNaN(e)?s.find(l).filter(e).get(0):s.find(l).get(e):s.find("[name=hidden-first]").get(0))?.focus(),query(r.box).find(".w2ui-message").find(l+",[name=hidden-first],[name=hidden-last]").off(".keep-focus"),query(s).find(l+",[name=hidden-first],[name=hidden-last]").on("blur.keep-focus",function(e){setTimeout(()=>{var e=document.activeElement,t=0{if("object"==typeof i&&(i=(s=i).text),(s=s||{}).where=s.where??document.body,s.timeout=s.timeout??15e3,"function"==typeof this.tmp.notify_resolve&&(this.tmp.notify_resolve(),query(this.tmp.notify_where).find("#w2ui-notify").remove()),this.tmp.notify_resolve=t,this.tmp.notify_where=s.where,clearTimeout(this.tmp.notify_timer),i){if("object"==typeof s.actions){let t={};Object.keys(s.actions).forEach(e=>{t[e]=`${e}`}),i=this.execTemplate(i,t)}var e=` +
    +
    + ${i} + +
    +
    `;query(s.where).append(e),query(s.where).find("#w2ui-notify").find(".w2ui-notify-close").on("click",e=>{query(s.where).find("#w2ui-notify").remove(),t()}),s.actions&&query(s.where).find("#w2ui-notify .w2ui-notify-link").on("click",e=>{e=query(e.target).attr("value");s.actions[e](),query(s.where).find("#w2ui-notify").remove(),t()}),0{query(s.where).find("#w2ui-notify").remove(),t()},s.timeout))}})}confirm(e,t){w2utils.normButtons(t="string"==typeof t?{text:t}:t,{yes:"Yes",no:"No"});e=w2utils.message(e,t);return e&&e.action(e=>{e.detail.self.close()}),e}normButtons(i,s){i.actions=i.actions??{};var e=Object.keys(s);return e.forEach(t=>{var e=i["btn_"+t];e&&(s[t]={text:w2utils.lang(e.text??""),class:e.class??"",style:e.style??"",attrs:e.attrs??""},delete i["btn_"+t]),Array("text","class","style","attrs").forEach(e=>{i[t+"_"+e]&&("string"==typeof s[t]&&(s[t]={text:s[t]}),s[t][e]=i[t+"_"+e],delete i[t+"_"+e])})}),e.includes("yes")&&e.includes("no")&&(w2utils.settings.macButtonOrder?w2utils.extend(i.actions,{no:s.no,yes:s.yes}):w2utils.extend(i.actions,{yes:s.yes,no:s.no})),e.includes("ok")&&e.includes("cancel")&&(w2utils.settings.macButtonOrder?w2utils.extend(i.actions,{cancel:s.cancel,ok:s.ok}):w2utils.extend(i.actions,{ok:s.ok,cancel:s.cancel})),i}getSize(e,t){let i=0;if(0<(e=query(e)).length){e=e[0];var s=getComputedStyle(e);switch(t){case"width":i=parseFloat(s.width),"auto"===s.width&&(i=0);break;case"height":i=parseFloat(s.height),"auto"===s.height&&(i=0);break;default:i=parseFloat(s[t]??0)||0}}return i}getStrWidth(e,t){query("body").append(` +
    + ${this.encodeTags(e)} +
    `);t=query("#_tmp_width")[0].clientWidth;return query("#_tmp_width").remove(),t}execTemplate(e,i){return"string"==typeof e&&i&&"object"==typeof i?e.replace(/\${([^}]+)?}/g,function(e,t){return i[t]||t}):e}marker(e,s,l={onlyFirst:!1,wholeWord:!1}){Array.isArray(s)||(s=null!=s&&""!==s?[s]:[]);let r=l.wholeWord;query(e).each(t=>{for(var e=t,i=/\((.|\n|\r)*)\<\/span\>/gi;-1!==e.innerHTML.indexOf('{e=(e="string"!=typeof e?String(e):e).replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&").replace(/&/g,"&").replace(//g,"<");e=new RegExp((r?"\\b":"")+e+(r?"\\b":"")+"(?!([^<]+)?>)","i"+(l.onlyFirst?"":"g"));t.innerHTML=t.innerHTML.replace(e,e=>''+e+"")})})}lang(e,t){if(!e||null==this.settings.phrases||"string"!=typeof e||"<=>=".includes(e))return this.execTemplate(e,t);let i=this.settings.phrases[e];return null==i?(i=e,this.settings.warnNoPhrase&&(this.settings.missing||(this.settings.missing={}),this.settings.missing[e]="---",this.settings.phrases[e]="---",console.log(`Missing translation for "%c${e}%c", see %c w2utils.settings.phrases %c with value "---"`,"color: orange","","color: #999",""))):"---"!==i||this.settings.warnNoPhrase||(i=e),"---"===i&&(i=`---`),this.execTemplate(i,t)}locale(l,i,r){return new Promise((s,t)=>{if(Array.isArray(l)){this.settings.phrases={};let i=[],t={};l.forEach((e,t)=>{5===e.length&&(e="locale/"+e.toLowerCase()+".json",l[t]=e),i.push(this.locale(e,!0,!1))}),void Promise.allSettled(i).then(e=>{e.forEach(e=>{e.value&&(t[e.value.file]=e.value.data)}),l.forEach(e=>{this.settings=this.extend({},this.settings,t[e])}),s()})}else(l=l||"en-us")instanceof Object?this.settings=this.extend({},this.settings,w2locale,l):(5===l.length&&(l="locale/"+l.toLowerCase()+".json"),fetch(l,{method:"GET"}).then(e=>e.json()).then(e=>{!0!==r&&(this.settings=i?this.extend({},this.settings,e):this.extend({},this.settings,w2locale,{phrases:{}},e)),s({file:l,data:e})}).catch(e=>{console.log("ERROR: Cannot load locale "+l),t(e)}))})}scrollBarSize(){return this.tmp.scrollBarSize||(query("body").append(` +
    +
    1
    +
    + `),this.tmp.scrollBarSize=100-query("#_scrollbar_width > div")[0].clientWidth,query("#_scrollbar_width").remove()),this.tmp.scrollBarSize}checkName(e){return null==e?(console.log('ERROR: Property "name" is required but not supplied.'),!1):null!=w2ui[e]?(console.log(`ERROR: Object named "${e}" is already registered as w2ui.${e}.`),!1):!!this.isAlphaNumeric(e)||(console.log('ERROR: Property "name" has to be alpha-numeric (a-z, 0-9, dash and underscore).'),!1)}checkUniqueId(t,i,s,l){Array.isArray(i)||(i=[i]);let r=!0;return i.forEach(e=>{e.id===t&&(console.log(`ERROR: The item id="${t}" is not unique within the ${s} "${l}".`,i),r=!1)}),r}encodeParams(t,i=""){let s="";return Object.keys(t).forEach(e=>{""!=s&&(s+="&"),"object"==typeof t[e]?s+=this.encodeParams(t[e],i+e+(i?"]":"")+"["):s+=""+i+e+(i?"]":"")+"="+t[e]}),s}parseRoute(e){let n=[];e=e.replace(/\/\(/g,"(?:/").replace(/\+/g,"__plus__").replace(/(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?/g,(e,t,i,s,l,r)=>(n.push({name:s,optional:!!r}),t=t||"",(r?"":t)+"(?:"+(r?t:"")+(i||"")+(l||(i?"([^/.]+?)":"([^/]+?)"))+")"+(r||""))).replace(/([\/.])/g,"\\$1").replace(/__plus__/g,"(.+)").replace(/\*/g,"(.*)");return{path:new RegExp("^"+e+"$","i"),keys:n}}getCursorPosition(e){if(null==e)return null;let t=0;var i,s=e.ownerDocument||e.document,l=s.defaultView||s.parentWindow;let r;return["INPUT","TEXTAREA"].includes(e.tagName)?t=e.selectionStart:l.getSelection?0<(r=l.getSelection()).rangeCount&&((i=(l=r.getRangeAt(0)).cloneRange()).selectNodeContents(e),i.setEnd(l.endContainer,l.endOffset),t=i.toString().length):(r=s.selection)&&"Control"!==r.type&&(l=r.createRange(),(i=s.body.createTextRange()).moveToElementText(e),i.setEndPoint("EndToEnd",l),t=i.text.length),t}setCursorPosition(s,l,t){if(null!=s){var r=document.createRange();let i,e=window.getSelection();if(["INPUT","TEXTAREA"].includes(s.tagName))s.setSelectionRange(l,t??l);else{for(let t=0;t").replace(/&/g,"&").replace(/"/g,'"').replace(/ /g," "):e).length){(i=(i=s.childNodes[t]).childNodes&&0i.length&&(l=i.length),r.setStart(i,l),t?r.setEnd(i,t):r.collapse(!0),e.removeAllRanges(),e.addRange(r))}}}parseColor(e){if("string"!=typeof e)return null;let t={};if(3===(e="#"===(e=e.trim().toUpperCase())[0]?e.substr(1):e).length)t={r:parseInt(e[0]+e[0],16),g:parseInt(e[1]+e[1],16),b:parseInt(e[2]+e[2],16),a:1};else if(6===e.length)t={r:parseInt(e.substr(0,2),16),g:parseInt(e.substr(2,2),16),b:parseInt(e.substr(4,2),16),a:1};else if(8===e.length)t={r:parseInt(e.substr(0,2),16),g:parseInt(e.substr(2,2),16),b:parseInt(e.substr(4,2),16),a:Math.round(parseInt(e.substr(6,2),16)/255*100)/100};else if(4{s[t]=this.clone(e,i)}):this.isPlainObject(e)?(s={},Object.assign(s,e),i.exclude&&i.exclude.forEach(e=>{delete s[e]}),Object.keys(s).forEach(e=>{s[e]=this.clone(s[e],i),void 0===s[e]&&delete s[e]})):e instanceof Function&&!i.functions||e instanceof Node&&!i.elements||e instanceof Event&&!i.events||(s=e),s}extend(i,s){if(Array.isArray(i)){if(!Array.isArray(s))throw new Error("Arrays can be extended with arrays only");i.splice(0,i.length),s.forEach(e=>{i.push(this.clone(e))})}else{if(i instanceof Node||i instanceof Event)throw new Error("HTML elmenents and events cannot be extended");if(i&&"object"==typeof i&&null!=s){if("object"!=typeof s)throw new Error("Object can be extended with other objects only.");Object.keys(s).forEach(e=>{var t;null!=i[e]&&"object"==typeof i[e]&&null!=s[e]&&"object"==typeof s[e]?(t=this.clone(s[e]),i[e]instanceof Node||i[e]instanceof Event?i[e]=t:(Array.isArray(i[e])&&this.isPlainObject(t)&&(i[e]={}),this.extend(i[e],t))):i[e]=this.clone(s[e])})}else if(null!=s)throw new Error("Object is not extendable, only {} or [] can be extended.")}if(2{"string"==typeof e||"number"==typeof e?i[t]={id:e,text:String(e)}:null!=e?(null!=e.caption&&null==e.text&&(e.text=e.caption),null!=e.text&&null==e.id&&(e.id=e.text),null==e.text&&null!=e.id&&(e.text=e.id)):i[t]={id:null,text:"null"}}),i):"function"==typeof i?(e=i.call(this,i,e),w2utils.normMenu.call(this,e)):"object"==typeof i?Object.keys(i).map(e=>({id:e,text:i[e]})):void 0}prepareParams(i,e,t){t=t??w2utils.settings.dataType;let s=e.body;switch(t){case"HTTPJSON":s={request:s},["PUT","DELETE"].includes(e.method)&&(e.method="POST"),l();break;case"HTTP":["PUT","DELETE"].includes(e.method)&&(e.method="POST"),l();break;case"RESTFULL":["PUT","DELETE"].includes(e.method)?e.headers["Content-Type"]="application/json":l();break;case"JSON":"GET"==e.method?(s={request:s},l()):(e.headers["Content-Type"]="application/json",e.method="POST")}return e.body="string"==typeof e.body?e.body:JSON.stringify(e.body),e;function l(){Object.keys(s).forEach(e=>{let t=s[e];"object"==typeof t&&(t=JSON.stringify(t)),i.searchParams.append(e,t)}),delete e.body}}bindEvents(e,r){0!=e.length&&(e?.[0]instanceof Node&&(e=Array.isArray(e)?e:e.get()),query(e).each(s=>{let l=query(s).data();Object.keys(l).forEach(i=>{if(-1!=["click","dblclick","mouseenter","mouseleave","mouseover","mouseout","mousedown","mousemove","mouseup","contextmenu","focus","focusin","focusout","blur","input","change","keydown","keyup","keypress"].indexOf(String(i).toLowerCase())){let e=l[i],t=(e="string"==typeof e?e.split("|").map(e=>{"null"===(e="undefined"===(e="false"===(e="true"===e?!0:e)?!1:e)?void 0:e)&&(e=null);var t=["'",'"',"`"];return e="string"==typeof(e=parseFloat(e)==e?parseFloat(e):e)&&t.includes(e[0])&&t.includes(e[e.length-1])?e.substring(1,e.length-1):e}):e)[0];e=e.slice(1),query(s).off(i+".w2utils-bind").on(i+".w2utils-bind",function(i){switch(t){case"alert":alert(e[0]);break;case"stop":i.stopPropagation();break;case"prevent":i.preventDefault();break;case"stopPrevent":return i.stopPropagation(),i.preventDefault(),!1;default:if(null==r[t])throw new Error(`Cannot dispatch event as the method "${t}" does not exist.`);r[t].apply(r,e.map((e,t)=>{switch(String(e).toLowerCase()){case"event":return i;case"this":return this;default:return e}}))}})}})}))}debounce(t,i=250){let s;return(...e)=>{clearTimeout(s),s=setTimeout(()=>{t(...e)},i)}}}var w2utils=new Utils;class Dialog extends w2base{constructor(){super(),this.defaults={title:"",text:"",body:"",buttons:"",width:450,height:250,focus:null,actions:null,style:"",speed:.3,modal:!1,maximized:!1,keyboard:!0,showClose:!0,showMax:!1,transition:null,openMaximized:!1,moved:!1},this.name="popup",this.status="closed",this.onOpen=null,this.onClose=null,this.onMax=null,this.onMin=null,this.onToggle=null,this.onKeydown=null,this.onAction=null,this.onMove=null,this.tmp={},this.handleResize=e=>{this.options.moved||this.center(void 0,void 0,!0)}}open(s){let l=this;"closing"!=this.status&&!query("#w2ui-popup").hasClass("animating")||this.close(!0);var e=this.options;null!=(s=["string","number"].includes(typeof s)?w2utils.extend({title:"Notification",body:`
    ${s}
    `,actions:{Ok(){l.close()}},cancelAction:"ok"},arguments[1]??{}):s).text&&(s.body=`
    ${s.text}
    `),s=Object.assign({},this.defaults,e,{title:"",body:""},s,{maximized:!1}),this.options=s,0===query("#w2ui-popup").length&&(this.off("*"),Object.keys(this).forEach(e=>{e.startsWith("on")&&"on"!=e&&(this[e]=null)})),Object.keys(s).forEach(e=>{e.startsWith("on")&&"on"!=e&&s[e]&&(this[e]=s[e])}),s.width=parseInt(s.width),s.height=parseInt(s.height);let r,t,i;var{top:n,left:a}=this.center();let o={self:this,action(e){return l.on("action.prom",e),o},close(e){return l.on("close.prom",e),o},then(e){return l.on("open:after.prom",e),o}};if(null==s.actions||s.buttons||(s.buttons="",Object.keys(s.actions).forEach(e=>{var t=s.actions[e];let i=e;"function"==typeof t&&(s.buttons+=``),"object"==typeof t&&(s.buttons+=``,i=Array.isArray(s.actions)?t.text:e),"string"==typeof t&&(s.buttons+=``,i=t),"string"==typeof i&&(i=i[0].toLowerCase()+i.substr(1).replace(/\s+/g,"")),o[i]=function(t){return l.on("action.buttons",e=>{e.detail.action[0].toLowerCase()+e.detail.action.substr(1).replace(/\s+/g,"")==i&&t(e)}),o}})),0===query("#w2ui-popup").length){if(!0===(r=this.trigger("open",{target:"popup",present:!1})).isCancelled)return;this.status="opening",w2utils.lock(document.body,{opacity:.3,onClick:s.modal?null:()=>{this.close()}});let e="";s.showClose&&(e+=`
    + +
    `),s.showMax&&(e+=`
    + +
    `);a=` + left: ${a}px; + top: ${n}px; + width: ${parseInt(s.width)}px; + height: ${parseInt(s.height)}px; + transition: ${s.speed}s + `;t=`
    `,query("body").append(t),query("#w2ui-popup")[0]._w2popup={self:this,created:new Promise(e=>{this._promCreated=e}),opened:new Promise(e=>{this._promOpened=e}),closing:new Promise(e=>{this._promClosing=e}),closed:new Promise(e=>{this._promClosed=e})},a=`${s.title?"":"top: 0px !important;"} `+(s.buttons?"":"bottom: 0px !important;"),t=` + +
    ${e}
    +
    +
    +
    +
    +
    +
    + + `,query("#w2ui-popup").html(t),s.title&&query("#w2ui-popup .w2ui-popup-title").append(w2utils.lang(s.title)),s.buttons&&query("#w2ui-popup .w2ui-popup-buttons").append(s.buttons),s.body&&query("#w2ui-popup .w2ui-popup-body").append(s.body),setTimeout(()=>{query("#w2ui-popup").css("transition",s.speed+"s").removeClass("w2ui-anim-open"),w2utils.bindEvents("#w2ui-popup .w2ui-eaction",this),query("#w2ui-popup").find(".w2ui-popup-body").show(),this._promCreated()},1),clearTimeout(this._timer),this._timer=setTimeout(()=>{this.status="open",l.setFocus(s.focus),r.finish(),this._promOpened(),query("#w2ui-popup").removeClass("animating")},1e3*s.speed)}else{if(!0===(r=this.trigger("open",{target:"popup",present:!0})).isCancelled)return;this.status="opening",null!=e&&(e.maximized||e.width==s.width&&e.height==s.height||this.resize(s.width,s.height),s.prevSize=s.width+"px:"+s.height+"px",s.maximized=e.maximized);n=query("#w2ui-popup .w2ui-box").get(0).cloneNode(!0);query(n).removeClass("w2ui-box").addClass("w2ui-box-temp").find(".w2ui-popup-body").empty().append(s.body),query("#w2ui-popup .w2ui-box").after(n),s.buttons?(query("#w2ui-popup .w2ui-popup-buttons").show().html("").append(s.buttons),query("#w2ui-popup .w2ui-popup-body").removeClass("w2ui-popup-no-buttons"),query("#w2ui-popup .w2ui-box, #w2ui-popup .w2ui-box-temp").css("bottom","")):(query("#w2ui-popup .w2ui-popup-buttons").hide().html(""),query("#w2ui-popup .w2ui-popup-body").addClass("w2ui-popup-no-buttons"),query("#w2ui-popup .w2ui-box, #w2ui-popup .w2ui-box-temp").css("bottom","0px")),s.title?(query("#w2ui-popup .w2ui-popup-title").show().html((s.showClose?`
    + +
    `:"")+(s.showMax?`
    + +
    `:"")).append(s.title),query("#w2ui-popup .w2ui-popup-body").removeClass("w2ui-popup-no-title"),query("#w2ui-popup .w2ui-box, #w2ui-popup .w2ui-box-temp").css("top","")):(query("#w2ui-popup .w2ui-popup-title").hide().html(""),query("#w2ui-popup .w2ui-popup-body").addClass("w2ui-popup-no-title"),query("#w2ui-popup .w2ui-box, #w2ui-popup .w2ui-box-temp").css("top","0px"));let t=query("#w2ui-popup .w2ui-box")[0],i=query("#w2ui-popup .w2ui-box-temp")[0];query("#w2ui-popup").addClass("animating"),w2utils.transition(t,i,s.transition,()=>{query(t).remove(),query(i).removeClass("w2ui-box-temp").addClass("w2ui-box");var e=query(i).find(".w2ui-popup-body");1==e.length&&(e[0].style.cssText=s.style,e.show()),l.setFocus(s.focus),query("#w2ui-popup").removeClass("animating")}),this.status="open",r.finish(),w2utils.bindEvents("#w2ui-popup .w2ui-eaction",this),query("#w2ui-popup").find(".w2ui-popup-body").show()}return s.openMaximized&&this.max(),s._last_focus=document.activeElement,s.keyboard&&query(document.body).on("keydown",e=>{this.keydown(e)}),query(window).on("resize",this.handleResize),i={resizing:!1,mvMove:function(e){1==i.resizing&&(e=e||window.event,i.div_x=e.screenX-i.x,i.div_y=e.screenY-i.y,!0!==(e=l.trigger("move",{target:"popup",div_x:i.div_x,div_y:i.div_y,originalEvent:e})).isCancelled)&&(query("#w2ui-popup").css({transition:"none",transform:"translate3d("+i.div_x+"px, "+i.div_y+"px, 0px)"}),l.options.moved=!0,e.finish())},mvStop:function(e){1!=i.resizing||(e=e||window.event,l.status="open",i.div_x=e.screenX-i.x,i.div_y=e.screenY-i.y,query("#w2ui-popup").css({left:i.pos_x+i.div_x+"px",top:i.pos_y+i.div_y+"px"}).css({transition:"none",transform:"translate3d(0px, 0px, 0px)"}),i.resizing=!1,query(document.body).off(".w2ui-popup"),i.isLocked)||l.unlock()}},query("#w2ui-popup .w2ui-popup-title").on("mousedown",function(e){var t;l.options.maximized||(e=(e=e)||window.event,l.status="moving",t=query("#w2ui-popup").get(0).getBoundingClientRect(),Object.assign(i,{resizing:!0,isLocked:1==query("#w2ui-popup > .w2ui-lock").length,x:e.screenX,y:e.screenY,pos_x:t.x,pos_y:t.y}),i.isLocked||l.lock({opacity:0}),query(document.body).on("mousemove.w2ui-popup",i.mvMove).on("mouseup.w2ui-popup",i.mvStop),e.stopPropagation?e.stopPropagation():e.cancelBubble=!0,e.preventDefault&&e.preventDefault())}),o}load(s){return new Promise((i,e)=>{if(null==(s="string"==typeof s?{url:s}:s).url)console.log("ERROR: The url is not defined."),e("The url is not defined");else{this.status="loading";let[e,t]=String(s.url).split("#");e&&fetch(e).then(e=>e.text()).then(e=>{i(this.template(e,t,s))})}})}template(t,e,i={}){let s;try{s=query(t)}catch(e){s=query.html(t)}return e&&(s=s.filter("#"+e)),Object.assign(i,{width:parseInt(query(s).css("width")),height:parseInt(query(s).css("height")),title:query(s).find("[rel=title]").html(),body:query(s).find("[rel=body]").html(),buttons:query(s).find("[rel=buttons]").html(),style:query(s).find("[rel=body]").get(0).style.cssText}),this.open(i)}action(e,t){let i=this.options.actions[e];i instanceof Object&&i.onClick&&(i=i.onClick);e=this.trigger("action",{action:e,target:"popup",self:this,originalEvent:t,value:this.input?this.input.value:null});!0!==e.isCancelled&&("function"==typeof i&&i.call(this,t),e.finish())}keydown(e){var t;this.options&&!this.options.keyboard||!0!==(t=this.trigger("keydown",{target:"popup",originalEvent:e})).isCancelled&&(27===e.keyCode&&(e.preventDefault(),0==query("#w2ui-popup .w2ui-message").length)&&(this.options.cancelAction?this.action(this.options.cancelAction):this.close()),t.finish())}close(e){let t=this.trigger("close",{target:"popup"});var i;!0!==t.isCancelled&&(i=()=>{query("#w2ui-popup").remove(),this.options._last_focus&&0{e.finish()},1e3*this.options.speed+50))}max(){if(!0!==this.options.maximized){let e=this.trigger("max",{target:"popup"});var t;!0!==e.isCancelled&&(this.status="resizing",t=query("#w2ui-popup").get(0).getBoundingClientRect(),this.options.prevSize=t.width+":"+t.height,this.resize(1e4,1e4,()=>{this.status="open",this.options.maximized=!0,e.finish()}))}}min(){if(!0===this.options.maximized){var t=this.options.prevSize.split(":");let e=this.trigger("min",{target:"popup"});!0!==e.isCancelled&&(this.status="resizing",this.options.maximized=!1,this.resize(parseInt(t[0]),parseInt(t[1]),()=>{this.status="open",this.options.prevSize=null,e.finish()}))}}clear(){query("#w2ui-popup .w2ui-popup-title").html(""),query("#w2ui-popup .w2ui-popup-body").html(""),query("#w2ui-popup .w2ui-popup-buttons").html("")}reset(){this.open(this.defaults)}message(e){return w2utils.message({owner:this,box:query("#w2ui-popup").get(0),after:".w2ui-popup-title"},e)}confirm(e){return w2utils.confirm({owner:this,box:query("#w2ui-popup"),after:".w2ui-popup-title"},e)}setFocus(e){let s=query("#w2ui-popup"),l="input, button, select, textarea, [contentEditable], .w2ui-input";null!=e?(isNaN(e)?s.find(l).filter(e).get(0):s.find(l).get(e))?.focus():(e=s.find("[name=hidden-first]").get(0))&&e.focus(),query(s).find(l+",[name=hidden-first],[name=hidden-last]").off(".keep-focus").on("blur.keep-focus",function(e){setTimeout(()=>{var e=document.activeElement,t=0{s.resizeMessages()},10);setTimeout(()=>{clearInterval(a),s.resizeMessages(),"function"==typeof i&&i()},1e3*this.options.speed+50)}resizeMessages(){query("#w2ui-popup .w2ui-message").each(e=>{var t=e._msg_options,i=query("#w2ui-popup"),s=(parseInt(t.width)<10&&(t.width=10),parseInt(t.height)<10&&(t.height=10),i[0].getBoundingClientRect()),i=parseInt(i.find(".w2ui-popup-title")[0].clientHeight),l=parseInt(s.width),s=parseInt(s.height);t.width=t.originalWidth,t.width>l-10&&(t.width=l-10),t.height=t.originalHeight,t.height>s-i-5&&(t.height=s-i-5),t.originalHeight<0&&(t.height=s+t.originalHeight-i),t.originalWidth<0&&(t.width=l+2*t.originalWidth),query(e).css({left:(l-t.width)/2+"px",width:t.width+"px",height:t.height+"px"})})}}function w2alert(e,t,i){let s;t={title:w2utils.lang(t??"Notification"),body:`
    ${e}
    `,showClose:!1,actions:["Ok"],cancelAction:"ok"};return(s=0{"function"==typeof e.detail.self?.close&&e.detail.self.close(),"function"==typeof i&&i()}),s}function w2confirm(e,t,i){let s,l=e;return(l=["string","number"].includes(typeof l)?{msg:l}:l).msg&&(l.body=`
    ${l.msg}
    `,delete l.msg),w2utils.extend(l,{title:w2utils.lang(t??"Confirmation"),showClose:!1,modal:!0,cancelAction:"no"}),w2utils.normButtons(l,{yes:"Yes",no:"No"}),(s=0{"function"==typeof e.detail.self?.close&&e.detail.self.close(),"function"==typeof i&&i(e.detail.action)}),s}function w2prompt(e,t,i){let s,l=e;return(l=["string","number"].includes(typeof l)?{label:l}:l).label&&(l.focus=0,l.body=l.textarea?`
    +
    ${l.label}
    + +
    `:`
    + + +
    `),w2utils.extend(l,{title:w2utils.lang(t??"Notification"),showClose:!1,modal:!0,cancelAction:"cancel"}),w2utils.normButtons(l,{ok:"Ok",cancel:"Cancel"}),(s=0{e=e.detail.box||query("#w2ui-popup .w2ui-popup-body").get(0);w2utils.bindEvents(query(e).find("#w2prompt"),{keydown(e){27==e.keyCode&&e.stopPropagation()},change(e){var t=s.self.trigger("change",{target:"prompt",originalEvent:e});!0!==t.isCancelled&&(13==e.keyCode&&e.ctrlKey&&s.self.action("Ok",e),27==e.keyCode&&s.self.action("Cancel",e),t.finish())}}),query(e).find(".w2ui-eaction").trigger("keyup")}).on("action:after.prompt",e=>{"function"==typeof e.detail.self?.close&&e.detail.self.close(),"function"==typeof i&&i(e.detail.action)}),s}let w2popup=new Dialog;class Tooltip{static active={};constructor(){this.defaults={name:null,html:"",style:"",class:"",position:"top|bottom",align:"",anchor:null,anchorClass:"",anchorStyle:"",autoShow:!1,autoShowOn:null,autoHideOn:null,arrowSize:8,margin:0,margin:1,screenMargin:2,autoResize:!0,offsetX:0,offsetY:0,maxWidth:null,maxHeight:null,watchScroll:null,watchResize:null,hideOn:null,onThen:null,onShow:null,onHide:null,onUpdate:null,onMove:null}}static observeRemove=new MutationObserver(e=>{let t=0;Object.keys(Tooltip.active).forEach(e=>{e=Tooltip.active[e];e.displayed&&(e.anchor&&e.anchor.isConnected?t++:e.hide())}),0===t&&Tooltip.observeRemove.disconnect()});trigger(e,t){var i;if(2==arguments.length&&(i=e,(e=t).type=i),e.overlay)return e.overlay.trigger(e);console.log("ERROR: cannot find overlay where to trigger events")}get(e){return 0==arguments.length?Object.keys(Tooltip.active):!0===e?Tooltip.active:Tooltip.active[e.replace(/[\s\.#]/g,"_")]}attach(t,s){let l,r,n=this;if(0!=arguments.length){1==arguments.length&&t.anchor?t=(l=t).anchor:2===arguments.length&&"string"==typeof s?s=(l={anchor:t,html:s}).html:2===arguments.length&&null!=s&&"object"==typeof s&&(s=(l=s).html),l=w2utils.extend({},this.defaults,l||{}),!(s=!s&&l.text?l.text:s)&&l.html&&(s=l.html),delete l.anchor;let e=l.name||t.id;t!=document&&t!=document.body||(t=document.body,e="context-menu"),e||(e="noname-"+Object.keys(Tooltip.active).length,console.log("NOTICE: name property is not defined for tooltip, could lead to too many instances")),e=e.replace(/[\s\.#]/g,"_"),Tooltip.active[e]?((r=Tooltip.active[e]).prevOptions=r.options,r.options=l,r.anchor=t,r.prevOptions.html==r.options.html&&r.prevOptions.class==r.options.class&&r.prevOptions.style==r.options.style||(r.needsUpdate=!0),l=r.options):(r=new w2base,Object.assign(r,{id:"w2overlay-"+e,name:e,options:l,anchor:t,displayed:!1,tmp:{observeResize:new ResizeObserver(()=>{this.resize(r.name)})},hide(){n.hide(e)}}),Tooltip.active[e]=r),Object.keys(r.options).forEach(e=>{var t=r.options[e];e.startsWith("on")&&"function"==typeof t&&(r[e]=t,delete r.options[e])}),!0===l.autoShow&&(l.autoShowOn=l.autoShowOn??"mouseenter",l.autoHideOn=l.autoHideOn??"mouseleave",l.autoShow=!1),l.autoShowOn&&(s="autoShow-"+r.name,query(t).off("."+s).on(l.autoShowOn+"."+s,e=>{n.show(r.name),e.stopPropagation()}),delete l.autoShowOn),l.autoHideOn&&(s="autoHide-"+r.name,query(t).off("."+s).on(l.autoHideOn+"."+s,e=>{n.hide(r.name),e.stopPropagation()}),delete l.autoHideOn),r.off(".attach");let i={overlay:r,then:t=>(r.on("show:after.attach",e=>{t(e)}),i),show:t=>(r.on("show.attach",e=>{t(e)}),i),hide:t=>(r.on("hide.attach",e=>{t(e)}),i),update:t=>(r.on("update.attach",e=>{t(e)}),i),move:t=>(r.on("move.attach",e=>{t(e)}),i)};return i}}update(e,t){var i=Tooltip.active[e];i?(i.needsUpdate=!0,i.options.html=t,this.show(e)):console.log(`Tooltip "${e}" is not displayed. Cannot update it.`)}show(i){if(i instanceof HTMLElement||i instanceof Object){let e=i,t=(i instanceof HTMLElement&&((e=arguments[1]||{}).anchor=i),this.attach(e));return query(t.overlay.anchor).off(".autoShow-"+t.overlay.name).off(".autoHide-"+t.overlay.name),setTimeout(()=>{this.show(t.overlay.name),this.initControls&&this.initControls(t.overlay)},1),t}let t,r=this,n=Tooltip.active[i.replace(/[\s\.#]/g,"_")];if(n){let l=n.options;if(!n||n.displayed&&!n.needsUpdate)this.resize(n?.name);else{var s=l.position.split("|"),s=["top","bottom"].includes(s[0]);let e="both"==l.align&&s?"":"white-space: nowrap;";if(l.maxWidth&&w2utils.getStrWidth(l.html,"")>l.maxWidth&&(e="width: "+l.maxWidth+"px; white-space: inherit; overflow: auto;"),e+=" max-height: "+(l.maxHeight||window.innerHeight-40)+"px;",""!==l.html&&null!=l.html){if(n.box){if(!0===(t=this.trigger("update",{target:i,overlay:n})).isCancelled)return void(n.prevOptions&&(n.options=n.prevOptions,delete n.prevOptions));query(n.box).find(".w2ui-overlay-body").attr("style",(l.style||"")+"; "+e).removeClass().addClass("w2ui-overlay-body "+l.class).html(l.html)}else{if(!0===(t=this.trigger("show",{target:i,overlay:n})).isCancelled)return;query("body").append(``),n.box=query("#"+w2utils.escapeId(n.id))[0],n.displayed=!0;s=query(n.anchor).data("tooltipName")??[];s.push(i),query(n.anchor).data("tooltipName",s),w2utils.bindEvents(n.box,{}),n.tmp.originalCSS="",0{r.hide(n.name)},i=query(n.anchor),s="tooltip-"+n.name;query("body").off("."+s),l.hideOn.includes("doc-click")&&(["INPUT","TEXTAREA"].includes(n.anchor.tagName)&&i.off(`.${s}-doc`).on(`click.${s}-doc`,e=>{e.stopPropagation()}),query("body").on("click."+s,t));l.hideOn.includes("focus-change")&&query("body").on("focusin."+s,e=>{document.activeElement!=n.anchor&&r.hide(n.name)});["INPUT","TEXTAREA"].includes(n.anchor.tagName)&&(i.off("."+s),l.hideOn.forEach(e=>{-1==["doc-click","focus-change"].indexOf(e)&&i.on(e+"."+s,{once:!0},t)}))}{var a=document.body;let e="tooltip-"+n.name,t=a;"BODY"==a.tagName&&(t=a.ownerDocument);query(t).off("."+e).on("scroll."+e,e=>{Object.assign(n.tmp,{scrollLeft:a.scrollLeft,scrollTop:a.scrollTop}),r.resize(n.name)})}return query(n.box).show(),n.tmp.observeResize.observe(n.box),Tooltip.observeRemove.observe(document.body,{subtree:!0,childList:!0}),query(n.box).css("opacity",1).find(".w2ui-overlay-body").html(l.html),setTimeout(()=>{query(n.box).css({"pointer-events":"auto"}).data("ready","yes")},100),delete n.needsUpdate,n.box.overlay=n,t&&t.finish(),{overlay:n}}r.hide(i)}}}hide(e){let i;if(0==arguments.length)Object.keys(Tooltip.active).forEach(e=>{this.hide(e)});else if(e instanceof HTMLElement)(query(e).data("tooltipName")??[]).forEach(e=>{this.hide(e)});else if("string"==typeof e&&(e=e.replace(/[\s\.#]/g,"_"),i=Tooltip.active[e]),i&&i.box){delete Tooltip.active[e];e=this.trigger("hide",{target:e,overlay:i});if(!0!==e.isCancelled){var s="tooltip-"+i.name;i.tmp.observeResize?.disconnect(),i.options.watchScroll&&query(i.options.watchScroll).off(".w2scroll-"+i.name);let t=0;Object.keys(Tooltip.active).forEach(e=>{Tooltip.active[e].displayed&&t++}),0==t&&Tooltip.observeRemove.disconnect(),query("body").off("."+s),query(document).off("."+s),i.box.remove(),i.box=null,i.displayed=!1;var l=query(i.anchor).data("tooltipName")??[];-1!=l.indexOf(i.name)&&l.splice(l.indexOf(i.name),1),0==l.length?query(i.anchor).removeData("tooltipName"):query(i.anchor).data("tooltipName",l),i.anchor.style.cssText=i.tmp.originalCSS,query(i.anchor).off("."+s).removeClass(i.options.anchorClass),e.finish()}}}resize(i){if(0==arguments.length)Object.keys(Tooltip.active).forEach(e=>{e=Tooltip.active[e];e.displayed&&this.resize(e.name)});else{var s=Tooltip.active[i.replace(/[\s\.#]/g,"_")];let t=this.getPosition(s.name);var l=t.left+"x"+t.top;let e;s.tmp.lastPos!=l&&(e=this.trigger("move",{target:i,overlay:s,pos:t})),query(s.box).css({left:t.left+"px",top:t.top+"px"}).then(e=>{null!=t.width&&e.css("width",t.width+"px").find(".w2ui-overlay-body").css("width","100%"),null!=t.height&&e.css("height",t.height+"px").find(".w2ui-overlay-body").css("height","100%")}).find(".w2ui-overlay-body").removeClass("w2ui-arrow-right w2ui-arrow-left w2ui-arrow-top w2ui-arrow-bottom").addClass(t.arrow.class).closest(".w2ui-overlay").find("style").text(t.arrow.style),s.tmp.lastPos!=l&&e&&(s.tmp.lastPos=l,e.finish())}}getPosition(e){let g=Tooltip.active[e.replace(/[\s\.#]/g,"_")];if(g&&g.box){let t=g.options;(g.tmp.resizedY||g.tmp.resizedX)&&query(g.box).css({width:"",height:"",scroll:"auto"});var e=w2utils.scrollBarSize(),y=!(document.body.scrollWidth==document.body.clientWidth),w=!(document.body.scrollHeight==document.body.clientHeight);let i={width:window.innerWidth-(w?e:0),height:window.innerHeight-(y?e:0)};var b,v=("auto"==t.position?"top|bottom|right|left":t.position).split("|");let s=["top","bottom"].includes(v[0]),l=g.box.getBoundingClientRect(),r=g.anchor.getBoundingClientRect(),n=(g.anchor==document.body&&({x,y:_,width:q,height:C}=t.originalEvent,r={left:x-2,top:_-4,width:q,height:C,arrow:"none"}),t.arrowSize),a=("none"==r.arrow&&(n=0),{top:r.top,bottom:i.height-(r.top+r.height)-+(y?e:0),left:r.left,right:i.width-(r.left+r.width)+(w?e:0)});l.width<22&&(l.width=22),l.height<14&&(l.height=14);let o,h,d,u,c="",p={offset:0,class:"",style:`#${g.id} { --tip-size: ${n}px; }`},f={left:0,top:0},m={posX:"",x:0,posY:"",y:0};v.forEach(e=>{["top","bottom"].includes(e)&&(!c&&l.height+n/1.893m.y)&&Object.assign(m,{posY:e,y:a[e]}),["left","right"].includes(e)&&(!c&&l.width+n/1.893m.x)&&Object.assign(m,{posX:e,x:a[e]})}),c=c||(s?m.posY:m.posX),t.autoResize&&(["top","bottom"].includes(c)&&(l.height>a[c]?(u=a[c],g.tmp.resizedY=!0):g.tmp.resizedY=!1),["left","right"].includes(c))&&(l.width>a[c]?(d=a[c],g.tmp.resizedX=!0):g.tmp.resizedX=!1);var x=c;switch(p.class=r.arrow||"w2ui-arrow-"+x,x){case"top":o=r.left+(r.width-(d??l.width))/2,h=r.top-(u??l.height)-n/1.5+1;break;case"bottom":o=r.left+(r.width-(d??l.width))/2,h=r.top+r.height+n/1.25+1;break;case"left":o=r.left-(d??l.width)-n/1.2-1,h=r.top+(r.height-(u??l.height))/2;break;case"right":o=r.left+r.width+n/1.2+1,h=r.top+(r.height-(u??l.height))/2}if(s)"left"==t.align&&(f.left=r.left-o,o=r.left),"right"==t.align&&(f.left=r.left+r.width-(d??l.width)-o,o=r.left+r.width-(d??l.width)),["top","bottom"].includes(c)&&t.align.startsWith("both")&&(b=t.align.split(":")[1]??50,r.width>=b)&&(o=r.left,d=r.width),"top"==t.align&&(f.top=r.top-h,h=r.top),"bottom"==t.align&&(f.top=r.top+r.height-(u??l.height)-h,h=r.top+r.height-(u??l.height)),["left","right"].includes(c)&&t.align.startsWith("both")&&(b=t.align.split(":")[1]??50,r.height>=b)&&(h=r.top,u=r.height);{let e;(["left","right"].includes(t.align)&&r.width<(d??l.width)||["top","bottom"].includes(t.align)&&r.height<(u??l.height))&&(e=!0);var _="right"==c?n:t.screenMargin,q="bottom"==c?n:t.screenMargin,C=i.width-(d??l.width)-("left"==c?n:t.screenMargin),y=i.height-(u??l.height)-("top"==c?n:t.screenMargin)+3;(["top","bottom"].includes(c)||t.autoResize)&&(o<_&&(e=!0,f.left-=o,o=_),o>C)&&(e=!0,f.left-=o-C,o+=C-o);(["left","right"].includes(c)||t.autoResize)&&(hy)&&(e=!0,f.top-=h-y,h+=y-h);e&&(_=s?"left":"top",C=s?"width":"height",p.offset=-f[_],q=l[C]/2-n,Math.abs(p.offset)>q+n&&(p.class=""),Math.abs(p.offset)>q&&(p.offset=p.offset<0?-q:q),p.style=w2utils.stripSpaces(`#${g.id} .w2ui-overlay-body:after, + #${g.id} .w2ui-overlay-body:before { + --tip-size: ${n}px; + margin-${_}: ${p.offset}px; + }`))}w="top"==c?-t.margin:"bottom"==c?t.margin:0,e="left"==c?-t.margin:"right"==c?t.margin:0;return h=Math.floor(100*(h+parseFloat(t.offsetY)+parseFloat(w)))/100,{left:o=Math.floor(100*(o+parseFloat(t.offsetX)+parseFloat(e)))/100,top:h,arrow:p,adjust:f,width:d,height:u,pos:c}}}}class ColorTooltip extends Tooltip{constructor(){super(),this.palette=[["000000","333333","555555","777777","888888","999999","AAAAAA","CCCCCC","DDDDDD","EEEEEE","F7F7F7","FFFFFF"],["FF011B","FF9838","FFC300","FFFD59","86FF14","14FF7A","2EFFFC","2693FF","006CE7","9B24F4","FF21F5","FF0099"],["FFEAEA","FCEFE1","FCF4DC","FFFECF","EBFFD9","D9FFE9","E0FFFF","E8F4FF","ECF4FC","EAE6F4","FFF5FE","FCF0F7"],["F4CCCC","FCE5CD","FFF1C2","FFFDA1","D5FCB1","B5F7D0","BFFFFF","D6ECFF","CFE2F3","D9D1E9","FFE3FD","FFD9F0"],["EA9899","F9CB9C","FFE48C","F7F56F","B9F77E","84F0B1","83F7F7","B5DAFF","9FC5E8","B4A7D6","FAB9F6","FFADDE"],["E06666","F6B26B","DEB737","E0DE51","8FDB48","52D189","4EDEDB","76ACE3","6FA8DC","8E7CC3","E07EDA","F26DBD"],["CC0814","E69138","AB8816","B5B20E","6BAB30","27A85F","1BA8A6","3C81C7","3D85C6","674EA7","A14F9D","BF4990"],["99050C","B45F17","80650E","737103","395E14","10783D","13615E","094785","0A5394","351C75","780172","782C5A"]],this.defaults=w2utils.extend({},this.defaults,{advanced:!1,transparent:!0,position:"top|bottom",class:"w2ui-white",color:"",liveUpdate:!0,arrowSize:12,autoResize:!1,anchorClass:"w2ui-focus",autoShowOn:"focus",hideOn:["doc-click","focus-change"],onSelect:null,onLiveUpdate:null})}attach(e,t){let i;1==arguments.length&&e.anchor?e=(i=e).anchor:2===arguments.length&&null!=t&&"object"==typeof t&&((i=t).anchor=e);t=i.hideOn;i=w2utils.extend({},this.defaults,i||{}),t&&(i.hideOn=t),i.style+="; padding: 0;",i.transparent&&"333333"==this.palette[0][1]&&(this.palette[0].splice(1,1),this.palette[0].push("")),i.transparent||"333333"==this.palette[0][1]||(this.palette[0].splice(1,0,"333333"),this.palette[0].pop()),i.color&&(i.color=String(i.color).toUpperCase()),"string"==typeof i.color&&"#"===i.color.substr(0,1)&&(i.color=i.color.substr(1)),this.index=[-1,-1];let s=super.attach(i),l=s.overlay;return l.options.html=this.getColorHTML(l.name,i),l.on("show.attach",e=>{var e=e.detail.overlay,t=e.anchor,i=e.options;["INPUT","TEXTAREA"].includes(t.tagName)&&!i.color&&t.value&&(e.tmp.initColor=t.value),delete e.newColor}),l.on("show:after.attach",e=>{var t;s.overlay?.box&&(t=query(s.overlay.box).find(".w2ui-eaction"),w2utils.bindEvents(t,this),this.initControls(s.overlay))}),l.on("update:after.attach",e=>{var t;s.overlay?.box&&(t=query(s.overlay.box).find(".w2ui-eaction"),w2utils.bindEvents(t,this),this.initControls(s.overlay))}),l.on("hide.attach",e=>{var e=e.detail.overlay,t=e.anchor,i=e.newColor??e.options.color??"",t=(["INPUT","TEXTAREA"].includes(t.tagName)&&t.value!=i&&(t.value=i),this.trigger("select",{color:i,target:e.name,overlay:e}));!0!==t.isCancelled&&t.finish()}),s.liveUpdate=t=>(l.on("liveUpdate.attach",e=>{t(e)}),s),s.select=t=>(l.on("select.attach",e=>{t(e)}),s),s}select(e,t){let i;this.index=[-1,-1],"string"!=typeof t&&(i=t.target,this.index=query(i).attr("index").split(":"),t=query(i).closest(".w2ui-overlay").attr("name"));var s=this.get(t),t=this.trigger("liveUpdate",{color:e,target:t,overlay:s,param:arguments[1]});!0!==t.isCancelled&&(["INPUT","TEXTAREA"].includes(s.anchor.tagName)&&s.options.liveUpdate&&query(s.anchor).val(e),s.newColor=e,query(s.box).find(".w2ui-selected").removeClass("w2ui-selected"),i&&query(i).addClass("w2ui-selected"),t.finish())}nextColor(e){var t=this.palette;switch(e){case"up":this.index[0]--;break;case"down":this.index[0]++;break;case"right":this.index[1]++;break;case"left":this.index[1]--}return this.index[0]<0&&(this.index[0]=0),this.index[0]>t.length-2&&(this.index[0]=t.length-2),this.index[1]<0&&(this.index[1]=0),this.index[1]>t[0].length-1&&(this.index[1]=t[0].length-1),t[this.index[0]][this.index[1]]}tabClick(e,t){"string"!=typeof t&&(t=query(t.target).closest(".w2ui-overlay").attr("name"));var t=this.get(t),i=query(t.box).find(`.w2ui-color-tab:nth-child(${e})`);query(t.box).find(".w2ui-color-tab").removeClass("w2ui-selected"),query(i).addClass("w2ui-selected"),query(t.box).find(".w2ui-tab-content").hide().closest(".w2ui-colors").find(".tab-"+e).show()}getColorHTML(s,l){let r=` +
    +
    `;for(let i=0;i';for(let t=0;t  +
    `}r+="
    ",i<2&&(r+='
    ')}return r=(r=(r+="")+` + `)+` +
    +
    +
    +
    + ${"string"==typeof l.html?l.html:""} +
    +
    `}initControls(a){let n,o=this;var e=a.options;let h=w2utils.parseColor(e.color||a.tmp.initColor),d=(null==h&&(h={r:140,g:150,b:160,a:1}),w2utils.rgb2hsv(h));!0===e.advanced&&this.tabClick(2,a.name),u(d,!0,!0),query(a.box).find("input").off(".w2color").on("change.w2color",e=>{e=query(e.target);let t=parseFloat(e.val());var i=parseFloat(e.attr("max")),i=(isNaN(t)&&(t=0,e.val(0)),1i&&(e.val(i),t=i),t<0&&(e.val(0),t=0),e.attr("name")),e={};-1!==["r","g","b","a"].indexOf(i)?(h[i]=t,d=w2utils.rgb2hsv(h)):-1!==["h","s","v"].indexOf(i)&&(e[i]=t),u(e,!0)}),query(a.box).find(".color-original").off(".w2color").on("click.w2color",e=>{e=w2utils.parseColor(query(e.target).css("background-color"));null!=e&&(h=e,u(d=w2utils.rgb2hsv(h),!0))});e=`${w2utils.isIOS?"touchstart":"mousedown"}.w2color`;let s=`${w2utils.isIOS?"touchend":"mouseup"}.w2color`,l=`${w2utils.isIOS?"touchmove":"mousemove"}.w2color`;function u(e,t,i){null!=e.h&&(d.h=e.h),null!=e.s&&(d.s=e.s),null!=e.v&&(d.v=e.v),null!=e.a&&(h.a=e.a,d.a=e.a);let s="rgba("+(h=w2utils.hsv2rgb(d)).r+","+h.g+","+h.b+","+h.a+")",l=[Number(h.r).toString(16).toUpperCase(),Number(h.g).toString(16).toUpperCase(),Number(h.b).toString(16).toUpperCase(),Math.round(255*Number(h.a)).toString(16).toUpperCase()];var r,n;l.forEach((e,t)=>{1===e.length&&(l[t]="0"+e)}),s=l[0]+l[1]+l[2]+l[3],1===h.a&&(s=l[0]+l[1]+l[2]),query(a.box).find(".color-preview").css("background-color","#"+s),query(a.box).find("input").each(e=>{e.name&&(null!=h[e.name]&&(e.value=h[e.name]),null!=d[e.name]&&(e.value=d[e.name]),"a"===e.name)&&(e.value=h.a)}),i?(e=a.tmp?.initColor||s,query(a.box).find(".color-original").css("background-color","#"+e),query(a.box).find(".w2ui-colors .w2ui-selected").removeClass("w2ui-selected"),query(a.box).find(`.w2ui-colors [name="${e}"]`).addClass("w2ui-selected"),8==s.length&&o.tabClick(2,a.name)):o.select(s,a.name),t&&(i=query(a.box).find(".palette .value1"),e=query(a.box).find(".rainbow .value2"),t=query(a.box).find(".alpha .value2"),r=parseInt(i[0].clientWidth)/2,n=parseInt(e[0].clientWidth)/2,i.css({left:150*d.s/100-r+"px",top:125*(100-d.v)/100-r+"px"}),e.css("left",d.h/2.4-n+"px"),t.css("left",150*h.a-n+"px"),c())}function c(){var e=w2utils.hsv2rgb(d.h,100,100),e=`${e.r},${e.g},`+e.b;query(a.box).find(".palette").css("background-image",`linear-gradient(90deg, rgba(${e},0) 0%, rgba(${e},1) 100%)`)}function r(e){query("body").off(".w2color")}function p(e){var t=n.el,i=e.pageX-n.x,e=e.pageY-n.y;let s=n.left+i,l=n.top+e;var i=parseInt(t.prop("clientWidth"))/2,e=(s<-i&&(s=-i),l<-i&&(l=-i),s>n.width-i&&(s=n.width-i),l>n.height-i&&(l=n.height-i),t.hasClass("move-x")&&t.css({left:s+"px"}),t.hasClass("move-y")&&t.css({top:l+"px"}),query(t.get(0).parentNode).attr("name")),r=parseInt(t.css("left"))+i,t=parseInt(t.css("top"))+i;"palette"===e&&u({s:Math.round(r/n.width*100),v:Math.round(100-t/n.height*100)}),"rainbow"===e&&(u({h:Math.round(2.4*r)}),c()),"alpha"===e&&u({a:parseFloat(Number(r/150).toFixed(2))})}query(a.box).find(".palette, .rainbow, .alpha").off(".w2color").on(e+".w2color",function(e){var t=query(this).find(".value1, .value2"),i=parseInt(t.prop("clientWidth"))/2;t.hasClass("move-x")&&t.css({left:e.offsetX-i+"px"});t.hasClass("move-y")&&t.css({top:e.offsetY-i+"px"});n={el:t,x:e.pageX,y:e.pageY,width:t.prop("parentNode").clientWidth,height:t.prop("parentNode").clientHeight,left:parseInt(t.css("left")),top:parseInt(t.css("top"))},p(e),query("body").off(".w2color").on(l,p).on(s,r)})}}class MenuTooltip extends Tooltip{constructor(){super(),this.defaults=w2utils.extend({},this.defaults,{type:"normal",items:[],index:null,render:null,spinner:!1,msgNoItems:w2utils.lang("No items found"),topHTML:"",menuStyle:"",filter:!1,markSearch:!1,match:"contains",search:!1,altRows:!1,arrowSize:10,align:"left",position:"bottom|top",class:"w2ui-white",anchorClass:"w2ui-focus",autoShowOn:"focus",hideOn:["doc-click","focus-change","select"],onSelect:null,onSubMenu:null,onRemove:null})}attach(e,t){let i;1==arguments.length&&e.anchor?e=(i=e).anchor:2===arguments.length&&null!=t&&"object"==typeof t&&((i=t).anchor=e);t=i.hideOn;i=w2utils.extend({},this.defaults,i||{}),t&&(i.hideOn=t),i.style+="; padding: 0;",null==i.items&&(i.items=[]),i.html=this.getMenuHTML(i);let s=super.attach(i),l=s.overlay;return l.on("show:after.attach, update:after.attach",e=>{if(s.overlay?.box){let e="";l.selected=null,l.options.items=w2utils.normMenu(l.options.items),["INPUT","TEXTAREA"].includes(l.anchor.tagName)&&(e=l.anchor.value,l.selected=l.anchor.dataset.selectedIndex);var t=query(s.overlay.box).find(".w2ui-eaction");w2utils.bindEvents(t,this),this.applyFilter(l.name,null,e).then(e=>{l.tmp.searchCount=e.count,l.tmp.search=e.search,this.refreshSearch(l.name),this.initControls(s.overlay),this.refreshIndex(l.name)})}}),l.on("hide:after.attach",e=>{w2tooltip.hide(l.name+"-tooltip")}),s.select=t=>(l.on("select.attach",e=>{t(e)}),s),s.remove=t=>(l.on("remove.attach",e=>{t(e)}),s),s.subMenu=t=>(l.on("subMenu.attach",e=>{t(e)}),s),s}update(e,t){var i,s=Tooltip.active[e];s?((i=s.options).items!=t&&(i.items=t),t=this.getMenuHTML(i),i.html!=t&&(i.html=t,s.needsUpdate=!0,this.show(e))):console.log(`Tooltip "${e}" is not displayed. Cannot update it.`)}initControls(i){query(i.box).find(".w2ui-menu:not(.w2ui-sub-menu)").off(".w2menu").on("mouseDown.w2menu",{delegate:".w2ui-menu-item"},e=>{var t=e.delegate.dataset;this.menuDown(i,e,t.index,t.parents)}).on((w2utils.isIOS?"touchStart":"click")+".w2menu",{delegate:".w2ui-menu-item"},e=>{var t=e.delegate.dataset;this.menuClick(i,e,parseInt(t.index),t.parents)}).find(".w2ui-menu-item").off(".w2menu").on("mouseEnter.w2menu",e=>{var t=e.target.dataset,t=i.options.items[t.index]?.tooltip;t&&w2tooltip.show({name:i.name+"-tooltip",anchor:e.target,html:t,position:"right|left",hideOn:["doc-click"]})}).on("mouseLeave.w2menu",e=>{w2tooltip.hide(i.name+"-tooltip")}),["INPUT","TEXTAREA"].includes(i.anchor.tagName)&&query(i.anchor).off(".w2menu").on("input.w2menu",e=>{}).on("keyup.w2menu",e=>{e._searchType="filter",this.keyUp(i,e)}),i.options.search&&query(i.box).find("#menu-search").off(".w2menu").on("keyup.w2menu",e=>{e._searchType="search",this.keyUp(i,e)})}getCurrent(e,t){var e=Tooltip.active[e.replace(/[\s\.#]/g,"_")],i=e.options;let s=(t||(e.selected??"")).split("-");var t=s.length-1,e=s[t],l=s.slice(0,s.length-1).join("-"),e=w2utils.isInt(e)?parseInt(e):0;let r=i.items;return s.forEach((e,t)=>{t +
    +
    + ${w2utils.lang("Loading...")} +
    + `;u=u||[],null==e&&(e=h.items),Array.isArray(e)||(e=[]);let c=0,t=null,i="",p=(!d&&h.search&&(i+=` + `,e.forEach(e=>e.hidden=!1)),!d&&h.topHTML&&(i+=`
    ${h.topHTML}
    `),` + ${i} +
    + `);return e.forEach((r,n)=>{t=r.icon;var a=(0`),s=``),"break"!==r.type&&null!=i&&""!==i&&"--"!=String(i).substr(0,2)){var o=["w2ui-menu-item"];1==h.altRows&&o.push(c%2==0?"w2ui-even":"w2ui-odd");let e=1,t=(""===s&&e++,null==r.count&&null==r.hotkey&&!0!==r.remove&&null==r.items&&e++,null==r.tooltip&&null!=r.hint&&(r.tooltip=r.hint),"");if(!0===r.remove)t='x';else if(null!=r.items){let e=[];"function"==typeof r.items?e=r.items(r):Array.isArray(r.items)&&(e=r.items),t="",l=` +
    + ${this.getMenuHTML(h,e,!0,u.concat(n))} +
    `}else null!=r.count&&(t+=""+r.count+""),null!=r.hotkey&&(t+=''+r.hotkey+"");!0===r.disabled&&o.push("w2ui-disabled"),!0===r._noSearchInside&&o.push("w2ui-no-search-inside"),""!==l&&(o.push("has-sub-menu"),r.expanded?o.push("expanded"):o.push("collapsed")),p+=` +
    +
    + ${s} + + +
    + `+l,c++}else{o=(i??"").replace(/^-+/g,"");p+=` +
    +
    + ${o?`
    ${o}
    `:""} +
    `}}e[n]=r}),0===c&&h.msgNoItems&&(p+=` +
    + ${w2utils.lang(h.msgNoItems)} +
    `),p+="
    "}refreshIndex(e){var t,i,e=Tooltip.active[e.replace(/[\s\.#]/g,"_")];e&&(e.displayed||this.show(e.name),t=query(e.box).find(".w2ui-overlay-body").get(0),i=query(e.box).find(".w2ui-menu-search, .w2ui-menu-top").get(0),query(e.box).find(".w2ui-menu-item.w2ui-selected").removeClass("w2ui-selected"),e=query(e.box).find(`.w2ui-menu-item[index="${e.selected}"]`).addClass("w2ui-selected").get(0))&&(e.offsetTop+e.clientHeight>t.clientHeight+t.scrollTop&&e.scrollIntoView({behavior:"smooth",block:"start",inline:"start"}),e.offsetTop{var t;this.getCurrent(i,e.getAttribute("index")).item?.hidden?query(e).hide():((t=s.tmp?.search)&&s.options.markSearch&&w2utils.marker(e,t,{onlyFirst:"begins"==s.options.match}),query(e).show())}),query(s.box).find(".w2ui-sub-menu").each(e=>{var t=query(e).find(".w2ui-menu-item").get().some(e=>"none"!=e.style.display);this.getCurrent(i,e.dataset.parent).item.expanded&&(t?query(e).parent().show():query(e).parent().hide())}),0!=s.tmp.searchCount&&0!=s.options?.items?.length||(0==query(s.box).find(".w2ui-no-items").length&&query(s.box).find(".w2ui-menu:not(.w2ui-sub-menu)").append(` +
    + ${w2utils.lang(s.options.msgNoItems)} +
    `),query(s.box).find(".w2ui-no-items").show()))}applyFilter(s,t,l,i){let r=0;var n=Tooltip.active[s.replace(/[\s\.#]/g,"_")];let a=n.options,o,h;var d=new Promise((e,t)=>{o=e,h=t});null==l&&(l=["INPUT","TEXTAREA"].includes(n.anchor.tagName)?n.anchor.value:"");let u=[];a.selected&&(Array.isArray(a.selected)?u=a.selected.map(e=>e?.id??e):a.selected?.id&&(u=[a.selected.id])),n.tmp.activeChain=null;var c=n.tmp.remote??{hasMore:!0,emtpySet:!1,search:null,total:-1};if(null==t&&a.url&&c.hasMore&&c.search!==l){let e=!0,t=w2utils.lang("Loading...");l.length{this.update(s,e),this.applyFilter(s,null,l).then(e=>{o(e)})}).catch(e=>{console.log("Server Request error",e)})}else{let e;null==t&&!0===(e=this.trigger("search",{search:l,overlay:n,prom:d,resolve:o,reject:h})).isCancelled||(null==t&&(t=n.options.items),!1===a.filter?o({count:-1,search:l}):(t.forEach(t=>{let e="",i="";-1!==["is","begins","begins with"].indexOf(a.match)&&(e="^"),-1!==["is","ends","ends with"].indexOf(a.match)&&(i="$");try{new RegExp(e+l+i,"i").test(t.text)||"..."===t.text?t.hidden=!1:t.hidden=!0}catch(e){}a.hideSelected&&u.includes(t.id)&&(t.hidden=!0),Array.isArray(t.items)&&0{e=e.count;0a.search.length||r.length>=a.search.length&&r.substr(0,a.search.length)!==a.search||r.length{var e=n.url;let i={search:r,max:n.cacheMax};Object.assign(i,n.postData);var t,s=this.trigger("request",{search:r,overlay:l,url:e,postData:i,httpMethod:n.method??"GET",httpHeaders:{}});!0!==s.isCancelled&&(e=new URL(s.detail.url,location),t=w2utils.prepareParams(e,{method:s.detail.httpMethod,headers:s.detail.httpHeaders,body:s.detail.postData}),a.controller=new AbortController,t.signal=a.controller.signal,fetch(e,t).then(e=>e.json()).then(e=>{a.controller=null;var t=l.trigger("load",{search:i.search,overlay:l,data:e});!0!==t.isCancelled&&("string"==typeof(e=t.detail.data)&&(e=JSON.parse(e)),null==(e=Array.isArray(e)?{records:e}:e).records&&null!=e.items&&(e.records=e.items,delete e.items),e.error||null!=e.records||(e.records=[]),Array.isArray(e.records)?(e.records.length>=n.cacheMax?(e.records.splice(n.cacheMax,e.records.length),a.hasMore=!0):a.hasMore=!1,null==n.recId&&null!=n.recid&&(n.recId=n.recid),(n.recId||n.recText)&&e.records.forEach(e=>{"string"==typeof n.recId&&(e.id=e[n.recId]),"function"==typeof n.recId&&(e.id=n.recId(e)),"string"==typeof n.recText&&(e.text=e[n.recText]),"function"==typeof n.recText&&(e.text=n.recText(e))}),a.loading=!1,a.search=r,a.total=e.records.length,a.lastError="",a.emptySet=""===r&&0===e.records.length,t.finish(),o(w2utils.normMenu(e.records))):console.error("ERROR: server did not return proper data structure","\n"," - it should return",{records:[{id:1,text:"item"}]},"\n"," - or just an array ",[{id:1,text:"item"}],"\n"," - or if errorr ",{error:!0,message:"error message"}))}).catch(e=>{var t=this.trigger("error",{overlay:l,search:r,error:e});!0!==t.isCancelled&&("AbortError"!==e?.name&&console.error("ERROR: Server communication failed.","\n"," - it should return",{records:[{id:1,text:"item"}]},"\n"," - or just an array ",[{id:1,text:"item"}],"\n"," - or if errorr ",{error:!0,message:"error message"}),a.loading=!1,a.search="",a.total=-1,a.emptySet=!0,a.lastError=t.detail.error||"Server communication failed",n.items=[],t.finish(),h())}),s.finish())},e?n.debounce??350:0)),new Promise((e,t)=>{o=e,h=t})}getActiveChain(i,e,s=[],l=[],t){var r=Tooltip.active[i.replace(/[\s\.#]/g,"_")];return null!=r.tmp.activeChain?r.tmp.activeChain:((e=null==e?r.options.items:e).forEach((e,t)=>{e.hidden||e.disabled||e?.text?.startsWith("--")||(l.push(s.concat([t]).join("-")),Array.isArray(e.items)&&0{l=l[e].items}),l[i]);if(!a.disabled){let l=(i,s)=>{i.forEach((e,t)=>{e.id!=a.id&&(e.group===a.group&&e.checked&&(n.find(`.w2ui-menu-item[index="${(s?s+"-":"")+t}"] .w2ui-icon`).removeClass("w2ui-icon-check").addClass("w2ui-icon-empty"),i[t].checked=!1),Array.isArray(e.items))&&l(e.items,t)})};"check"!==e.type&&"radio"!==e.type||!1===a.group||query(t.target).hasClass("remove")||query(t.target).closest(".w2ui-menu-item").hasClass("has-sub-menu")||(a.checked="radio"==e.type||!a.checked,a.checked?("radio"===e.type&&query(t.target).closest(".w2ui-menu").find(".w2ui-icon").removeClass("w2ui-icon-check").addClass("w2ui-icon-empty"),"check"===e.type&&null!=a.group&&l(e.items),r.removeClass("w2ui-icon-empty").addClass("w2ui-icon-check")):"check"===e.type&&r.removeClass("w2ui-icon-check").addClass("w2ui-icon-empty")),query(t.target).hasClass("remove")||(n.find(".w2ui-menu-item").removeClass("w2ui-selected"),query(t.delegate).addClass("w2ui-selected"))}}menuClick(t,i,s,l){var r=t.options;let n=r.items;var a=query(i.delegate).closest(".w2ui-menu-item");let o=!r.hideOn.includes("select");(i.shiftKey||i.metaKey||i.ctrlKey)&&(o=!0),"string"==typeof l&&""!==l?l.split("-").forEach(e=>{n=n[e].items}):l=null;var h=(n="function"==typeof n?n({overlay:t,index:s,parentIndex:l,event:i}):n)[s];if(!h.disabled||query(i.target).hasClass("remove")){let e;if(query(i.target).hasClass("remove")){if(!0===(e=this.trigger("remove",{originalEvent:i,target:t.name,overlay:t,item:h,index:s,parentIndex:l,el:a[0]})).isCancelled)return;o=!r.hideOn.includes("item-remove"),a.remove()}else if(a.hasClass("has-sub-menu")){if(!0===(e=this.trigger("subMenu",{originalEvent:i,target:t.name,overlay:t,item:h,index:s,parentIndex:l,el:a[0]})).isCancelled)return;o=!0,a.hasClass("expanded")?(h.expanded=!1,a.removeClass("expanded").addClass("collapsed"),query(a.get(0).nextElementSibling).hide()):(h.expanded=!0,a.addClass("expanded").removeClass("collapsed"),query(a.get(0).nextElementSibling).show()),t.selected=parseInt(a.attr("index"))}else{r=this.findChecked(r.items);if(t.selected=parseInt(a.attr("index")),!0===(e=this.trigger("select",{originalEvent:i,target:t.name,overlay:t,item:h,index:s,parentIndex:l,selected:r,keepOpen:o,el:a[0]})).isCancelled)return;null!=h.keepOpen&&(o=h.keepOpen),["INPUT","TEXTAREA"].includes(t.anchor.tagName)&&(t.anchor.dataset.selected=h.id,t.anchor.dataset.selectedIndex=t.selected)}o||this.hide(t.name),e.finish()}}findChecked(e){let t=[];return e.forEach(e=>{e.checked&&t.push(e),Array.isArray(e.items)&&(t=t.concat(this.findChecked(e.items)))}),t}keyUp(s,l){var r=s.options,e=l.target.value;let n=!0,a=!1;switch(l.keyCode){case 46:case 8:""!==e||s.displayed||(n=!1);break;case 13:if(!s.displayed||!s.selected)return;var{index:t,parents:i}=this.getCurrent(s.name);l.delegate=query(s.box).find(".w2ui-selected").get(0),this.menuClick(s,l,parseInt(t),i),n=!1;break;case 27:n=!1,s.displayed?this.hide(s.name):(t=s.anchor,["INPUT","TEXTAREA"].includes(t.tagName)&&(t.value="",delete t.dataset.selected,delete t.dataset.selectedIndex));break;case 37:{if(!s.displayed)return;let{item:e,index:t,parents:i}=this.getCurrent(s.name);i&&(e=r.items[i],t=parseInt(i),i="",a=!0),Array.isArray(e?.items)&&0{s.tmp.searchCount=e.count,s.tmp.search=e.search,0!==e.count&&this.getActiveChain(s.name).includes(s.selected)||(s.selected=null),this.refreshSearch(s.name)}),a&&this.refreshIndex(s.name)}}class DateTooltip extends Tooltip{constructor(){super();var e=new Date;this.daysCount=[31,28,31,30,31,30,31,31,30,31,30,31],this.today=e.getFullYear()+"/"+(Number(e.getMonth())+1)+"/"+e.getDate(),this.defaults=w2utils.extend({},this.defaults,{position:"top|bottom",class:"w2ui-calendar",type:"date",format:"",value:"",start:null,end:null,blockDates:[],blockWeekdays:[],colored:{},arrowSize:12,autoResize:!1,anchorClass:"w2ui-focus",autoShowOn:"focus",hideOn:["doc-click","focus-change"],onSelect:null})}attach(e,t){let i;1==arguments.length&&e.anchor?e=(i=e).anchor:2===arguments.length&&null!=t&&"object"==typeof t&&((i=t).anchor=e);var t=i.hideOn,e=(i=w2utils.extend({},this.defaults,i||{}),t&&(i.hideOn=t),i.format||(e=w2utils.settings.dateFormat,t=w2utils.settings.timeFormat,"date"==i.type?i.format=e:"time"==i.type?i.format=t:i.format=e+"|"+t),"time"==i.type?this.getHourHTML(i):this.getMonthHTML(i));i.style+="; padding: 0;",i.html=e.html;let s=super.attach(i),l=s.overlay;return Object.assign(l.tmp,e),l.on("show.attach",e=>{var e=e.detail.overlay,t=e.anchor,i=e.options;["INPUT","TEXTAREA"].includes(t.tagName)&&!i.value&&t.value&&(e.tmp.initValue=t.value),delete e.newValue,delete e.newDate}),l.on("show:after.attach",e=>{s.overlay?.box&&this.initControls(s.overlay)}),l.on("update:after.attach",e=>{s.overlay?.box&&this.initControls(s.overlay)}),l.on("hide.attach",e=>{var e=e.detail.overlay,t=e.anchor;null!=e.newValue&&(e.newDate&&(e.newValue=e.newDate+" "+e.newValue),["INPUT","TEXTAREA"].includes(t.tagName)&&t.value!=e.newValue&&(t.value=e.newValue),!0!==(t=this.trigger("select",{date:e.newValue,target:e.name,overlay:e})).isCancelled)&&t.finish()}),s.select=t=>(l.on("select.attach",e=>{t(e)}),s),s}initControls(l){let r=l.options,t=e=>{let{month:t,year:i}=l.tmp;12<(t+=e)&&(t=1,i++),t<1&&(t=12,i--);e=this.getMonthHTML(r,t,i);Object.assign(l.tmp,e),query(l.box).find(".w2ui-overlay-body").html(e.html),this.initControls(l)},i=(e,t)=>{query(e.target).parent().find(".w2ui-jump-month, .w2ui-jump-year").removeClass("w2ui-selected"),query(e.target).addClass("w2ui-selected");e=new Date;let{jumpMonth:i,jumpYear:s}=l.tmp;(i=t&&(null==s&&(s=e.getFullYear()),null==i)?e.getMonth()+1:i)&&s&&(t=this.getMonthHTML(r,i,s),Object.assign(l.tmp,t),query(l.box).find(".w2ui-overlay-body").html(t.html),l.tmp.jump=!1,this.initControls(l))};query(l.box).find(".w2ui-cal-title").off(".calendar").on("click.calendar",e=>{var t,i;Object.assign(l.tmp,{jumpYear:null,jumpMonth:null}),l.tmp.jump?({month:t,year:i}=l.tmp,t=this.getMonthHTML(r,t,i),query(l.box).find(".w2ui-overlay-body").html(t.html),l.tmp.jump=!1):(query(l.box).find(".w2ui-overlay-body .w2ui-cal-days").replace(this.getYearHTML()),(i=query(l.box).find(`[name="${l.tmp.year}"]`).get(0))&&i.scrollIntoView(!0),l.tmp.jump=!0),this.initControls(l),e.stopPropagation()}).find(".w2ui-cal-previous").off(".calendar").on("click.calendar",e=>{t(-1),e.stopPropagation()}).parent().find(".w2ui-cal-next").off(".calendar").on("click.calendar",e=>{t(1),e.stopPropagation()}),query(l.box).find(".w2ui-cal-now").off(".calendar").on("click.calendar",e=>{"datetime"==r.type?l.newDate?l.newValue=w2utils.formatTime(new Date,r.format.split("|")[1]):l.newValue=w2utils.formatDateTime(new Date,r.format):"date"==r.type?l.newValue=w2utils.formatDate(new Date,r.format):"time"==r.type&&(l.newValue=w2utils.formatTime(new Date,r.format)),this.hide(l.name)}),query(l.box).off(".calendar").on("click.calendar",{delegate:".w2ui-day.w2ui-date"},e=>{"datetime"==r.type?(l.newDate=query(e.target).attr("date"),query(l.box).find(".w2ui-overlay-body").html(this.getHourHTML(l.options).html),this.initControls(l)):(l.newValue=query(e.target).attr("date"),this.hide(l.name))}).on("click.calendar",{delegate:".w2ui-jump-month"},e=>{l.tmp.jumpMonth=parseInt(query(e.target).attr("name")),i(e)}).on("dblclick.calendar",{delegate:".w2ui-jump-month"},e=>{l.tmp.jumpMonth=parseInt(query(e.target).attr("name")),i(e,!0)}).on("click.calendar",{delegate:".w2ui-jump-year"},e=>{l.tmp.jumpYear=parseInt(query(e.target).attr("name")),i(e)}).on("dblclick.calendar",{delegate:".w2ui-jump-year"},e=>{l.tmp.jumpYear=parseInt(query(e.target).attr("name")),i(e,!0)}).on("click.calendar",{delegate:".w2ui-time.hour"},e=>{var e=query(e.target).attr("hour");let t=this.str2min(r.value)%60;l.tmp.initValue&&!r.value&&(t=this.str2min(l.tmp.initValue)%60),r.noMinutes?(l.newValue=this.min2str(60*e,r.format),this.hide(l.name)):(l.newValue=e+":"+t,e=this.getMinHTML(e,r).html,query(l.box).find(".w2ui-overlay-body").html(e),this.initControls(l))}).on("click.calendar",{delegate:".w2ui-time.min"},e=>{e=60*Math.floor(this.str2min(l.newValue)/60)+parseInt(query(e.target).attr("min"));l.newValue=this.min2str(e,r.format),this.hide(l.name)})}getMonthHTML(l,r,e){var t=w2utils.settings.fulldays.slice(),i=w2utils.settings.shortdays.slice();"M"!==w2utils.settings.weekStarts&&(t.unshift(t.pop()),i.unshift(i.pop()));let s=new Date;var t="datetime"===l.type?w2utils.isDateTime(l.value,l.format,!0):w2utils.isDate(l.value,l.format,!0),n=w2utils.formatDate(t);null!=r&&null!=e||(e=(t||s).getFullYear(),r=t?t.getMonth()+1:s.getMonth()+1),12${i[e]}`}let c=` +
    +
    +
    +
    +
    +
    +
    + ${w2utils.settings.fullmonths[r-1]}, ${e} + +
    +
    + ${o} + `,p=new Date(e+`/${r}/1`);t=(p=new Date(p.getTime()+432e5)).getDay();"M"==w2utils.settings.weekStarts&&a--,0 + ${g} +
    `,p=new Date(p.getTime()+864e5)}return c+="",l.btnNow&&(t=w2utils.lang("Today"+("datetime"==l.type?" & Now":"")),c+=`
    ${t}
    `),{html:c,month:r,year:e}}getYearHTML(){let t="",i="";for(let e=0;e${w2utils.settings.shortmonths[e]}`;for(let e=w2utils.settings.dateStartYear;e<=w2utils.settings.dateEndYear;e++)i+=`
    ${e}
    `;return`
    +
    ${t}
    +
    ${i}
    +
    `}getHourHTML(l){(l=l??{}).format||(l.format=w2utils.settings.timeFormat);var r=-1${e}
    `}return{html:`
    +
    ${w2utils.lang("Select Hour")}
    +
    +
    ${a[0]}
    +
    ${a[1]}
    +
    ${a[2]}
    +
    + ${l.btnNow?`
    ${w2utils.lang("Now")}
    `:""} +
    `}}getMinHTML(i,s){null==i&&(i=0),(s=s??{}).format||(s.format=w2utils.settings.timeFormat);var l=-1${a}
    `}return{html:`
    +
    ${w2utils.lang("Select Minute")}
    +
    +
    ${n[0]}
    +
    ${n[1]}
    +
    ${n[2]}
    +
    + ${s.btnNow?`
    ${w2utils.lang("Now")}
    `:""} +
    `}}inRange(i,s,e){let l=!1;if("date"===s.type){var r=w2utils.isDate(i,s.format,!0);if(r){if(s.start||s.end){var n="string"==typeof s.start?s.start:query(s.start).val(),a="string"==typeof s.end?s.end:query(s.end).val();let e=w2utils.isDate(n,s.format,!0),t=w2utils.isDate(a,s.format,!0);n=new Date(r);e=e||n,t=t||n,n>=e&&n<=t&&(l=!0)}else l=!0;Array.isArray(s.blockDates)&&s.blockDates.includes(i)&&(l=!1),Array.isArray(s.blockWeekdays)&&s.blockWeekdays.includes(r.getDay())&&(l=!1)}}else if("time"===s.type)if(s.start||s.end){a=this.str2min(i);let e=this.str2min(s.start),t=this.str2min(s.end);e=e||a,t=t||a,a>=e&&a<=t&&(l=!0)}else l=!0;else"datetime"===s.type&&(n=w2utils.isDateTime(i,s.format,!0))&&(r=s.format.split("|").map(e=>e.trim()),e?(a=w2utils.formatDate(n,r[0]),i=w2utils.extend({},s,{type:"date",format:r[0]}),this.inRange(a,i)&&(l=!0)):(e=w2utils.formatTime(n,r[1]),a={type:"time",format:r[1],start:s.startTime,end:s.endTime},this.inRange(e,a)&&(l=!0)));return l}str2min(e){var t;return"string"!=typeof e||2!==(t=e.split(":")).length?null:(t[0]=parseInt(t[0]),t[1]=parseInt(t[1]),-1!==e.indexOf("pm")&&12!==t[0]&&(t[0]+=12),e.includes("am")&&12==t[0]&&(t[0]=0),60*t[0]+t[1])}min2str(e,t){let i="";1440<=e&&(e%=1440),e<0&&(e=1440+e);var s=Math.floor(e/60),e=(e%60<10?"0":"")+e%60;return t=t||w2utils.settings.timeFormat,i=-1!==t.indexOf("h24")?s+":"+e:(s<=12?s:s-12)+":"+e+" "+(12<=s?"pm":"am")}}let w2tooltip=new Tooltip,w2menu=new MenuTooltip,w2color=new ColorTooltip,w2date=new DateTooltip;class w2toolbar extends w2base{constructor(e){super(e.name),this.box=null,this.name=null,this.routeData={},this.items=[],this.right="",this.tooltip="top|left",this.onClick=null,this.onMouseDown=null,this.onMouseUp=null,this.onMouseEnter=null,this.onMouseLeave=null,this.onRender=null,this.onRefresh=null,this.onResize=null,this.onDestroy=null,this.item_template={id:null,type:"button",text:null,html:"",tooltip:null,count:null,hidden:!1,disabled:!1,checked:!1,icon:null,route:null,arrow:null,style:null,group:null,items:null,selected:null,color:null,overlay:{anchorClass:""},onClick:null,onRefresh:null},this.last={badge:{}};var t=e.items;delete e.items,Object.assign(this,e),Array.isArray(t)&&this.add(t,!0),e.items=t,"string"==typeof this.box&&(this.box=query(this.box).get(0)),this.box&&this.render(this.box)}add(e,t){this.insert(null,e,t)}insert(r,e,n){(e=Array.isArray(e)?e:[e]).forEach((e,t,i)=>{"string"==typeof e&&(e=i[t]={id:e,text:e});var l,s=["button","check","radio","drop","menu","menu-radio","menu-check","color","text-color","html","break","spacer","new-line"];if(s.includes(String(e.type)))if(null!=e.id||["break","spacer","new-line"].includes(e.type)){if(null==e.type)console.log('ERROR: The parameter "type" is required but not supplied.',e);else if(w2utils.checkUniqueId(e.id,this.items,"toolbar",this.name)){let s=w2utils.extend({},this.item_template,e);"menu-check"==s.type?(Array.isArray(s.selected)||(s.selected=[]),Array.isArray(s.items)&&s.items.forEach(e=>{(e="string"==typeof e?i[t]={id:e,text:e}:e).checked&&!s.selected.includes(e.id)&&s.selected.push(e.id),!e.checked&&s.selected.includes(e.id)&&(e.checked=!0),null==e.checked&&(e.checked=!1)})):"menu-radio"==s.type&&Array.isArray(s.items)&&s.items.forEach((e,t,i)=>{(e="string"==typeof e?i[t]={id:e,text:e}:e).checked&&null==s.selected?s.selected=e.id:e.checked=!1,e.checked||s.selected!=e.id||(e.checked=!0),null==e.checked&&(e.checked=!1)}),null==r?this.items.push(s):(l=this.get(r,!0),this.items=this.items.slice(0,l).concat([s],this.items.slice(l))),s.line=s.line??1,!0!==n&&this.refresh(s.id)}}else console.log('ERROR: The parameter "id" is required but not supplied.',e);else console.log('ERROR: The parameter "type" should be one of the following:',s,`, but ${e.type} is supplied.`,e)}),!0!==n&&this.resize()}remove(){let i=0;return Array.from(arguments).forEach(e=>{var t=this.get(e);t&&-1==String(e).indexOf(":")&&(i++,query(this.box).find("#tb_"+this.name+"_item_"+w2utils.escapeId(t.id)).remove(),null!=(e=this.get(t.id,!0)))&&this.items.splice(e,1)}),this.resize(),i}set(e,t){var i=this.get(e);return null!=i&&(Object.assign(i,t),this.refresh(String(e).split(":")[0]),!0)}get(e,i){if(0===arguments.length){var t=[];for(let e=0;e span`);0{var t=this.get(e);t&&(t.hidden=!1,i.push(String(e).split(":")[0]))}),setTimeout(()=>{i.forEach(e=>{this.refresh(e),this.resize()})},15),i}hide(){let i=[];return Array.from(arguments).forEach(e=>{var t=this.get(e);t&&(t.hidden=!0,i.push(String(e).split(":")[0]))}),setTimeout(()=>{i.forEach(e=>{this.refresh(e),this.tooltipHide(e),this.resize()})},15),i}enable(){let i=[];return Array.from(arguments).forEach(e=>{var t=this.get(e);t&&(t.disabled=!1,i.push(String(e).split(":")[0]))}),setTimeout(()=>{i.forEach(e=>{this.refresh(e)})},15),i}disable(){let i=[];return Array.from(arguments).forEach(e=>{var t=this.get(e);t&&(t.disabled=!0,i.push(String(e).split(":")[0]))}),setTimeout(()=>{i.forEach(e=>{this.refresh(e),this.tooltipHide(e)})},15),i}check(){let i=[];return Array.from(arguments).forEach(e=>{var t=this.get(e);t&&-1==String(e).indexOf(":")&&(t.checked=!0,i.push(String(e).split(":")[0]))}),setTimeout(()=>{i.forEach(e=>{this.refresh(e)})},15),i}uncheck(){let i=[];return Array.from(arguments).forEach(e=>{var t=this.get(e);t&&-1==String(e).indexOf(":")&&(["menu","menu-radio","menu-check","drop","color","text-color"].includes(t.type)&&t.checked&&w2tooltip.hide(this.name+"-drop"),t.checked=!1,i.push(String(e).split(":")[0]))}),setTimeout(()=>{i.forEach(e=>{this.refresh(e)})},15),i}click(e,t){var i=String(e).split(":");let l=this.get(i[0]),r=l&&l.items?w2utils.normMenu.call(this,l.items,l):[];if(1{var t=(e,t)=>{let i=this;return function(){i.set(e,{checked:!1})}},i=query(this.box).find("#tb_"+this.name+"_item_"+w2utils.escapeId(l.id));if(w2utils.isPlainObject(l.overlay)||(l.overlay={}),"drop"==l.type&&w2tooltip.show(w2utils.extend({html:l.html,class:"w2ui-white",hideOn:["doc-click"]},l.overlay,{anchor:i[0],name:this.name+"-drop",data:{item:l,btn:s}})).hide(t(l.id,s)),["menu","menu-radio","menu-check"].includes(l.type)){let e="normal";"menu-radio"==l.type&&(e="radio",r.forEach(e=>{l.selected==e.id?e.checked=!0:e.checked=!1})),"menu-check"==l.type&&(e="check",r.forEach(e=>{Array.isArray(l.selected)&&l.selected.includes(e.id)?e.checked=!0:e.checked=!1})),w2menu.show(w2utils.extend({items:r},l.overlay,{type:e,name:this.name+"-drop",anchor:i[0],data:{item:l,btn:s}})).hide(t(l.id,s)).remove(e=>{this.menuClick({name:this.name,remove:!0,item:l,subItem:e.detail.item,originalEvent:e})}).select(e=>{this.menuClick({name:this.name,item:l,subItem:e.detail.item,originalEvent:e})})}["color","text-color"].includes(l.type)&&w2color.show(w2utils.extend({color:l.color},l.overlay,{anchor:i[0],name:this.name+"-drop",data:{item:l,btn:s}})).hide(t(l.id,s)).select(e=>{null!=e.detail.color&&this.colorClick({name:this.name,item:l,color:e.detail.color})})},0)}if(["check","menu","menu-radio","menu-check","drop","color","text-color"].includes(l.type)&&(l.checked=!l.checked,l.checked?query(this.box).find(s).addClass("checked"):query(this.box).find(s).removeClass("checked")),l.route){let t=String("/"+l.route).replace(/\/{2,}/g,"/");var a=w2utils.parseRoute(t);if(0{window.location.hash=t},1)}this.tooltipShow(e),i.finish()}}}scroll(a,o,h){return new Promise((e,t)=>{var i=query(this.box).find(`.w2ui-tb-line:nth-child(${o}) .w2ui-scroll-wrapper`),s=i.get(0).scrollLeft,l=i.find(".w2ui-tb-right").get(0),r=i.parent().get(0).getBoundingClientRect().width,n=s+parseInt(l.offsetLeft)+parseInt(l.clientWidth);switch(a){case"left":(scroll=s-r+50)<=0&&(scroll=0),i.get(0).scrollTo({top:0,left:scroll,behavior:h?"atuo":"smooth"});break;case"right":(scroll=s+r-50)>=n-r&&(scroll=n-r),i.get(0).scrollTo({top:0,left:scroll,behavior:h?"atuo":"smooth"})}setTimeout(()=>{this.resize(),e()},h?0:500)})}render(e){var s=Date.now(),l=("string"==typeof e&&(e=query(e).get(0)),this.trigger("render",{target:this.name,box:e??this.box}));if(!0!==l.isCancelled&&(null!=e&&(0 ",r),null!=r.hint&&console.log("NOTICE: toolbar item.hint property is deprecated, please use item.tooltip. Item -> ",r),0!==e&&"new-line"!=r.type||(i++,t+=` +
    +
    +
    ${this.right[i-1]??""}
    +
    +
    +
    +
    + `),r.line=i)}return query(this.box).attr("name",this.name).addClass("w2ui-reset w2ui-toolbar").html(t),0{this.resize()}),this.last.observeResize.observe(this.box),this.refresh(),this.resize(),l.finish(),Date.now()-s}}refresh(t){var i=Date.now(),l=this.trigger("refresh",{target:null!=t?t:this.name,item:this.get(t)});if(!0!==l.isCancelled){let e;if(null==t)for(let e=0;e{i[e].anchor==s.get(0)&&(i[e].anchor=t)})}if(["menu","menu-radio","menu-check"].includes(r.type)&&r.checked){let t=Array.isArray(r.selected)?r.selected:[r.selected];r.items.forEach(e=>{t.includes(e.id)?e.checked=!0:e.checked=!1}),w2menu.update(this.name+"-drop",r.items)}return"function"==typeof r.onRefresh&&e.finish(),l.finish(),Date.now()-i}}}}resize(){var e=Date.now(),t=this.trigger("resize",{target:this.name});if(!0!==t.isCancelled)return query(this.box).find(".w2ui-tb-line").each(e=>{var e=query(e),t=(e.find(".w2ui-scroll-left, .w2ui-scroll-right").hide(),e.find(".w2ui-scroll-wrapper").get(0)),i=e.find(".w2ui-tb-right"),s=e.get(0).getBoundingClientRect().width,i=0e.id==t)}),""),s="function"==typeof i.text?i.text.call(this,i):i.text;i.icon&&(t=i.icon,"function"==typeof i.icon&&(t=i.icon.call(this,i)),t=`
    ${t="<"!==String(t).slice(0,1)?``:t}
    `);var l=["w2ui-tb-button"];switch(i.checked&&l.push("checked"),i.disabled&&l.push("disabled"),i.hidden&&l.push("hidden"),t||l.push("no-icon"),i.type){case"color":case"text-color":"string"==typeof i.color&&("#"==i.color.slice(0,1)&&(i.color=i.color.slice(1)),[3,6,8].includes(i.color.length))&&(i.color="#"+i.color),"color"==i.type&&(s=` + `+(i.text?`
    ${w2utils.lang(i.text)}
    `:"")),"text-color"==i.type&&(s=''+(i.text?w2utils.lang(i.text):"Aa")+"");case"menu":case"menu-check":case"menu-radio":case"button":case"check":case"radio":case"drop":var r=!0===i.arrow||!1!==i.arrow&&["menu","menu-radio","menu-check","drop","color","text-color"].includes(i.type);e=` +
    + ${t} + ${""!=s?`
    + ${w2utils.lang(s)} + ${null!=i.count?w2utils.stripSpaces(` + ${i.count} + `):""} + ${r?'':""} +
    `:""} +
    + `;break;case"break":e=`
    +   +
    `;break;case"spacer":e=`
    +
    `;break;case"html":e=`
    + ${"function"==typeof i.html?i.html.call(this,i):i.html} +
    `}return e}tooltipShow(t){if(null!=this.tooltip){var i=query(this.box).find("#tb_"+this.name+"_item_"+w2utils.escapeId(t)).get(0),t=this.get(t),s=this.tooltip;let e=t.tooltip;"function"==typeof e&&(e=e.call(this,t)),["menu","menu-radio","menu-check","drop","color","text-color"].includes(t.type)&&1==t.checked||w2tooltip.show({anchor:i,name:this.name+"-tooltip",html:e,position:s})}}tooltipHide(e){null!=this.tooltip&&w2tooltip.hide(this.name+"-tooltip")}menuClick(t){if(t.item&&!t.item.disabled){var i=this.trigger(!0!==t.remove?"click":"remove",{target:t.item.id+":"+t.subItem.id,item:t.item,subItem:t.subItem,originalEvent:t.originalEvent});if(!0!==i.isCancelled){let l=t.subItem,r=this.get(t.item.id),e=r.items;if("function"==typeof e&&(e=r.items()),"menu"==r.type&&(r.selected=l.id),"menu-radio"==r.type&&(r.selected=l.id,Array.isArray(e)&&e.forEach(e=>{!0===e.checked&&delete e.checked,Array.isArray(e.items)&&e.items.forEach(e=>{!0===e.checked&&delete e.checked})}),l.checked=!0),"menu-check"==r.type)if(Array.isArray(r.selected)||(r.selected=[]),null==l.group){var n=r.selected.indexOf(l.id);-1==n?(r.selected.push(l.id),l.checked=!0):(r.selected.splice(n,1),l.checked=!1)}else if(!1!==l.group){let i=[];n=r.selected.indexOf(l.id);let s=e=>{e.forEach(e=>{var t;e.group===l.group&&-1!=(t=r.selected.indexOf(e.id))&&(e.id!=l.id&&i.push(e.id),r.selected.splice(t,1)),Array.isArray(e.items)&&s(e.items)})};s(e),-1==n&&(r.selected.push(l.id),l.checked=!0)}if("string"==typeof l.route){let t=""!==l.route?String("/"+l.route).replace(/\/{2,}/g,"/"):"";var s=w2utils.parseRoute(t);if(0{window.location.hash=t},1)}this.refresh(t.item.id),i.finish()}}}colorClick(e){var t;e.item&&!e.item.disabled&&!0!==(t=this.trigger("click",{target:e.item.id,item:e.item,color:e.color,final:e.final,originalEvent:e.originalEvent})).isCancelled&&(e.item.color=e.color,this.refresh(e.item.id),t.finish())}mouseAction(e,t,i,s){var l=this.get(s),e=this.trigger("mouse"+i,{target:s,item:l,object:l,originalEvent:e});if(!0!==e.isCancelled&&!l.disabled&&!l.hidden){switch(i){case"Enter":query(t).addClass("over"),this.tooltipShow(s);break;case"Leave":query(t).removeClass("over down"),this.tooltipHide(s);break;case"Down":query(t).addClass("down");break;case"Up":query(t).removeClass("down")}e.finish()}}}class w2sidebar extends w2base{constructor(e){super(e.name),this.name=null,this.box=null,this.sidebar=null,this.parent=null,this.nodes=[],this.menu=[],this.routeData={},this.selected=null,this.icon=null,this.style="",this.topHTML="",this.bottomHTML="",this.flatButton=!1,this.keyboard=!0,this.flat=!1,this.hasFocus=!1,this.levelPadding=12,this.skipRefresh=!1,this.tabIndex=null,this.handle={size:0,style:"",html:"",tooltip:""},this.onClick=null,this.onDblClick=null,this.onMouseEnter=null,this.onMouseLeave=null,this.onContextMenu=null,this.onMenuClick=null,this.onExpand=null,this.onCollapse=null,this.onKeydown=null,this.onRender=null,this.onRefresh=null,this.onResize=null,this.onDestroy=null,this.onFocus=null,this.onBlur=null,this.onFlat=null,this.node_template={id:null,text:"",order:null,count:null,icon:null,nodes:[],style:"",route:null,selected:!1,expanded:!1,hidden:!1,disabled:!1,group:!1,groupShowHide:!0,collapsible:!1,plus:!1,onClick:null,onDblClick:null,onContextMenu:null,onExpand:null,onCollapse:null,parent:null,sidebar:null},this.last={badge:{}};var t=e.nodes;delete e.nodes,Object.assign(this,e),Array.isArray(t)&&this.add(t),e.nodes=t,"string"==typeof this.box&&(this.box=query(this.box).get(0)),this.box&&this.render(this.box)}add(e,t){return 1==arguments.length&&(t=arguments[0],e=this),"string"==typeof e&&(e=this.get(e)),this.insert(e=null!=e&&""!=e?e:this,null,t)}insert(t,i,s){let l,r,n,a,o;if(2==arguments.length&&"string"==typeof t)if(s=arguments[1],null!=(i=arguments[0])){if(null==(r=this.get(i)))return null!=(s=Array.isArray(s)?s:[s])[0].caption&&null==s[0].text&&(console.log("NOTICE: sidebar node.caption property is deprecated, please use node.text. Node -> ",s[0]),s[0].text=s[0].caption),l=s[0].text,console.log('ERROR: Cannot insert node "'+l+'" because cannot find node "'+i+'" to insert before.'),null;t=this.get(i).parent}else t=this;null!=(t="string"==typeof t?this.get(t):t)&&""!=t||(t=this),Array.isArray(s)||(s=[s]);for(let e=0;e{null!=(i=this.get(e))&&(null!=this.selected&&this.selected===i.id&&(this.selected=null),null!=(e=this.get(i.parent,e,!0)))&&(i.parent.nodes[e].selected&&i.sidebar.unselect(i.id),i.parent.nodes.splice(e,1),i.parent.collapsible=0{var e=i.nodes&&0{e.nodes&&0{t.call(this,e),e.nodes&&0{-1===e.text.toLowerCase().indexOf(i)?e.hidden=!0:(t++,function e(t){t.parent&&(t.parent.hidden=!1,e(t.parent))}(e),e.hidden=!1)}),this.refresh(),t}show(){let t=[];return Array.from(arguments).forEach(e=>{e=this.get(e);null!=e&&!1!==e.hidden&&(e.hidden=!1,t.push(e.id))}),0{e=this.get(e);null!=e&&!0!==e.hidden&&(e.hidden=!0,t.push(e.id))}),0{e=this.get(e);null!=e&&!1!==e.disabled&&(e.disabled=!1,t.push(e.id))}),0{e=this.get(e);null!=e&&!0!==e.disabled&&(e.disabled=!0,e.selected&&this.unselect(e.id),t.push(e.id))}),0{t.refresh(e)},0),!0):void 0)}expand(e){var t=this.get(e),i=this.trigger("expand",{target:e,object:t});if(!0!==i.isCancelled)return query(this.box).find("#node_"+w2utils.escapeId(e)+"_sub").show(),query(this.box).find("#node_"+w2utils.escapeId(e)+" .w2ui-collapsed").removeClass("w2ui-collapsed").addClass("w2ui-expanded"),t.expanded=!0,i.finish(),this.refresh(e),!0}collapseAll(t){if(null==(t="string"==typeof(t=null==t?this:t)?this.get(t):t).nodes)return!1;for(let e=0;e{var t=query(e).attr("id").replace("node_",""),t=n.get(t);null!=t&&(t.selected=!1),query(e).removeClass("w2ui-selected").find(".w2ui-icon").removeClass("w2ui-icon-selected")});let t=query(n.box).find("#node_"+w2utils.escapeId(l)),s=query(n.box).find("#node_"+w2utils.escapeId(n.selected));t.addClass("w2ui-selected").find(".w2ui-icon").addClass("w2ui-icon-selected"),setTimeout(()=>{var e=n.trigger("click",{target:l,originalEvent:r,node:a,object:a});if(!0===e.isCancelled)t.removeClass("w2ui-selected").find(".w2ui-icon").removeClass("w2ui-icon-selected"),s.addClass("w2ui-selected").find(".w2ui-icon").addClass("w2ui-icon-selected");else{if(null!=s&&(s.selected=!1),n.get(l).selected=!0,n.selected=l,"string"==typeof a.route){let t=""!==a.route?String("/"+a.route).replace(/\/{2,}/g,"/"):"";var i=w2utils.parseRoute(t);if(0{window.location.hash=t},1)}e.finish()}},1)}}focus(e){let t=this;e=this.trigger("focus",{target:this.name,originalEvent:e});if(!0===e.isCancelled)return!1;this.hasFocus=!0,query(this.box).find(".w2ui-sidebar-body").addClass("w2ui-focus"),setTimeout(()=>{var e=query(t.box).find("#sidebar_"+t.name+"_focus").get(0);document.activeElement!=e&&e.focus()},10),e.finish()}blur(e){e=this.trigger("blur",{target:this.name,originalEvent:e});if(!0===e.isCancelled)return!1;this.hasFocus=!1,query(this.box).find(".w2ui-sidebar-body").removeClass("w2ui-focus"),e.finish()}keydown(e){let n=this,t=n.get(n.selected);var i;function s(e,t){null==e||e.hidden||e.disabled||e.group||(n.click(e.id,t),n.inView(e.id))||n.scrollIntoView(e.id)}function l(e,t){for(e=t(e);null!=e&&(e.hidden||e.disabled)&&!e.group;)e=t(e);return e}function r(e){if(null==e)return null;var t=e.parent,e=n.get(e.id,!0);let i=0t.clientHeight+t.scrollTop)}scrollIntoView(i,s){return new Promise((e,t)=>{null==i&&(i=this.selected),null!=this.get(i)&&(query(this.box).find("#node_"+w2utils.escapeId(i)).get(0).scrollIntoView({block:"center",inline:"center",behavior:s?"atuo":"smooth"}),setTimeout(()=>{this.resize(),e()},s?0:500))})}dblClick(e,t){var i=this.get(e),t=this.trigger("dblClick",{target:e,originalEvent:t,object:i});!0!==t.isCancelled&&(this.toggle(e),t.finish())}contextMenu(t,i){var e=this.get(t),s=(t!=this.selected&&this.click(t),this.trigger("contextMenu",{target:t,originalEvent:i,object:e,allowOnDisabled:!1}));!0===s.isCancelled||e.disabled&&!s.allowOnDisabled||(0{this.menuClick(t,parseInt(e.detail.index),i)}),i.preventDefault&&i.preventDefault(),s.finish())}menuClick(e,t,i){e=this.trigger("menuClick",{target:e,originalEvent:i,menuIndex:t,menuItem:this.menu[t]});!0!==e.isCancelled&&e.finish()}goFlat(){var e=this.trigger("flat",{goFlat:!this.flat});!0!==e.isCancelled&&(this.flat=!this.flat,this.refresh(),e.finish())}render(e){var i=Date.now();let s=this;"string"==typeof e&&(e=query(e).get(0));var l=this.trigger("render",{target:this.name,box:e??this.box});if(!0!==l.isCancelled&&(null!=e&&(0 +
    + +
    +
    + `);e=query(this.box).get(0).getBoundingClientRect();query(this.box).find(":scope > div").css({width:e.width+"px",height:e.height+"px"}),query(this.box).get(0).style.cssText+=this.style;let t;return query(this.box).find("#sidebar_"+this.name+"_focus").on("focus",function(e){clearTimeout(t),s.hasFocus||s.focus(e)}).on("blur",function(e){t=setTimeout(()=>{s.hasFocus&&s.blur(e)},100)}).on("keydown",function(e){9!=e.keyCode&&w2ui[s.name].keydown.call(w2ui[s.name],e)}),query(this.box).off("mousedown").on("mousedown",function(t){setTimeout(()=>{var e;-1==["INPUT","TEXTAREA","SELECT"].indexOf(t.target.tagName.toUpperCase())&&(e=query(s.box).find("#sidebar_"+s.name+"_focus"),document.activeElement!=e.get(0))&&e.get(0).focus()},1)}),this.last.observeResize=new ResizeObserver(()=>{this.resize()}),this.last.observeResize.observe(this.box),l.finish(),this.refresh(),Date.now()-i}}update(e,t){var i,s,e=this.get(e);let l;return e&&(i=query(this.box).find("#node_"+w2utils.escapeId(e.id)),e.group?(t.text&&(e.text=t.text,i.find(".w2ui-group-text").replace("function"==typeof e.text?e.text.call(this,e):''+e.text+""),delete t.text),t.class&&(e.class=t.class,l=i.data("level"),i.get(0).className="w2ui-node-group w2ui-level-"+l+(e.class?" "+e.class:""),delete t.class),t.style&&(e.style=t.style,i.get(0).nextElementSibling.style=e.style+";"+(!e.hidden&&e.expanded?"":"display: none;"),delete t.style)):(t.icon&&0<(s=i.find(".w2ui-node-image > span")).length&&(e.icon=t.icon,s[0].className="function"==typeof e.icon?e.icon.call(this,e):e.icon,delete t.icon),t.count&&(e.count=t.count,i.find(".w2ui-node-count").html(e.count),0`),null!=l||""===this.topHTML&&""===e||(query(this.box).find(".w2ui-sidebar-top").html(this.topHTML+e),query(this.box).find(".w2ui-sidebar-body").css("top",query(this.box).find(".w2ui-sidebar-top").get(0)?.clientHeight+"px"),query(this.box).find(".w2ui-flat").off("click").on("click",e=>{this.goFlat()})),null!=l&&""!==this.bottomHTML&&(query(this.box).find(".w2ui-sidebar-bottom").html(this.bottomHTML),query(this.box).find(".w2ui-sidebar-body").css("bottom",query(this.box).find(".w2ui-sidebar-bottom").get(0)?.clientHeight+"px")),query(this.box).find(":scope > div").removeClass("w2ui-sidebar-flat").addClass(this.flat?"w2ui-sidebar-flat":"").css({width:query(this.box).get(0)?.clientWidth+"px",height:query(this.box).get(0)?.clientHeight+"px"}),0'),query(this.box).find(o).remove(),query(this.box).find(i).remove(),query(this.box).find("#sidebar_"+this.name+"_tmp").before(s),query(this.box).find("#sidebar_"+this.name+"_tmp").remove());var l=query(this.box).find(":scope > div").get(0),d={top:l?.scrollTop,left:l?.scrollLeft};query(this.box).find(i).html("");for(let e=0;e ",t),t.text=t.caption),Array.isArray(t.nodes)&&0${e}
    `),i=` +
    + ${t.groupShowHide&&t.collapsible?`${!t.hidden&&t.expanded?w2utils.lang("Hide"):w2utils.lang("Show")}`:""} ${e} +
    +
    +
    `,h.flat&&(i=` +
     
    +
    `)}else{t.selected&&!t.disabled&&(h.selected=t.id),l="",s&&(l=` +
    + +
    `);let e="";var n=null!=t.count?`
    + ${t.count} +
    `:"",a=(!0===t.collapsible&&(e=`
    `),w2utils.lang("function"==typeof t.text?t.text.call(h,t):t.text)),o=["w2ui-node","w2ui-level-"+r,"w2ui-eaction"];t.selected&&o.push("w2ui-selected"),t.disabled&&o.push("w2ui-disabled"),t.class&&o.push(t.class),i=` +
    + ${h.handle.html?`
    + ${"function"==typeof h.handle.html?h.handle.html.call(h,t):h.handle.html} +
    `:""} +
    + ${e} ${l} ${n} +
    ${a}
    +
    +
    +
    `,h.flat&&(i=` +
    +
    ${l}
    +
    +
    `)}return i}}}}mouseAction(e,t,i,s,l){var r=this.get(i),n=w2utils.lang("function"==typeof r.text?r.text.call(this,r):r.text)+(r.count||0===r.count?' - '+r.count+"":""),e=this.trigger("mouse"+e,{target:i,node:r,tooltip:n,originalEvent:s});"tooltip"==l&&this.tooltip(t,n,i),"handle"==l&&this.handleTooltip(t,i),e.finish()}tooltip(e,t,i){e=query(e).find(".w2ui-node-data");""!==t?w2tooltip.show({anchor:e.get(0),name:this.name+"_tooltip",html:t,position:"right|left"}):w2tooltip.hide(this.name+"_tooltip")}handleTooltip(e,t){let i=this.handle.tooltip;""!==(i="function"==typeof i?i(t):i)&&null!=t?w2tooltip.show({anchor:e,name:this.name+"_tooltip",html:i,position:"top|bottom"}):w2tooltip.hide(this.name+"_tooltip")}showPlus(e,t){query(e).find("span:nth-child(1)").css("color",t)}resize(){var e,t=Date.now(),i=this.trigger("resize",{target:this.name});if(!0!==i.isCancelled)return e=query(this.box).get(0).getBoundingClientRect(),query(this.box).css("overflow","hidden"),query(this.box).find(":scope > div").css({width:e.width+"px",height:e.height+"px"}),i.finish(),Date.now()-t}destroy(){var e=this.trigger("destroy",{target:this.name});!0!==e.isCancelled&&(0{var t,i;null==e.id?console.log(`ERROR: The parameter "id" is required but not supplied. (obj: ${this.name})`):w2utils.checkUniqueId(e.id,this.tabs,"tabs",this.name)&&(e=Object.assign({},this.tab_template,e),null==s?(this.tabs.push(e),l.push(this.animateInsert(null,e))):(t=this.get(s,!0),i=this.tabs[t].id,this.tabs.splice(t,0,e),l.push(this.animateInsert(i,e))))}),Promise.all(l)}remove(){let t=0;return Array.from(arguments).forEach(e=>{e=this.get(e);e&&(t++,this.tabs.splice(this.get(e.id,!0),1),query(this.box).find(`#tabs_${this.name}_tab_`+w2utils.escapeId(e.id)).remove())}),this.resize(),t}select(e){return this.active!=e&&null!=this.get(e)&&(this.active=e,this.refresh(),!0)}set(e,t){var i=this.get(e,!0);return null!=i&&(w2utils.extend(this.tabs[i],t),this.refresh(e),!0)}get(t,i){if(0===arguments.length){var s=[];for(let e=0;e{e=this.get(e);e&&!1!==e.hidden&&(e.hidden=!1,t.push(e.id))}),setTimeout(()=>{t.forEach(e=>{this.refresh(e),this.resize()})},15),t}hide(){let t=[];return Array.from(arguments).forEach(e=>{e=this.get(e);e&&!0!==e.hidden&&(e.hidden=!0,t.push(e.id))}),setTimeout(()=>{t.forEach(e=>{this.refresh(e),this.resize()})},15),t}enable(){let t=[];return Array.from(arguments).forEach(e=>{e=this.get(e);e&&!1!==e.disabled&&(e.disabled=!1,t.push(e.id))}),setTimeout(()=>{t.forEach(e=>{this.refresh(e)})},15),t}disable(){let t=[];return Array.from(arguments).forEach(e=>{e=this.get(e);e&&!0!==e.disabled&&(e.disabled=!0,t.push(e.id))}),setTimeout(()=>{t.forEach(e=>{this.refresh(e)})},15),t}dragMove(i){if(this.last.reordering){let s=this;var l=this.last.moving,r=this.tabs[l.index],n=h(l.index,1),a=h(l.index,-1),r=query(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(r.id));if(0t)return n=this.tabs.indexOf(n),this.tabs.splice(l.index,0,this.tabs.splice(n,1)[0]),l.$tab.before(o.get(0)),l.$tab.css("opacity",0),void Object.assign(this.last.moving,{index:n,divX:-e,x:i.pageX+e,left:l.left+l.divX+e})}if(l.divX<0&&a){o=query(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(a.id));let e=parseInt(r.get(0).clientWidth),t=parseInt(o.get(0).clientWidth);e=et&&(n=this.tabs.indexOf(a),this.tabs.splice(l.index,0,this.tabs.splice(n,1)[0]),o.before(l.$tab),l.$tab.css("opacity",0),Object.assign(l,{index:n,divX:e,x:i.pageX-e,left:l.left+l.divX-e}))}function h(e,t){e+=t;let i=s.tabs[e];return i=i&&i.hidden?h(e,t):i}}}mouseAction(e,t,i){var s=this.get(t),l=this.trigger("mouse"+e,{target:t,tab:s,object:s,originalEvent:i});if(!0!==l.isCancelled&&!s.disabled&&!s.hidden){switch(e){case"Enter":this.tooltipShow(t);break;case"Leave":this.tooltipHide(t);break;case"Down":this.initReorder(t,i)}l.finish()}}tooltipShow(t){var i=this.get(t),t=query(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(t)).get(0);if(null!=this.tooltip&&!i.disabled&&!this.last.reordering){var s=this.tooltip;let e=i.tooltip;"function"==typeof e&&(e=e.call(this,i)),w2tooltip.show({anchor:t,name:this.name+"_tooltip",html:e,position:s})}}tooltipHide(e){null!=this.tooltip&&w2tooltip.hide(this.name+"_tooltip")}getTabHTML(e){e=this.get(e,!0),e=this.tabs[e];if(null==e)return!1;null==e.text&&null!=e.caption&&(e.text=e.caption),null==e.tooltip&&null!=e.hint&&(e.tooltip=e.hint),null!=e.caption&&console.log("NOTICE: tabs tab.caption property is deprecated, please use tab.text. Tab -> ",e),null!=e.hint&&console.log("NOTICE: tabs tab.hint property is deprecated, please use tab.tooltip. Tab -> ",e);let t=e.text,i=(null==(t="function"==typeof t?t.call(this,e):t)&&(t=""),""),s="";return e.hidden&&(s+="display: none;"),e.disabled&&(s+="opacity: 0.2;"),e.closable&&!e.disabled&&(i=`
    +
    `),` +
    + ${w2utils.lang(t)+i} +
    `}refresh(e){var t=Date.now(),i=("up"==this.flow?query(this.box).addClass("w2ui-tabs-up"):query(this.box).removeClass("w2ui-tabs-up"),this.trigger("refresh",{target:null!=e?e:this.name,object:this.get(e)}));if(!0!==i.isCancelled){if(null==e)for(let e=0;e +
    +
    ${this.right}
    +
    +
    +
    `,query(this.box).attr("name",this.name).addClass("w2ui-reset w2ui-tabs").html(e),0{this.resize()}),this.last.observeResize.observe(this.box),i.finish(),this.refresh(),this.resize(),Date.now()-t)}initReorder(e,n){if(this.reorder){let t=this,i=query(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(e)),s=this.get(e,!0),l=query(i.get(0).cloneNode(!0)),r;l.attr("id","#tabs_"+this.name+"_tab_ghost"),this.last.moving={index:s,indexFrom:s,$tab:i,$ghost:l,divX:0,left:i.get(0).getBoundingClientRect().left,parentX:query(this.box).get(0).getBoundingClientRect().left,x:n.pageX,opacity:i.css("opacity")},query(document).off(".w2uiTabReorder").on("mousemove.w2uiTabReorder",function(e){if(!t.last.reordering){if(!0===(r=t.trigger("reorder",{target:t.tabs[s].id,indexFrom:s,tab:t.tabs[s]})).isCancelled)return;w2tooltip.hide(this.name+"_tooltip"),t.last.reordering=!0,l.addClass("moving"),l.css({"pointer-events":"none",position:"absolute",left:i.get(0).getBoundingClientRect().left}),i.css("opacity",0),query(t.box).find(".w2ui-scroll-wrapper").append(l.get(0)),query(t.box).find(".w2ui-tab-close").hide()}t.last.moving.divX=e.pageX-t.last.moving.x,l.css("left",t.last.moving.left-t.last.moving.parentX+t.last.moving.divX+"px"),t.dragMove(e)}).on("mouseup.w2uiTabReorder",function(){query(document).off(".w2uiTabReorder"),l.css({transition:"0.1s",left:t.last.moving.$tab.get(0).getBoundingClientRect().left-t.last.moving.parentX}),query(t.box).find(".w2ui-tab-close").show(),setTimeout(()=>{l.remove(),i.css({opacity:t.last.moving.opacity}),t.last.reordering&&r.finish({indexTo:t.last.moving.index}),t.last.reordering=!1},100)})}}scroll(a,o){return new Promise((e,t)=>{var i=query(this.box).find(".w2ui-scroll-wrapper"),s=i.get(0).scrollLeft,l=i.find(".w2ui-tabs-right").get(0),r=i.parent().get(0).getBoundingClientRect().width,n=s+parseInt(l.offsetLeft)+parseInt(l.clientWidth);switch(a){case"left":{let e=s-r+50;e<=0&&(e=0),i.get(0).scrollTo({top:0,left:e,behavior:o?"atuo":"smooth"});break}case"right":{let e=s+r-50;e>=n-r&&(e=n-r),i.get(0).scrollTo({top:0,left:e,behavior:o?"atuo":"smooth"});break}}setTimeout(()=>{this.resize(),e()},o?0:350)})}scrollIntoView(i,s){return new Promise((e,t)=>{null==i&&(i=this.active),null!=this.get(i)&&(query(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(i)).get(0).scrollIntoView({block:"start",inline:"center",behavior:s?"atuo":"smooth"}),setTimeout(()=>{this.resize(),e()},s?0:500))})}resize(){var e=Date.now();if(null!=this.box){var t,i,s,l,r=this.trigger("resize",{target:this.name});if(!0!==r.isCancelled)return(t=query(this.box)).find(".w2ui-scroll-left, .w2ui-scroll-right").hide(),i=t.find(".w2ui-scroll-wrapper").get(0),l=t.find(".w2ui-tabs-right"),(s=t.get(0).getBoundingClientRect().width)<(l=0{window.location.hash=t},1)}e.finish()}}clickClose(e,t){var i=this.get(e);if(null==i||i.disabled)return!1;let s=this.trigger("close",{target:e,object:i,tab:i,originalEvent:t});!0!==s.isCancelled&&(this.animateClose(e).then(()=>{this.remove(e),s.finish(),this.refresh()}),t)&&t.stopPropagation()}animateClose(r){return new Promise((e,t)=>{var i=query(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(r)),s=parseInt(i.get(0).clientWidth||0);let l=i.replace(`
    `);setTimeout(()=>{l.css({width:"0px"})},1),setTimeout(()=>{l.remove(),this.resize(),e()},500)})}animateInsert(t,r){return new Promise((i,e)=>{let s=query(this.box).find("#tabs_"+this.name+"_tab_"+w2utils.escapeId(t)),l=query.html(this.getTabHTML(r.id));if(0==s.length)(s=query(this.box).find("#tabs_tabs_right")).before(l),this.resize();else{l.css({opacity:0}),query(this.box).find("#tabs_tabs_right").before(l.get(0));let e=query(this.box).find("#"+l.attr("id")).get(0).clientWidth??0,t=query.html('
    ');s.before(t),l.hide(),t.before(l[0]),setTimeout(()=>{t.css({width:e+"px"})},1),setTimeout(()=>{t.remove(),l.css({opacity:1}).show(),this.refresh(r.id),this.resize(),i()},500)}})}}let w2panels=["top","left","main","preview","right","bottom"];class w2layout extends w2base{constructor(e){super(e.name),this.box=null,this.name=null,this.panels=[],this.last={},this.padding=1,this.resizer=4,this.style="",this.onShow=null,this.onHide=null,this.onResizing=null,this.onResizerClick=null,this.onRender=null,this.onRefresh=null,this.onChange=null,this.onResize=null,this.onDestroy=null,this.panel_template={type:null,title:"",size:100,minSize:20,maxSize:!1,hidden:!1,resizable:!1,overflow:"auto",style:"",html:"",tabs:null,toolbar:null,width:null,height:null,show:{toolbar:!1,tabs:!1},removed:null,onRefresh:null,onShow:null,onHide:null},Object.assign(this,e),Array.isArray(this.panels)||(this.panels=[]),this.panels.forEach((e,t)=>{var i,s,l;this.panels[t]=w2utils.extend({},this.panel_template,e),(w2utils.isPlainObject(e.tabs)||Array.isArray(e.tabs))&&function(e,t,i){var s=e.get(t);null!=s&&null==i&&(i=s.tabs);if(null==s||null==i)return;Array.isArray(i)&&(i={tabs:i});var l=e.name+"_"+t+"_tabs";w2ui[l]&&w2ui[l].destroy();s.tabs=new w2tabs(w2utils.extend({},i,{owner:e,name:e.name+"_"+t+"_tabs"})),s.show.tabs=!0}(this,e.type),(w2utils.isPlainObject(e.toolbar)||Array.isArray(e.toolbar))&&(t=this,e=e.type,i=void 0,null!=(s=t.get(e))&&null==i&&(i=s.toolbar),null!=s)&&null!=i&&(Array.isArray(i)&&(i={items:i}),l=t.name+"_"+e+"_toolbar",w2ui[l]&&w2ui[l].destroy(),s.toolbar=new w2toolbar(w2utils.extend({},i,{owner:t,name:t.name+"_"+e+"_toolbar"})),s.show.toolbar=!0)}),w2panels.forEach(e=>{null==this.get(e)&&this.panels.push(w2utils.extend({},this.panel_template,{type:e,hidden:"main"!==e,size:50}))}),"string"==typeof this.box&&(this.box=query(this.box).get(0)),this.box&&this.render(this.box)}html(l,r,n){let a=this.get(l);var e={panel:l,html:a.html,error:!1,cancelled:!1,removed(e){"function"==typeof e&&(a.removed=e)}};if("function"==typeof a.removed&&(a.removed({panel:l,html:a.html,html_new:r,transition:n||"none"}),a.removed=null),"css"==l)query(this.box).find("#layout_"+this.name+"_panel_css").html(""),e.status=!0;else if(null==a)console.log("ERROR: incorrect panel name. Panel name can be main, left, right, top, bottom, preview or css"),e.error=!0;else if(null!=r){var t=this.trigger("change",{target:l,panel:a,html_new:r,transition:n});if(!0===t.isCancelled)e.cancelled=!0;else{let i="#layout_"+this.name+"_panel_"+a.type;var o=query(this.box).find(i+"> .w2ui-panel-content");let s=0;if(0 .w2ui-panel-content"),t=(e.after('
    '),query(this.box).find(i+"> .w2ui-panel-content.new-panel"));e.css("top",s),t.css("top",s),"object"==typeof r?(r.box=t[0],r.render()):t.hide().html(r),w2utils.transition(e[0],t[0],n,()=>{e.remove(),t.removeClass("new-panel"),t.css("overflow",a.overflow),query(query(this.box).find(i+"> .w2ui-panel-content").get(1)).remove(),query(this.box).removeClass("animating"),this.refresh(l)})}else this.refresh(l);t.finish()}}return e}message(e,t){var i=this.get(e);let s=query(this.box).find("#layout_"+this.name+"_panel_"+i.type),l=s.css("overflow");s.css("overflow","hidden");i=w2utils.message({owner:this,box:s.get(0),after:".w2ui-panel-title",param:e},t);return i&&i.self.on("close:after",()=>{s.css("overflow",l)}),i}confirm(e,t){var i=this.get(e);let s=query(this.box).find("#layout_"+this.name+"_panel_"+i.type),l=s.css("overflow");s.css("overflow","hidden");i=w2utils.confirm({owner:this,box:s.get(0),after:".w2ui-panel-title",param:e},t);return i&&i.self.on("close:after",()=>{s.css("overflow",l)}),i}load(i,s,l){return new Promise((t,e)=>{"css"!=i&&null==this.get(i)||null==s?e():fetch(s).then(e=>e.text()).then(e=>{this.resize(),t(this.html(i,e,l))})})}sizeTo(e,t,i){return null!=this.get(e)&&(query(this.box).find(":scope > div > .w2ui-panel").css("transition",!0!==i?".2s":"0s"),setTimeout(()=>{this.set(e,{size:t})},1),setTimeout(()=>{query(this.box).find(":scope > div > .w2ui-panel").css("transition","0s"),this.resize()},300),!0)}show(e,t){let i=this.trigger("show",{target:e,thisect:this.get(e),immediate:t});var s;if(!0!==i.isCancelled)return null!=(s=this.get(e))&&(!(s.hidden=!1)===t?(query(this.box).find("#layout_"+this.name+"_panel_"+e).css({opacity:"1"}),i.finish(),this.resize()):(query(this.box).addClass("animating"),query(this.box).find("#layout_"+this.name+"_panel_"+e).css({opacity:"0"}),query(this.box).find(":scope > div > .w2ui-panel").css("transition",".2s"),setTimeout(()=>{this.resize()},1),setTimeout(()=>{query(this.box).find("#layout_"+this.name+"_panel_"+e).css({opacity:"1"})},250),setTimeout(()=>{query(this.box).find(":scope > div > .w2ui-panel").css("transition","0s"),query(this.box).removeClass("animating"),i.finish(),this.resize()},300)),!0)}hide(e,t){let i=this.trigger("hide",{target:e,object:this.get(e),immediate:t});var s;if(!0!==i.isCancelled)return null!=(s=this.get(e))&&((s.hidden=!0)===t?(query(this.box).find("#layout_"+this.name+"_panel_"+e).css({opacity:"0"}),i.finish(),this.resize()):(query(this.box).addClass("animating"),query(this.box).find(":scope > div > .w2ui-panel").css("transition",".2s"),query(this.box).find("#layout_"+this.name+"_panel_"+e).css({opacity:"0"}),setTimeout(()=>{this.resize()},1),setTimeout(()=>{query(this.box).find(":scope > div > .w2ui-panel").css("transition","0s"),query(this.box).removeClass("animating"),i.finish(),this.resize()},300)),!0)}toggle(e,t){var i=this.get(e);return null!=i&&(i.hidden?this.show(e,t):this.hide(e,t))}set(e,t){var i=this.get(e,!0);return null!=i&&(w2utils.extend(this.panels[i],t),null==t.html&&null==t.resizable||this.refresh(e),this.resize(),!0)}get(t,i){for(let e=0;e .w2ui-panel-content");return 1!=e.length?null:e[0]}hideToolbar(e){var t=this.get(e);t&&(t.show.toolbar=!1,query(this.box).find("#layout_"+this.name+"_panel_"+e+"> .w2ui-panel-toolbar").hide(),this.resize())}showToolbar(e){var t=this.get(e);t&&(t.show.toolbar=!0,query(this.box).find("#layout_"+this.name+"_panel_"+e+"> .w2ui-panel-toolbar").show(),this.resize())}toggleToolbar(e){var t=this.get(e);t&&(t.show.toolbar?this.hideToolbar(e):this.showToolbar(e))}assignToolbar(e,t){"string"==typeof t&&null!=w2ui[t]&&(t=w2ui[t]);var i=this.get(e),s=(i.toolbar=t,query(this.box).find(e+"> .w2ui-panel-toolbar"));null!=i.toolbar?(0===s.find("[name="+i.toolbar.name+"]").length?i.toolbar.render(s.get(0)):null!=i.toolbar&&i.toolbar.refresh(),(t.owner=this).showToolbar(e),this.refresh(e)):(s.html(""),this.hideToolbar(e))}hideTabs(e){var t=this.get(e);t&&(t.show.tabs=!1,query(this.box).find("#layout_"+this.name+"_panel_"+e+"> .w2ui-panel-tabs").hide(),this.resize())}showTabs(e){var t=this.get(e);t&&(t.show.tabs=!0,query(this.box).find("#layout_"+this.name+"_panel_"+e+"> .w2ui-panel-tabs").show(),this.resize())}toggleTabs(e){var t=this.get(e);t&&(t.show.tabs?this.hideTabs(e):this.showTabs(e))}render(e){var t=Date.now();let o=this;"string"==typeof e&&(e=query(e).get(0));var i=this.trigger("render",{target:this.name,box:e??this.box});if(!0!==i.isCancelled){if(null!=e&&(0"),0
    ';query(this.box).find(":scope > div").append(s)}return query(this.box).find(":scope > div").append('
    '),this.refresh(),this.last.observeResize=new ResizeObserver(()=>{this.resize()}),this.last.observeResize.observe(this.box),i.finish(),setTimeout(()=>{o.last.events={resizeStart:l,mouseMove:n,mouseUp:r},this.resize()},0),Date.now()-t}function l(e,t){o.box&&(t=t||window.event,query(document).off("mousemove",o.last.events.mouseMove).on("mousemove",o.last.events.mouseMove),query(document).off("mouseup",o.last.events.mouseUp).on("mouseup",o.last.events.mouseUp),o.last.resize={type:e,x:t.screenX,y:t.screenY,diff_x:0,diff_y:0,value:0},w2panels.forEach(e=>{var t=query(o.el(e)).find(".w2ui-lock");0{var t=query(o.el(e)).find(".w2ui-lock");"yes"==t.data("locked")?t.removeData("locked"):o.unlock(e)}),0!==o.last.diff_x||0!==o.last.resize.diff_y){var s=o.get("top"),l=o.get("bottom"),r=o.get(o.last.resize.type),i=w2utils.getSize(query(o.box),"width"),n=w2utils.getSize(query(o.box),"height"),a=String(r.size);let e,t;switch(o.last.resize.type){case"top":e=parseInt(r.sizeCalculated)+o.last.resize.diff_y,t=0;break;case"bottom":e=parseInt(r.sizeCalculated)-o.last.resize.diff_y,t=0;break;case"preview":e=parseInt(r.sizeCalculated)-o.last.resize.diff_y,t=(s&&!s.hidden?s.sizeCalculated:0)+(l&&!l.hidden?l.sizeCalculated:0);break;case"left":e=parseInt(r.sizeCalculated)+o.last.resize.diff_x,t=0;break;case"right":e=parseInt(r.sizeCalculated)-o.last.resize.diff_x,t=0}"%"==a.substr(a.length-1)?r.size=Math.floor(100*e/("left"==r.type||"right"==r.type?i:n-t)*100)/100+"%":"-"==String(r.size).substr(0,1)?r.size=parseInt(r.size)-r.sizeCalculated+e:r.size=e,o.resize()}query(o.box).find("#layout_"+o.name+"_resizer_"+o.last.resize.type).removeClass("active"),delete o.last.resize}}function n(i){if(o.box&&(i=i||window.event,null!=o.last.resize)){var s=o.get(o.last.resize.type),l=o.last.resize,r=o.trigger("resizing",{target:o.name,object:s,originalEvent:i,panel:l?l.type:"all",diff_x:l?l.diff_x:0,diff_y:l?l.diff_y:0});if(!0!==r.isCancelled){var n=query(o.box).find("#layout_"+o.name+"_resizer_"+l.type);let e=i.screenX-l.x,t=i.screenY-l.y;var a=o.get("main");switch(n.hasClass("active")||n.addClass("active"),l.type){case"left":s.minSize-e>s.width&&(e=s.minSize-s.width),s.maxSize&&s.width+e>s.maxSize&&(e=s.maxSize-s.width),a.minSize+e>a.width&&(e=a.width-a.minSize);break;case"right":s.minSize+e>s.width&&(e=s.width-s.minSize),s.maxSize&&s.width-e>s.maxSize&&(e=s.width-s.maxSize),a.minSize-e>a.width&&(e=a.minSize-a.width);break;case"top":s.minSize-t>s.height&&(t=s.minSize-s.height),s.maxSize&&s.height+t>s.maxSize&&(t=s.maxSize-s.height),a.minSize+t>a.height&&(t=a.height-a.minSize);break;case"preview":case"bottom":s.minSize+t>s.height&&(t=s.height-s.minSize),s.maxSize&&s.height-t>s.maxSize&&(t=s.height-s.maxSize),a.minSize-t>a.height&&(t=a.minSize-a.height)}switch(l.diff_x=e,l.diff_y=t,l.type){case"top":case"preview":case"bottom":(l.diff_x=0) .w2ui-panel-content")[0],setTimeout(()=>{0 .w2ui-panel-content").length&&(query(l.box).find(t+"> .w2ui-panel-content").removeClass().removeAttr("name").addClass("w2ui-panel-content").css("overflow",e.overflow)[0].style.cssText+=";"+e.style),e.html&&"function"==typeof e.html.render&&e.html.render()},1)):0 .w2ui-panel-content").length&&(query(l.box).find(t+"> .w2ui-panel-content").removeClass().removeAttr("name").addClass("w2ui-panel-content").html(e.html).css("overflow",e.overflow)[0].style.cssText+=";"+e.style);let i=query(l.box).find(t+"> .w2ui-panel-tabs");e.show.tabs?0===i.find("[name="+e.tabs.name+"]").length&&null!=e.tabs?e.tabs.render(i.get(0)):e.tabs.refresh():i.html("").removeClass("w2ui-tabs").hide(),i=query(l.box).find(t+"> .w2ui-panel-toolbar"),e.show.toolbar?0===i.find("[name="+e.toolbar.name+"]").length&&null!=e.toolbar?e.toolbar.render(i.get(0)):e.toolbar.refresh():i.html("").removeClass("w2ui-toolbar").hide(),i=query(l.box).find(t+"> .w2ui-panel-title"),e.title?i.html(e.title).show():i.html("").hide()}else{if(0===query(l.box).find("#layout_"+l.name+"_panel_main").length)return void l.render();l.resize();for(let e=0;ethis.padding?this.resizer:this.padding,query(this.box).find("#layout_"+this.name+"_resizer_top").css({display:"block",left:e+"px",top:t+"px",width:s+"px",height:l+"px",cursor:"ns-resize"}).off("mousedown").on("mousedown",function(e){e.preventDefault();var t=i.trigger("resizerClick",{target:"top",originalEvent:e});if(!0!==t.isCancelled)return w2ui[i.name].last.events.resizeStart("top",e),t.finish(),!1}))):(query(this.box).find("#layout_"+this.name+"_panel_top").hide(),query(this.box).find("#layout_"+this.name+"_resizer_top").hide()),null!=c&&!0!==c.hidden?(e=0,t=0+(b?f.sizeCalculated+this.padding:0),s=c.sizeCalculated,l=h-(b?f.sizeCalculated+this.padding:0)-(v?m.sizeCalculated+this.padding:0),query(this.box).find("#layout_"+this.name+"_panel_left").css({display:"block",left:e+"px",top:t+"px",width:s+"px",height:l+"px"}),c.width=s,c.height=l,c.resizable&&(e=c.sizeCalculated-(0===this.padding?this.resizer:0),s=this.resizer>this.padding?this.resizer:this.padding,query(this.box).find("#layout_"+this.name+"_resizer_left").css({display:"block",left:e+"px",top:t+"px",width:s+"px",height:l+"px",cursor:"ew-resize"}).off("mousedown").on("mousedown",function(e){e.preventDefault();var t=i.trigger("resizerClick",{target:"left",originalEvent:e});if(!0!==t.isCancelled)return w2ui[i.name].last.events.resizeStart("left",e),t.finish(),!1}))):(query(this.box).find("#layout_"+this.name+"_panel_left").hide(),query(this.box).find("#layout_"+this.name+"_resizer_left").hide()),null!=p&&!0!==p.hidden?(e=o-p.sizeCalculated,t=0+(b?f.sizeCalculated+this.padding:0),s=p.sizeCalculated,l=h-(b?f.sizeCalculated+this.padding:0)-(v?m.sizeCalculated+this.padding:0),query(this.box).find("#layout_"+this.name+"_panel_right").css({display:"block",left:e+"px",top:t+"px",width:s+"px",height:l+"px"}),p.width=s,p.height=l,p.resizable&&(e-=this.padding,s=this.resizer>this.padding?this.resizer:this.padding,query(this.box).find("#layout_"+this.name+"_resizer_right").css({display:"block",left:e+"px",top:t+"px",width:s+"px",height:l+"px",cursor:"ew-resize"}).off("mousedown").on("mousedown",function(e){e.preventDefault();var t=i.trigger("resizerClick",{target:"right",originalEvent:e});if(!0!==t.isCancelled)return w2ui[i.name].last.events.resizeStart("right",e),t.finish(),!1}))):(query(this.box).find("#layout_"+this.name+"_panel_right").hide(),query(this.box).find("#layout_"+this.name+"_resizer_right").hide()),null!=m&&!0!==m.hidden?(e=0,t=h-m.sizeCalculated,s=o,l=m.sizeCalculated,query(this.box).find("#layout_"+this.name+"_panel_bottom").css({display:"block",left:e+"px",top:t+"px",width:s+"px",height:l+"px"}),m.width=s,m.height=l,m.resizable&&(t-=0===this.padding?0:this.padding,l=this.resizer>this.padding?this.resizer:this.padding,query(this.box).find("#layout_"+this.name+"_resizer_bottom").css({display:"block",left:e+"px",top:t+"px",width:s+"px",height:l+"px",cursor:"ns-resize"}).off("mousedown").on("mousedown",function(e){e.preventDefault();var t=i.trigger("resizerClick",{target:"bottom",originalEvent:e});if(!0!==t.isCancelled)return w2ui[i.name].last.events.resizeStart("bottom",e),t.finish(),!1}))):(query(this.box).find("#layout_"+this.name+"_panel_bottom").hide(),query(this.box).find("#layout_"+this.name+"_resizer_bottom").hide()),e=0+(y?c.sizeCalculated+this.padding:0),t=0+(b?f.sizeCalculated+this.padding:0),s=o-(y?c.sizeCalculated+this.padding:0)-(w?p.sizeCalculated+this.padding:0),l=h-(b?f.sizeCalculated+this.padding:0)-(v?m.sizeCalculated+this.padding:0)-(g?u.sizeCalculated+this.padding:0),query(this.box).find("#layout_"+this.name+"_panel_main").css({display:"block",left:e+"px",top:t+"px",width:s+"px",height:l+"px"}),d.width=s,d.height=l,null!=u&&!0!==u.hidden?(e=0+(y?c.sizeCalculated+this.padding:0),t=h-(v?m.sizeCalculated+this.padding:0)-u.sizeCalculated,s=o-(y?c.sizeCalculated+this.padding:0)-(w?p.sizeCalculated+this.padding:0),l=u.sizeCalculated,query(this.box).find("#layout_"+this.name+"_panel_preview").css({display:"block",left:e+"px",top:t+"px",width:s+"px",height:l+"px"}),u.width=s,u.height=l,u.resizable&&(t-=0===this.padding?0:this.padding,l=this.resizer>this.padding?this.resizer:this.padding,query(this.box).find("#layout_"+this.name+"_resizer_preview").css({display:"block",left:e+"px",top:t+"px",width:s+"px",height:l+"px",cursor:"ns-resize"}).off("mousedown").on("mousedown",function(e){e.preventDefault();var t=i.trigger("resizerClick",{target:"preview",originalEvent:e});if(!0!==t.isCancelled)return w2ui[i.name].last.events.resizeStart("preview",e),t.finish(),!1}))):(query(this.box).find("#layout_"+this.name+"_panel_preview").hide(),query(this.box).find("#layout_"+this.name+"_resizer_preview").hide());for(let t=0;t .w2ui-panel-";let e=0;q&&(q.title&&(_=query(this.box).find(C+"title").css({top:e+"px",display:"block"}),e+=w2utils.getSize(_,"height")),q.show.tabs&&(_=query(this.box).find(C+"tabs").css({top:e+"px",display:"block"}),e+=w2utils.getSize(_,"height")),q.show.toolbar)&&(q=query(this.box).find(C+"toolbar").css({top:e+"px",display:"block"}),e+=w2utils.getSize(q,"height")),query(this.box).find(C+"content").css({display:"block"}).css({top:e+"px"})}return a.finish(),Date.now()-r}}destroy(){var e=this.trigger("destroy",{target:this.name});if(!0!==e.isCancelled)return null!=w2ui[this.name]&&(0'},add:{type:"button",id:"w2ui-add",text:"Add New",tooltip:"Add new record",icon:"w2ui-icon-plus"},edit:{type:"button",id:"w2ui-edit",text:"Edit",tooltip:"Edit selected record",icon:"w2ui-icon-pencil",batch:1,disabled:!0},delete:{type:"button",id:"w2ui-delete",text:"Delete",tooltip:"Delete selected records",icon:"w2ui-icon-cross",batch:!0,disabled:!0},save:{type:"button",id:"w2ui-save",text:"Save",tooltip:"Save changed records",icon:"w2ui-icon-check"}},this.operators={text:["is","begins","contains","ends"],number:["=","between",">","<",">=","<="],date:["is",{oper:"less",text:"before"},{oper:"more",text:"since"},"between"],list:["is"],hex:["is","between"],color:["is","begins","contains","ends"],enum:["in","not in"]},this.defaultOperator={text:"begins",number:"=",date:"is",list:"is",enum:"in",hex:"begins",color:"begins"},this.operatorsMap={text:"text",int:"number",float:"number",money:"number",currency:"number",percent:"number",hex:"hex",alphanumeric:"text",color:"color",date:"date",time:"date",datetime:"date",list:"list",combo:"text",enum:"enum",file:"enum",select:"list",radio:"list",checkbox:"list",toggle:"list"},this.onAdd=null,this.onEdit=null,this.onRequest=null,this.onLoad=null,this.onDelete=null,this.onSave=null,this.onSelect=null,this.onClick=null,this.onDblClick=null,this.onContextMenu=null,this.onContextMenuClick=null,this.onColumnClick=null,this.onColumnDblClick=null,this.onColumnContextMenu=null,this.onColumnResize=null,this.onColumnAutoResize=null,this.onSort=null,this.onSearch=null,this.onSearchOpen=null,this.onChange=null,this.onRestore=null,this.onExpand=null,this.onCollapse=null,this.onError=null,this.onKeydown=null,this.onToolbar=null,this.onColumnOnOff=null,this.onCopy=null,this.onPaste=null,this.onSelectionExtend=null,this.onEditField=null,this.onRender=null,this.onRefresh=null,this.onReload=null,this.onResize=null,this.onDestroy=null,this.onStateSave=null,this.onStateRestore=null,this.onFocus=null,this.onBlur=null,this.onReorderRow=null,this.onSearchSave=null,this.onSearchRemove=null,this.onSearchSelect=null,this.onColumnSelect=null,this.onColumnDragStart=null,this.onColumnDragEnd=null,this.onResizerDblClick=null,this.onMouseEnter=null,this.onMouseLeave=null,w2utils.extend(this,e),Array.isArray(this.records)){let i=[];this.records.forEach((e,t)=>{null!=e[this.recid]&&(e.recid=e[this.recid]),null==e.recid&&console.log("ERROR: Cannot add records without recid. (obj: "+this.name+")"),!0===e.w2ui?.summary&&(this.summary.push(e),i.push(t))}),i.sort();for(let e=i.length-1;0<=e;e--)this.records.splice(i[e],1)}Array.isArray(this.columns)&&this.columns.forEach((i,e)=>{i=w2utils.extend({},this.colTemplate,i);e=(this.columns[e]=i).searchable;if(null!=e&&!1!==e&&null==this.getSearch(i.field))if(w2utils.isPlainObject(e))this.addSearch(w2utils.extend({field:i.field,label:i.text,type:"text"},e));else{let e=i.searchable,t="";!0===i.searchable&&(e="text",t='size="20"'),this.addSearch({field:i.field,label:i.text,type:e,attr:t})}}),Array.isArray(this.defaultSearches)&&this.defaultSearches.forEach((e,t)=>{e.id="default-"+t,e.icon??="w2ui-icon-search"});e=this.cache("searches");Array.isArray(e)&&e.forEach(e=>{this.savedSearches.push({id:e.id??"none",text:e.text??"none",icon:"w2ui-icon-search",remove:!0,logic:e.logic??"AND",data:e.data??[]})}),"string"==typeof this.box&&(this.box=query(this.box).get(0)),this.box&&this.render(this.box)}add(t,i){Array.isArray(t)||(t=[t]);let s=0;for(let e=0;ethis.records.length&&(a=this.records.length);for(let i=n;i{this.columns.forEach(i=>{if(i.field==e){let t=w2utils.clone(s);Object.keys(t).forEach(e=>{"function"==typeof t[e]&&(t[e]=t[e](i)),i[e]!=t[e]&&l++}),w2utils.extend(i,t)}})}),0{if(!(e.w2ui&&null!=e.w2ui.parent_recid||t.w2ui&&null!=t.w2ui.parent_recid))return o(e,t);var i=n(e),s=n(t);for(let e=0;es.length?1:i.length{this.status(w2utils.lang("Sorting took ${count} seconds",{count:e/1e3}))},10),e;function n(e){var t;return e.w2ui&&null!=e.w2ui.parent_recid?e.w2ui._path||((t=a.get(e.w2ui.parent_recid))?n(t).concat(e):(console.log("ERROR: no parent record: "+e.w2ui.parent_recid),[e])):[e]}function o(s,l){if(s===l)return 0;for(let i=0;it.constructor.name?s:-s;e&&"object"==typeof e&&(e=e.valueOf()),t&&"object"==typeof t&&(t=t.valueOf());var r={}.toString;switch(e&&"object"==typeof e&&e.toString!=r&&(e=String(e)),t&&"object"==typeof t&&t.toString!=r&&(t=String(t)),"string"==typeof e&&(e=e.toLowerCase().trim()),"string"==typeof t&&(t=t.toLowerCase().trim()),l){case"natural":l=w2utils.naturalCompare;break;case"i18n":l=w2utils.i18nCompare}return"function"==typeof l?l(e,t)*s:t=parseFloat(a)&&parseFloat(c.parseField(l,s.field))<=parseFloat(o)&&r++:"date"==s.type?(h=c.parseField(l,s.field+"_")instanceof Date?c.parseField(l,s.field+"_"):c.parseField(l,s.field),n=w2utils.isDate(h,w2utils.settings.dateFormat,!0),a=w2utils.isDate(a,w2utils.settings.dateFormat,!0),null!=(o=w2utils.isDate(o,w2utils.settings.dateFormat,!0))&&(o=new Date(o.getTime()+864e5)),n>=a&&n=a&&n=a)&&n=":d=!0;case">":case"more":-1!=["int","float","money","currency","percent"].indexOf(s.type)?(n=parseFloat(c.parseField(l,s.field)),a=parseFloat(i.value),(n>a||d&&n===a)&&r++):"date"==s.type?(h=c.parseField(l,s.field+"_")instanceof Date?c.parseField(l,s.field+"_"):c.parseField(l,s.field),n=w2utils.isDate(h,w2utils.settings.dateFormat,!0),a=w2utils.isDate(a,w2utils.settings.dateFormat,!0),(n>a||d&&n===a)&&r++):"time"==s.type?(h=c.parseField(l,s.field+"_")instanceof Date?c.parseField(l,s.field+"_"):c.parseField(l,s.field),n=w2utils.formatTime(h,"hh24:mi"),a=w2utils.formatTime(a,"hh24:mi"),(n>a||d&&n===a)&&r++):"datetime"==s.type&&(h=c.parseField(l,s.field+"_")instanceof Date?c.parseField(l,s.field+"_"):c.parseField(l,s.field),n=w2utils.formatDateTime(h,"yyyy-mm-dd|hh24:mm:ss"),a=w2utils.formatDateTime(w2utils.isDateTime(a,w2utils.settings.datetimeFormat,!0),"yyyy-mm-dd|hh24:mm:ss"),n.length==a.length)&&(n>a||d&&n===a)&&r++;break;case"in":h=i.value,-1===(h=i.svalue?i.svalue:h).indexOf(w2utils.isFloat(t)?parseFloat(t):t)&&-1===h.indexOf(n)||r++;break;case"not in":h=i.value,-1===(h=i.svalue?i.svalue:h).indexOf(w2utils.isFloat(t)?parseFloat(t):t)&&-1===h.indexOf(n)&&r++;break;case"begins":case"begins with":0===n.indexOf(a)&&r++;break;case"contains":0<=n.indexOf(a)&&r++;break;case"null":null==c.parseField(l,s.field)&&r++;break;case"not null":null!=c.parseField(l,s.field)&&r++;break;case"ends":case"ends with":let e=n.lastIndexOf(a);-1!==e&&e==n.length-a.length&&r++}}}if("OR"==c.last.logic&&0!==r||"AND"==c.last.logic&&r==c.searchData.length)return!0;if(l.w2ui?.children&&!0!==l.w2ui?.expanded)for(let t=0;tthis.records.length&&(i=this.records.length-s),0{this.status(w2utils.lang("Search took ${count} seconds",{count:e/1e3}))},10),e}}getRangeData(e,i){var s=this.get(e[0].recid,!0),l=this.get(e[1].recid,!0),r=e[0].column,n=e[1].column,a=[];if(r==n)for(let e=s;e<=l;e++){var t=this.records[e],o=t[this.columns[r].field]||null;a.push(!0!==i?o:{data:o,column:r,index:e,record:t})}else if(s==l){var h=this.records[s];for(let e=r;e<=n;e++){var d=h[this.columns[e].field]||null;a.push(!0!==i?d:{data:d,column:e,index:s,record:h})}}else for(let t=s;t<=l;t++){var u=this.records[t];a.push([]);for(let e=r;e<=n;e++){var c=u[this.columns[e].field];!0!==i?a[a.length-1].push(c):a[a.length-1].push({data:c,column:e,index:t,record:u})}}return a}addRange(s){let e=0,l,r;if("row"!=this.selectType){Array.isArray(s)||(s=[s]);for(let i=0;ithis.last.colStart&&(e=query(this.box).find("#grid_"+this.name+"_rec_"+w2utils.escapeId(u.recid)+' td[col="start"]')),u.columnthis.last.colEnd&&(t=query(this.box).find("#grid_"+this.name+"_rec_"+w2utils.escapeId(c.recid)+' td[col="end"]'),l='"end"');var p=parseInt(query(this.box).find("#grid_"+this.name+"_rec_top").next().attr("index")),f=parseInt(query(this.box).find("#grid_"+this.name+"_rec_bottom").prev().attr("index")),m=parseInt(query(this.box).find("#grid_"+this.name+"_frec_top").next().attr("index")),g=parseInt(query(this.box).find("#grid_"+this.name+"_frec_bottom").prev().attr("index"));0===e.length&&u.indexp&&(e=query(this.box).find("#grid_"+this.name+"_rec_top").next().find('td[col="'+u.column+'"]')),0===t.length&&c.index>f&&u.indexm&&(i=query(this.box).find("#grid_"+this.name+"_frec_top").next().find('td[col="'+u.column+'"]')),0===s.length&&c.index>g&&u.index'+("selection"==d.name?'
    ':"")+""),n=query(this.box).find("#grid_"+this.name+"_f"+d.name)):(n.attr("style",d.style),n.find(".w2ui-selection-resizer").show()),0===s.length&&(0===(s=query(this.box).find("#grid_"+this.name+"_frec_"+w2utils.escapeId(c.recid)+" td:last-child")).length&&(s=query(this.box).find("#grid_"+this.name+"_frec_bottom td:first-child")),n.css("border-right","0px"),n.find(".w2ui-selection-resizer").hide()),null!=u.recid)&&null!=c.recid&&0'+("selection"==d.name?'
    ':"")+""),n=query(this.box).find("#grid_"+this.name+"_"+d.name)):n.attr("style",d.style),0===e.length&&0===(e=query(this.box).find("#grid_"+this.name+"_rec_"+w2utils.escapeId(u.recid)+" td:first-child")).length&&(e=query(this.box).find("#grid_"+this.name+"_rec_top td:first-child")),0!==s.length&&n.css("border-left","0px"),null!=u.recid)&&null!=c.recid&&0{e=this.trigger("resizerDblClick",{target:this.name,originalEvent:e});!0!==e.isCancelled&&e.finish()});let a={target:this.name,originalRange:null,newRange:null};return Date.now()-e;function i(s){var l=r.last.move;if(l&&"expand"==l.type){l.divX=s.screenX-l.x,l.divY=s.screenY-l.y;let e,t,i=s.target;"TD"!=i.tagName.toUpperCase()&&(i=query(i).closest("td")[0]),null!=(t=null!=query(i).attr("col")?parseInt(query(i).attr("col")):t)&&(i=query(i).closest("tr")[0],e=r.records[query(i).attr("index")].recid,l.newRange[1].recid!=e||l.newRange[1].column!=t)&&(s=w2utils.clone(l.newRange),l.newRange=[{recid:l.recid,column:l.column},{recid:e,column:t}],a.detail&&(a.detail.newRange=w2utils.clone(l.newRange),a.detail.originalRange=w2utils.clone(l.originalRange)),!0===(a=r.trigger("selectionExtend",a)).isCancelled?(l.newRange=s,a.detail.newRange=s):(r.removeRange("grid-selection-expand"),r.addRange({name:"grid-selection-expand",range:l.newRange,style:"background-color: rgba(100,100,100,0.1); border: 2px dotted rgba(100,100,100,0.5);"})))}}function s(e){r.removeRange("grid-selection-expand"),delete r.last.move,query("body").off(".w2ui-"+r.name),a.finish&&a.finish()}}}select(){if(0===arguments.length)return 0;let s=0;var l=this.last.selection;this.multiSelect||this.selectNone(!0);let t=Array.from(arguments);Array.isArray(t[0])&&(t=t[0]);var e={target:this.name},e=(1==t.length?(e.multiple=!1,w2utils.isPlainObject(t[0])?e.clicked={recid:t[0].recid,column:t[0].column}:e.recid=t[0]):(e.multiple=!0,e.clicked={recids:t}),this.trigger("select",e));if(!0===e.isCancelled)return 0;if("row"==this.selectType)for(let e=0;e=this.last.range_start&&r+1<=this.last.range_end)&&(e=query(this.box).find("#grid_"+this.name+"_frec_"+w2utils.escapeId(i)),t=query(this.box).find("#grid_"+this.name+"_rec_"+w2utils.escapeId(i))),"row"==this.selectType&&-1==l.indexes.indexOf(r)&&(l.indexes.push(r),e&&t&&(e.addClass("w2ui-selected").find(".w2ui-col-number").addClass("w2ui-row-selected"),t.addClass("w2ui-selected").find(".w2ui-col-number").addClass("w2ui-row-selected"),e.find(".w2ui-grid-select-check").prop("checked",!0)),s++)}}else{var n={};for(let e=0;e=this.last.range_start&&u+1<=this.last.range_end&&(t=query(this.box).find("#grid_"+this.name+"_rec_"+w2utils.escapeId(h)),i=query(this.box).find("#grid_"+this.name+"_frec_"+w2utils.escapeId(h)));var c=l.columns[u]||[];-1==l.indexes.indexOf(u)&&l.indexes.push(u);for(let e=0;ee-t);for(let e=0;ee-t);var f=0 td[col="${h}"]`).removeClass("w2ui-selected w2ui-inactive"),query(this.box).find(`#grid_${this.name}_frec_${w2utils.escapeId(r)} > td[col="${h}"]`).removeClass("w2ui-selected w2ui-inactive");let t=!1,i=!1;var d=this.getSelection();for(let e=0;e{i(t,""),Array.isArray(t.items)&&t.items.forEach(e=>{i(e,t.id+":")})}),this.show.toolbarSave&&(0{this.initSearches(),this.last.search_opened=!0;let t=query(`#w2overlay-${this.name}-search-overlay`);t.data("gridName",this.name).off(".grid-search").on("click.grid-search",()=>{t.find("input, select").each(e=>{e=query(e).data("tooltipName");e&&e.forEach(e=>{w2tooltip.hide(e)})})}),w2utils.bindEvents(t.find("select, input, button"),this);var i=query(`#w2overlay-${this.name}-search-overlay *[rel=search]`);0{t.removeClass("checked"),this.last.search_opened=!1})}}}searchClose(){w2tooltip.hide(this.name+"-search-overlay")}searchFieldTooltip(e,t,i){var e=this.searches[e],s=this.searchData[t];let l=s.operator,r=("less"==(l="more"==l&&"date"==s.type?"since":l)&&"date"==s.type&&(l="before"),""),n=s.value;Array.isArray(s.value)?(s.value.forEach(e=>{r+=`${e.text||e}`}),"date"==s.type&&(r="",s.value.forEach(e=>{r+=`${w2utils.formatDate(e)}`}))):"date"==s.type&&(n=w2utils.formatDateTime(n)),w2tooltip.hide(this.name+"-search-props"),w2tooltip.show({name:this.name+"-search-props",anchor:i,class:"w2ui-white",hideOn:"doc-click",html:` +
    + ${e.label} + ${w2utils.lang(l)} + ${Array.isArray(s.value)?""+r:`${n}`} +
    + +
    +
    `}).then(e=>{query(e.detail.overlay.box).find("#remove").on("click",()=>{this.searchData.splice(""+t,1),this.reload(),this.localSearch(),w2tooltip.hide(this.name+"-search-props")})})}searchSuggest(e,t,i){clearTimeout(this.last.kbd_timer),clearTimeout(this.last.overlay_timer),this.searchShowFields(!0),this.searchClose(),!0===t?w2tooltip.hide(this.name+"-search-suggest"):0${t}`:t}}).select(e=>{var t=this.trigger("searchSelect",{target:this.name,index:e.detail.index,item:e.detail.item});!0===t.isCancelled?e.preventDefault():(e.detail.overlay.hide(),this.last.logic=e.detail.item.logic||"AND",this.last.search="",this.last.label="[Multiple Fields]",this.searchData=w2utils.clone(e.detail.item.data),this.searchSelected=w2utils.clone(e.detail.item,{exclude:["icon","remove"]}),this.reload(),t.finish())}).remove(e=>{let i=e.detail.item,s=this.trigger("searchRemove",{target:this.name,index:e.detail.index,item:i});!0===s.isCancelled?e.preventDefault():(e.detail.overlay.hide(),this.confirm(w2utils.lang('Do you want to delete search "${item}"?',{item:i.text})).yes(e=>{var t=this.savedSearches.findIndex(e=>e.id==i.id);-1!==t&&this.savedSearches.splice(t,1),this.cacheSave("searches",this.savedSearches.map(e=>w2utils.clone(e,{exclude:["remove","icon"]}))),e.detail.self.close(),s.finish()}).no(e=>{e.detail.self.close()}))})):this.last.overlay_timer=setTimeout(()=>{this.searchSuggest(!0)},100))}searchSave(){let e="",t=(this.searchSelected&&(e=this.searchSelected.text),this.savedSearches.findIndex(e=>e.id==this.searchSelected?.id)),s=this.trigger("searchSave",{target:this.name,saveLocalStorage:!0});!0!==s.isCancelled&&this.message({width:350,height:150,body:``,buttons:` + + + `}).open(async i=>{query(i.detail.box).find("input, button").eq(0).val(e),await i.complete,query(i.detail.box).find("#grid-search-cancel").on("click",()=>{this.message()}),query(i.detail.box).find("#grid-search-save").on("click",()=>{var e=query(i.detail.box).find(".w2ui-message .search-name").val();this.searchSelected&&-1!=t?Object.assign(this.savedSearches[t],{id:e,text:e,logic:this.last.logic,data:w2utils.clone(this.searchData)}):this.savedSearches.push({id:e,text:e,icon:"w2ui-icon-search",remove:!0,logic:this.last.logic,data:this.searchData}),this.cacheSave("searches",this.savedSearches.map(e=>w2utils.clone(e,{exclude:["remove","icon"]}))),this.message(),(this.searchSelected?(this.searchSelected.text=e,query(this.box).find(`#grid_${this.name}_search_name .name-text`)):(this.searchSelected={text:e,logic:this.last.logic,data:w2utils.clone(this.searchData)},query(i.detail.box).find(`#grid_${this.name}_search_all`).val(" ").prop("readOnly",!0),query(i.detail.box).find(`#grid_${this.name}_search_name`).show().find(".name-text"))).html(e),s.finish({name:e})}),query(i.detail.box).find("input, button").off(".message").on("keydown.message",e=>{var t=String(query(i.detail.box).find(".w2ui-message-body input").val()).trim();13==e.keyCode&&""!=t&&query(i.detail.box).find("#grid-search-save").trigger("click"),27==e.keyCode&&this.message()}).eq(0).on("input.message",e=>{var t=query(i.detail.box).closest(".w2ui-message").find("#grid-search-save");""===String(query(i.detail.box).val()).trim()?t.prop("disabled",!0):t.prop("disabled",!1)}).get(0).focus()})}cache(e){if(w2utils.hasLocalStorage&&this.useLocalStorage)try{var t=JSON.parse(localStorage.w2ui||"{}");return t[this.stateId||this.name]??={},t[this.stateId||this.name][e]}catch(e){}return null}cacheSave(e,t){if(w2utils.hasLocalStorage&&this.useLocalStorage)try{var i=JSON.parse(localStorage.w2ui||"{}");return i[this.stateId||this.name]??={},i[this.stateId||this.name][e]=t,localStorage.w2ui=JSON.stringify(i),!0}catch(e){delete localStorage.w2ui}return!1}searchReset(e){var t=[];let i=!1;for(let e=0;e=this.searches.length?(this.last.field="",this.last.label=""):(this.last.field=this.searches[e].field,this.last.label=this.searches[e].label)}this.last.multi=!1,this.last.fetch.offset=0,this.last.scrollTop=0,this.last.scrollLeft=0,this.last.selection.indexes=[],this.last.selection.columns={},this.searchClose();l=l.val("").get(0);l?._w2field&&l._w2field.reset(),e||this.reload(),s.finish()}}searchShowFields(e){if(!0===e)w2tooltip.hide(this.name+"-search-fields");else{var l=[];for(let s=-1;s",e),e.label=e.caption),l.push({id:e.field,text:w2utils.lang(e.label),search:e,tooltip:i,disabled:t,checked:e.field==this.last.field})}w2menu.show({type:"radio",name:this.name+"-search-fields",anchor:query(this.box).find("#grid_"+this.name+"_search_name").parent().find(".w2ui-search-down").get(0),items:l,align:"none",hideOn:["doc-click","select"]}).select(e=>{this.searchInitInput(e.detail.item.search.field)})}}searchInitInput(e,t){let i;var s=query(this.box).find("#grid_"+this.name+"_search_all");if("all"==e)i={field:"all",label:w2utils.lang("All Fields")};else if(null==(i=this.getSearch(e)))return;""!=this.last.search?(this.last.label=i.label,this.search(i.field,this.last.search)):(this.last.field=i.field,this.last.label=i.label),s.attr("placeholder",w2utils.lang("Search")+" "+w2utils.lang(i.label||i.caption||i.field,!0))}clear(e){this.total=0,this.records=[],this.summary=[],this.last.fetch.offset=0,this.last.idCache={},this.last.selection={indexes:[],columns:{}},this.reset(!0),e||this.refresh()}reset(e){this.last.scrollTop=0,this.last.scrollLeft=0,this.last.range_start=null,this.last.range_end=null,query(this.box).find(`#grid_${this.name}_records`).prop("scrollTop",0),e||this.refresh()}skip(e,t){this.url?.get??this.url?(this.offset=parseInt(e),this.offset>this.total&&(this.offset=this.total-this.limit),(this.offset<0||!w2utils.isInt(this.offset))&&(this.offset=0),this.clear(!0),this.reload(t)):console.log("ERROR: grid.skip() can only be called when you have remote data source.")}load(e,t){return null==e?(console.log('ERROR: You need to provide url argument when calling .load() method of "'+this.name+'" object.'),new Promise((e,t)=>{t()})):(this.clear(!0),this.request("load",{},e,t))}reload(e){let t=this;var i=this.url?.get??this.url;return t.selectionSave(),i?this.load(i,()=>{t.selectionRestore(),"function"==typeof e&&e()}):(this.reset(!0),this.localSearch(),this.selectionRestore(),"function"==typeof e&&e({status:"success"}),new Promise(e=>{e()}))}request(i,e,t,s){let l=this,r,n;var a=new Promise((e,t)=>{r=e,n=t});if(null==e&&(e={}),!(t=t||this.url))return new Promise((e,t)=>{t()});w2utils.isInt(this.offset)||(this.offset=0),w2utils.isInt(this.last.fetch.offset)||(this.last.fetch.offset=0);let o;var h={limit:this.limit,offset:parseInt(this.offset)+parseInt(this.last.fetch.offset),searchLogic:this.last.logic,search:this.searchData.map(e=>{e=w2utils.clone(e);return this.searchMap&&this.searchMap[e.field]&&(e.field=this.searchMap[e.field]),e}),sort:this.sortData.map(e=>{e=w2utils.clone(e);return this.sortMap&&this.sortMap[e.field]&&(e.field=this.sortMap[e.field]),e})};if(0===this.searchData.length&&(delete h.search,delete h.searchLogic),0===this.sortData.length&&delete h.sort,w2utils.extend(h,this.postData),w2utils.extend(h,e),"delete"!=i&&"save"!=i||(delete h.limit,delete h.offset,"delete"==(h.action=i)&&(h[this.recid||"recid"]=this.getSelection())),"load"==i){if(!0===(o=this.trigger("request",{target:this.name,url:t,postData:h,httpMethod:"GET",httpHeaders:this.httpHeaders})).isCancelled)return new Promise((e,t)=>{t()})}else o={detail:{url:t,postData:h,httpMethod:"save"==i?"PUT":"DELETE",httpHeaders:this.httpHeaders}};if(0===this.last.fetch.offset&&this.lock(w2utils.lang(this.msgRefresh),!0),this.last.fetch.controller)try{this.last.fetch.controller.abort()}catch(e){}switch(t=o.detail.url,i){case"save":t?.save&&(t=t.save);break;case"delete":t?.remove&&(t=t.remove);break;default:t=t?.get??t}if(0{null!=e&&(200!=e?.status?u(e??{}):(l.unlock(),e.json().catch(u).then(e=>{this.requestComplete(e,i,s,r,n)})))}),"load"==i&&o.finish(),a;function u(e){var t;"AbortError"!==e?.name&&(l.unlock(),!0!==(t=l.trigger("error",{response:e,lastFetch:l.last.fetch})).isCancelled)&&(e.status&&200!=e.status?l.error(e.status+": "+e.statusText):(console.log("ERROR: Server communication failed.","\n EXPECTED:",{total:5,records:[{recid:1,field:"value"}]},"\n OR:",{error:!0,message:"error message"}),l.requestComplete({error:!0,message:w2utils.lang(this.msgHTTPError),response:e},i,s,r,n)),t.finish())}}requestComplete(e,t,i,s,l){let r=e.error??!1,n=(null==e.error&&"error"===e.status&&(r=!0),this.last.fetch.response=(Date.now()-this.last.fetch.start)/1e3,setTimeout(()=>{this.show.statusResponse&&this.status(w2utils.lang("Server Response ${count} seconds",{count:this.last.fetch.response}))},10),this.last.pull_more=!1,this.last.pull_refresh=!0,"load");"save"==this.last.fetch.action&&(n="save"),"delete"==this.last.fetch.action&&(n="delete");var a=this.trigger(n,{target:this.name,error:r,data:e,lastFetch:this.last.fetch});if(!0===a.isCancelled)l();else{if(r)this.error(w2utils.lang(e.message??this.msgServerError)),l(e);else if("function"==typeof this.parser?"object"!=typeof(e=this.parser(e))&&console.log("ERROR: Your parser did not return proper object"):null==e?e={error:!0,message:w2utils.lang(this.msgNotJSON)}:Array.isArray(e)&&(e={error:r,records:e,total:e.length}),"load"==t){if(null==e.total&&(e.total=-1),null==e.records&&(e.records=[]),e.records.length==this.limit?(l=this.records.length+e.records.length,this.last.fetch.hasMore=l!=this.total):(this.last.fetch.hasMore=!1,this.total=this.offset+this.last.fetch.offset+e.records.length),this.last.fetch.hasMore||query(this.box).find("#grid_"+this.name+"_rec_more, #grid_"+this.name+"_frec_more").hide(),0===this.last.fetch.offset)this.records=[],this.summary=[];else if(-1!=e.total&&parseInt(e.total)!=parseInt(this.total)){let e=this;return this.message(w2utils.lang(this.msgNeedReload)).ok(()=>{delete e.last.fetch.offset,e.reload()}),new Promise(e=>{e()})}w2utils.isInt(e.total)&&(this.total=parseInt(e.total)),e.records&&e.records.forEach(e=>{this.recid&&(e.recid=this.parseField(e,this.recid)),null==e.recid&&(e.recid="recid-"+this.records.length),(!0===e.w2ui?.summary?this.summary:this.records).push(e)}),e.summary&&(this.summary=[],e.summary.forEach(e=>{this.recid&&(e.recid=this.parseField(e,this.recid)),null==e.recid&&(e.recid="recid-"+this.summary.length),this.summary.push(e)}))}else if("delete"==t)return this.reset(),this.reload();(this.url?.get??this.url)||(this.localSort(),this.localSearch()),this.total=parseInt(this.total),0===this.last.fetch.offset?this.refresh():(this.scroll(),this.resize()),"function"==typeof i&&i(e),s(e),a.finish(),this.last.fetch.loaded=!0}}error(e){var t=this.trigger("error",{target:this.name,message:e});!0!==t.isCancelled&&(this.message(e),t.finish())}getChanges(t){var i=[];void 0===t&&(t=this.records);for(let e=0;e{e.error||this.mergeChanges(),s.finish(),"function"==typeof t&&t(e)}):(this.mergeChanges(),s.finish()))}editField(d,u,c,p){let f=this;if(!0===this.last.inEditMode)p&&13==p.keyCode?({index:m,column:g,value:y}=this.last._edit,this.editChange({type:"custom",value:y},m,g,p),this.editDone(m,g,p)):0<(y=query(this.box).find("div.w2ui-edit-box .w2ui-input")).length&&("DIV"==y.get(0).tagName?(y.text(y.text()+c),w2utils.setCursorPosition(y.get(0),y.text().length)):(y.val(y.val()+c),w2utils.setCursorPosition(y.get(0),y.val().length)));else{let o=this.get(d,!0),h=this.getCellEditable(o,u);if(h&&!["checkbox","check"].includes(h.type)){let n=this.records[o],a=this.columns[u];var m=!0===a.frozen?"_f":"_";if(-1!=["enum","file"].indexOf(h.type))console.log('ERROR: input types "enum" and "file" are not supported in inline editing.');else{var g=this.trigger("editField",{target:this.name,recid:d,column:u,value:c,index:o,originalEvent:p});if(!0!==g.isCancelled){c=g.detail.value,this.last.inEditMode=!0,this.last.editColumn=u,this.last._edit={value:c,index:o,column:u,recid:d},this.selectNone(!0),this.select({recid:d,column:u});var y=query(this.box).find("#grid_"+this.name+m+"rec_"+w2utils.escapeId(d));let e=y.find('[col="'+u+'"] > div'),t=(this.last._edit.tr=y,this.last._edit.div=e,query(this.box).find("div.w2ui-edit-box").remove(),"row"!=this.selectType&&(query(this.box).find("#grid_"+this.name+m+"selection").attr("id","grid_"+this.name+"_editable").removeClass("w2ui-selection").addClass("w2ui-edit-box").prepend('
    ').find(".w2ui-selection-resizer").remove(),e=query(this.box).find("#grid_"+this.name+"_editable > div:first-child")),h.attr=h.attr??"",h.text=h.text??"",h.style=h.style??"",h.items=h.items??[],null!=n.w2ui?.changes?.[a.field]?w2utils.stripTags(n.w2ui.changes[a.field]):w2utils.stripTags(f.parseField(n,a.field))),i="object"!=typeof(t=null==t?"":t)?t:"",s=(null!=g.detail.prevValue&&(i=g.detail.prevValue),null!=c&&(t=c),null!=a.style?a.style+";":"");"string"==typeof a.render&&["number","int","float","money","percent","size"].includes(a.render.split(":")[0])&&(s+="text-align: right;"),0 div').get(0)),m=`font-family: ${p["font-family"]}; font-size: ${p["font-size"]};`;function w(e){try{var t=getComputedStyle(e),i="DIV"==e.tagName.toUpperCase()?e.innerText:e.value,s=query(f.box).find("#grid_"+f.name+"_editable").get(0),l=`font-family: ${t["font-family"]}; font-size: ${t["font-size"]}; white-space: no-wrap;`,r=w2utils.getStrWidth(i,l);r+20>s.clientWidth&&query(s).css("width",r+20+"px")}catch(e){}}"div"===h.type?(e.addClass("w2ui-editable").html(w2utils.stripSpaces(`
    +
    `+h.text)),(l=e.find("div.w2ui-input").get(0)).innerText="object"!=typeof t?t:"",null!=c?w2utils.setCursorPosition(l,l.innerText.length):w2utils.setCursorPosition(l,0,l.innerText.length)):(e.addClass("w2ui-editable").html(w2utils.stripSpaces(``+h.text)),l=e.find("input").get(0),"number"==h.type&&(t=w2utils.formatNumber(t)),"date"==h.type&&(t=w2utils.formatDate(w2utils.isDate(t,h.format,!0)||new Date,h.format)),l.value="object"!=typeof t?t:"",y=e=>{var t=this.last._edit?.escKey;let i=!1;var s=query(l).data("tooltipName");s&&null!=w2tooltip.get(s[0])?.selected&&(i=!0),!this.last.inEditMode||t||!r.includes(h.type)||e.detail.overlay.anchor?.id!=this.last._edit.input?.id&&"list"!=h.type||(this.editChange(),this.editDone(void 0,void 0,{keyCode:i?13:0}))},new w2field(w2utils.extend({},h,{el:l,selected:t,onSelect:y,onHide:y})),null==c&&l&&l.select()),Object.assign(this.last._edit,{input:l,edit:h}),query(l).off(".w2ui-editable").on("blur.w2ui-editable",e=>{var t,i;this.last.inEditMode&&(t=this.last._edit.edit.type,i=query(l).data("tooltipName"),r.includes(t)&&i||(this.editChange(l,o,u,e),this.editDone()))}).on("mousedown.w2ui-editable",e=>{e.stopPropagation()}).on("click.w2ui-editable",e=>{w.call(l,e)}).on("paste.w2ui-editable",e=>{e.preventDefault();e=e.clipboardData.getData("text/plain");document.execCommand("insertHTML",!1,e)}).on("keyup.w2ui-editable",e=>{w.call(l,e)}).on("keydown.w2ui-editable",i=>{switch(i.keyCode){case 8:"list"!=h.type||l._w2field||i.preventDefault();break;case 9:case 13:i.preventDefault();break;case 27:var e=query(l).data("tooltipName");e&&0{switch(i.keyCode){case 9:var e=i.shiftKey?f.prevCell(o,u,!0):f.nextCell(o,u,!0);null!=e&&(t=f.records[e.index].recid,this.editChange(l,o,u,i),this.editDone(o,u,i),"row"!=f.selectType?(f.selectNone(!0),f.select({recid:t,column:e.colIndex})):f.editField(t,e.colIndex,null,i),i.preventDefault)&&i.preventDefault();break;case 13:{let e=!1;var t=query(l).data("tooltipName");t&&null!=w2tooltip.get(t[0]).selected&&(e=!0),t&&e||(this.editChange(l,o,u,i),this.editDone(o,u,i));break}case 27:{this.last._edit.escKey=!1;let e=f.parseField(n,a.field);null!=n.w2ui?.changes?.[a.field]&&(e=n.w2ui.changes[a.field]),null!=l._prevValue&&(e=l._prevValue),"DIV"==l.tagName?l.innerText=null!=e?e:"":l.value=null!=e?e:"",this.editDone(o,u,i),setTimeout(()=>{f.select({recid:d,column:u})},1);break}}w(l)},1)}),l&&(l._prevValue=i),"list"!=h.type&&setTimeout(()=>{this.last.inEditMode&&l&&(l.focus(),clearTimeout(this.last.kbd_timer),(l.resize=w)(l))},50),g.finish({input:l})}}}}}editChange(e,t,i,s){e=e??this.last._edit.input,t=t??this.last._edit.index,i=i??this.last._edit.column,s=s??{};var l=(t<0?this.summary:this.records)[t=t<0?-t-1:t],r=this.columns[i];let n="DIV"==e?.tagName?e.innerText:e.value;var a=e._w2field,o=(a&&("list"==a.type&&(n=a.selected),0!==Object.keys(n).length&&null!=n||(n=""),w2utils.isPlainObject(n)||(n=a.clean(n))),"checkbox"==e.type&&(!1===l.w2ui?.editable&&(e.checked=!e.checked),n=e.checked),this.parseField(l,r.field)),h=l.w2ui?.changes&&l.w2ui.changes.hasOwnProperty(r.field)?l.w2ui.changes[r.field]:o;let d={target:this.name,input:e,recid:l.recid,index:t,column:i,originalEvent:s,value:{new:n,previous:h,original:o}},u=(null!=s.target?._prevValue&&(d.value.previous=s.target._prevValue),0);for(;u<20;){if(u++,"object"!=typeof(n=d.value.new)&&String(o)!=String(n)||"object"==typeof n&&n&&n.id!=o&&("object"!=typeof o||null==o||n.id!=o.id)){if(!0!==(d=this.trigger("change",d)).isCancelled){if(n!==d.detail.value.new)continue;(""!==d.detail.value.new&&null!=d.detail.value.new||""!==h&&null!=h)&&(l.w2ui=l.w2ui??{},l.w2ui.changes=l.w2ui.changes??{},l.w2ui.changes[r.field]=d.detail.value.new),d.finish()}}else if(!0!==(d=this.trigger("restore",d)).isCancelled){if(n!==d.detail.value.new)continue;l.w2ui?.changes&&(delete l.w2ui.changes[r.field],0===Object.keys(l.w2ui.changes).length)&&delete l.w2ui.changes,d.finish()}break}}editDone(t,i,s){if(t=t??this.last._edit.index,i=i??this.last._edit.column,s=s??{},this.advanceOnEdit&&13==s.keyCode){let e=s.shiftKey?this.prevRow(t,i,1):this.nextRow(t,i,1);null==e&&(e=t),setTimeout(()=>{"row"!=this.selectType?(this.selectNone(!0),this.select({recid:this.records[e].recid,column:i})):this.editField(this.records[e].recid,i,null,s)},1)}var e=t<0,l=query(this.last._edit.tr).find('[col="'+i+'"]'),r=this.records[t],n=this.columns[i];this.last.inEditMode=!1,this.last._edit=null,e||(null!=r.w2ui?.changes?.[n.field]?l.addClass("w2ui-changed"):l.removeClass("w2ui-changed"),l.replace(this.getCellHTML(t,i,e))),query(this.box).find("div.w2ui-edit-box").remove(),this.updateToolbar(),setTimeout(()=>{var e=query(this.box).find(`#grid_${this.name}_focus`).get(0);document.activeElement===e||this.last.inEditMode||e.focus()},10)}delete(e){var t=this.trigger("delete",{target:this.name,force:e});if(e&&this.message(),!0!==t.isCancelled){e=t.detail.force;var i=this.getSelection();if(0!==i.length)if(""==this.msgDelete||e){if("object"!=typeof this.url?this.url:this.url.remove)this.request("delete");else if("object"!=typeof i[0])this.selectNone(),this.remove.apply(this,i);else{for(let e=0;e{e.detail.self.close(),this.delete(!0)}).no(e=>{e.detail.self.close()})}}click(l,r){var n=Date.now();let a=null;if(!(1==this.last.cancelClick||r&&r.altKey))if("object"==typeof l&&null!==l&&(a=l.column,l=l.recid),null==r&&(r={}),n-parseInt(this.last.click_time)<350&&this.last.click_recid==l&&"click"==r.type)this.dblClick(l,r);else{this.last.bubbleEl&&(this.last.bubbleEl=null),this.last.click_time=n;n=this.last.click_recid;if(this.last.click_recid=l,null==a&&r.target){let e=r.target;"TD"!=e.tagName&&(e=query(e).closest("td")[0]),null!=query(e).attr("col")&&(a=parseInt(query(e).attr("col")))}var o=this.trigger("click",{target:this.name,recid:l,column:a,originalEvent:r});if(!0!==o.isCancelled){var h=this.getSelection(),d=(query(this.box).find("#grid_"+this.name+"_check_all").prop("checked",!1),this.get(l,!0)),u=[];this.last.sel_ind=d,this.last.sel_col=a,this.last.sel_recid=l,this.last.sel_type="click";let e,i,t,s;if(r.shiftKey&&0h[0].column?(t=h[0].column,a):(t=a,h[0].column);for(let e=t;e<=s;e++)u.push(e)}else e=this.get(n,!0),i=this.get(l,!0);var c=[],p=(e>i&&(n=e,e=i,i=n),this.url?.get?this.url.get:this.url);for(let t=e;t<=i;t++)if(!(0=this.records.length?this.selectNone():this.selectAll())}else if(t.altKey&&(l=this.getColumn(s))&&l.sortable&&this.sort(s,null,!(!t||!t.ctrlKey&&!t.metaKey)),"line-number"==e.detail.field)this.getSelection().length>=this.records.length?this.selectNone():this.selectAll();else{t.shiftKey||t.metaKey||t.ctrlKey||this.selectNone(!0);var l=this.getSelection(),s=this.getColumn(e.detail.field,!0),i=[],r=[];if(0!=l.length&&t.shiftKey){let t=s,i=l[0].column;t>i&&(t=l[0].column,i=s);for(let e=t;e<=i;e++)r.push(e)}else r.push(s);if(!0!==(e=this.trigger("columnSelect",{target:this.name,columns:r})).isCancelled){for(let e=0;e{query("#w2overlay-context-menu .w2ui-grid-skip").off(".w2ui-grid").on("click.w2ui-grid",e=>{e.stopPropagation()}).on("keypress",e=>{13==e.keyCode&&(this.skip(e.target.value),this.toolbar.click("w2ui-column-on-off"))})}).select(e=>{var t=e.detail.item.id;["w2ui-stateSave","w2ui-stateReset"].includes(t)?this[t.substring(5)]():"w2ui-skip"!=t&&this.columnOnOff(e,e.detail.item.id),clearTimeout(this.last.kbd_timer)}),clearTimeout(this.last.kbd_timer)),t.preventDefault(),e.finish())}focus(e){e=this.trigger("focus",{target:this.name,originalEvent:e});if(!0===e.isCancelled)return!1;this.hasFocus=!0,query(this.box).removeClass("w2ui-inactive").find(".w2ui-inactive").removeClass("w2ui-inactive"),setTimeout(()=>{var e=query(this.box).find(`#grid_${this.name}_focus`).get(0);e&&document.activeElement!=e&&e.focus()},10),e.finish()}blur(e){e=this.trigger("blur",{target:this.name,originalEvent:e});if(!0===e.isCancelled)return!1;this.hasFocus=!1,query(this.box).addClass("w2ui-inactive").find(".w2ui-selected").addClass("w2ui-inactive"),query(this.box).find(".w2ui-selection").addClass("w2ui-inactive"),e.finish()}keydown(c){let p=this,f="object"!=typeof this.url?this.url:this.url.get;if(!0===p.keyboard){var m=p.trigger("keydown",{target:p.name,originalEvent:c});if(!0!==m.isCancelled)if(0t&&p.last.sel_ind!=l?p.unselect(p.records[l].recid):p.select(p.records[t].recid);else if(p.last.sel_ind>t&&p.last.sel_ind!=l){t=l;var i=[];for(let e=0;e{var e=query(p.box).find("#grid_"+p.name+"_focus"),t=e.val();e.val(""),p.editField(n,a[0],t,c)},1)),d&&c.preventDefault&&c.preventDefault(),m.finish()}}}scrollIntoView(e,s,t,i){let l=this.records.length;if(0!==(l=0==this.searchData.length||this.url?l:this.last.searchIds.length)){if(null==e){var r=this.getSelection();if(0===r.length)return;w2utils.isPlainObject(r[0])?(e=r[0].index,s=r[0].column):e=this.get(r[0],!0)}var r=query(this.box).find(`#grid_${this.name}_records`),n=r[0].clientWidth,a=r[0].clientHeight,o=r[0].scrollTop,h=r[0].scrollLeft,d=this.last.searchIds.length;if(0{clearTimeout(this.last.kbd_timer),this.contextMenuClick(i,s,e)}),clearTimeout(this.last.kbd_timer)),e.preventDefault(),t.finish())}}contextMenuClick(e,t,i){e=this.trigger("contextMenuClick",{target:this.name,recid:e,column:t,originalEvent:i.detail.originalEvent,menuEvent:i,menuIndex:i.detail.index,menuItem:i.detail.item});!0!==e.isCancelled&&e.finish()}toggle(e){var t=this.get(e);if(null!=t)return t.w2ui=t.w2ui??{},!0===t.w2ui.expanded?this.collapse(e):this.expand(e)}expand(e,t){var i=this.get(e,!0);let s=this.records[i];s.w2ui=s.w2ui??{};var l=w2utils.escapeId(e),r=s.w2ui.children;let n;if(Array.isArray(r)){if(!0===s.w2ui.expanded||0===r.length)return!1;if(!0===(n=this.trigger("expand",{target:this.name,recid:e})).isCancelled)return!1;s.w2ui.expanded=!0,r.forEach(e=>{e.w2ui=e.w2ui??{},e.w2ui.parent_recid=s.recid,null==e.w2ui.children&&(e.w2ui.children=[])}),this.records.splice.apply(this.records,[i+1,0].concat(r)),-1!==this.total&&(this.total+=r.length),("object"!=typeof this.url?this.url:this.url.get)||(this.localSort(!0,!0),0 + +
    + + + `),query(this.box).find("#grid_"+this.name+"_frec_"+l).after(` + ${this.show.lineNumbers?'':""} + +
    + + `),!0===(n=this.trigger("expand",{target:this.name,recid:e,box_id:"grid_"+this.name+"_rec_"+e+"_expanded",fbox_id:"grid_"+this.name+"_frec_"+e+"_expanded"})).isCancelled)return query(this.box).find("#grid_"+this.name+"_rec_"+l+"_expanded_row").remove(),query(this.box).find("#grid_"+this.name+"_frec_"+l+"_expanded_row").remove(),!1;i=query(this.box).find("#grid_"+this.name+"_rec_"+e+"_expanded"),r=query(this.box).find("#grid_"+this.name+"_frec_"+e+"_expanded"),t=i.find(":scope div:first-child")[0]?.clientHeight??50;i[0].clientHeight{query(this.box).find("#grid_"+this.name+"_rec_"+e+"_expanded_row").remove(),query(this.box).find("#grid_"+this.name+"_frec_"+e+"_expanded_row").remove(),l.w2ui.expanded=!1,n.finish(),this.resizeRecords()},300)}return!0}sort(i,e,s){var t=this.trigger("sort",{target:this.name,field:i,direction:e,multiField:s});if(!0!==t.isCancelled){if(null!=i){let t=this.sortData.length;for(let e=0;ei&&(i=s[e].column),-1==r.indexOf(s[e].index)&&r.push(s[e].index);r.sort((e,t)=>e-t);for(let e=0;e!!e);e.classList.forEach(e=>{t.includes(e)||i.push(e)}),e.classList.remove(...i),e.classList.add(...o)}}if(u.columns[t].style&&u.columns[t].style!=e.style.cssText&&(e.style.cssText=u.columns[t].style??""),null!=s.w2ui.class){if("string"==typeof s.w2ui.class){let t=["w2ui-odd","w2ui-even","w2ui-record"],i=[];n=s.w2ui.class.split(" ").filter(e=>!!e);l&&r&&(l.classList.forEach(e=>{t.includes(e)||i.push(e)}),l.classList.remove(...i),l.classList.add(...n),r.classList.remove(...i),r.classList.add(...n))}if(w2utils.isPlainObject(s.w2ui.class)&&"string"==typeof s.w2ui.class[a.field]){let t=["w2ui-grid-data"],i=[];h=s.w2ui.class[a.field].split(" ").filter(e=>!!e);e.classList.forEach(e=>{t.includes(e)||i.push(e)}),e.classList.remove(...i),e.classList.add(...h)}}null!=s.w2ui.style&&(l&&r&&"string"==typeof s.w2ui.style&&l.style.cssText!==s.w2ui.style&&(l.style.cssText="height: "+u.recordHeight+"px;"+s.w2ui.style,l.setAttribute("custom_style",s.w2ui.style),r.style.cssText="height: "+u.recordHeight+"px;"+s.w2ui.style,r.setAttribute("custom_style",s.w2ui.style)),w2utils.isPlainObject(s.w2ui.style))&&"string"==typeof s.w2ui.style[a.field]&&e.style.cssText!==s.w2ui.style[a.field]&&(e.style.cssText=s.w2ui.style[a.field])}}}}refreshCell(e,t){var i=this.get(e,!0),t=this.getColumn(t,!0),e=!this.records[i]||this.records[i].recid!=e,s=query(this.box).find(`${e?".w2ui-grid-summary ":""}#grid_${this.name}_data_${i}_`+t);return 0!=s.length&&(s.replace(this.getCellHTML(i,t,e)),!0)}refreshRow(t,i=null){let s=query(this.box).find("#grid_"+this.name+"_frec_"+w2utils.escapeId(t)),l=query(this.box).find("#grid_"+this.name+"_rec_"+w2utils.escapeId(t));if(0{var t=[];for(let e=0;e{var t=query(this.box).find('td[col="'+e.col+'"]:not(.w2ui-head)');w2utils.marker(t,e.search)})},50),this.updateToolbar(this.last.selection),t.finish(),this.resize(),this.addRange("selection"),setTimeout(()=>{this.resize(),this.scroll()},1),this.reorderColumns&&!this.last.columnDrag?this.last.columnDrag=this.initColumnDrag():!this.reorderColumns&&this.last.columnDrag&&this.last.columnDrag.remove(),Date.now()-e}}}refreshSearch(){if(this.multiSearch&&0`);let r=` + +
    `;this.searchData.forEach((i,e)=>{var t=this.getSearch(i.field,!0),s=this.searches[t];let l;if(l=Array.isArray(i.value)?`${i.value.length}`:s&&"list"==s.type&&i.text&&i.text!==i.value?": "+i.text:": "+i.value,s&&"date"==s.type)if("between"==i.operator){let e=i.value[0],t=i.value[1];Number(e)===e&&(e=w2utils.formatDate(e)),Number(t)===t&&(t=w2utils.formatDate(t)),l=`: ${e} - `+t}else{let e=i.value,t=(Number(e)==e&&(e=w2utils.formatDate(e)),i.operator);"more:"==(t="less"==(t="more"==t?"since":t)?"before":t).substr(0,5)&&(t="since"),l=`: ${t} `+e}r+=` + ${s?s.label:""} + ${l} + + `}),r+=` + ${this.show.searchSave?`
    + + `:""} + + `,query(this.box).find(`#grid_${this.name}_searches`).html(r),query(this.box).find(`#grid_${this.name}_search_logic`).html(w2utils.lang("AND"==this.last.logic?"All":"Any"))}else query(this.box).find(".w2ui-grid-toolbar").css("height",this.last.toolbar_height+"px").find(".w2ui-grid-searches").remove();this.searchSelected?(query(this.box).find(`#grid_${this.name}_search_all`).val(" ").prop("readOnly",!0),query(this.box).find(`#grid_${this.name}_search_name`).show().find(".name-text").html(this.searchSelected.text)):(query(this.box).find(`#grid_${this.name}_search_all`).prop("readOnly",!1),query(this.box).find(`#grid_${this.name}_search_name`).hide().find(".name-text").html("")),w2utils.bindEvents(query(this.box).find(`#grid_${this.name}_searches .w2ui-action, #grid_${this.name}_searches button`),this)}refreshBody(){this.scroll();var e=this.getRecordsHTML(),t=this.getColumnsHTML(),e='
    '+e[0]+'
    '+e[1]+'
    '+t[0]+'
    '+t[1]+"
    "+``;let l=query(this.box).find(`#grid_${this.name}_body`,this.box).html(e);t=query(this.box).find(`#grid_${this.name}_records`,this.box),e=query(this.box).find(`#grid_${this.name}_frecords`,this.box);"row"==this.selectType&&(t.on("mouseover mouseout",{delegate:"tr"},e=>{var t=query(e.delegate).attr("recid");query(this.box).find(`#grid_${this.name}_frec_`+w2utils.escapeId(t)).toggleClass("w2ui-record-hover","mouseover"==e.type)}),e.on("mouseover mouseout",{delegate:"tr"},e=>{var t=query(e.delegate).attr("recid");query(this.box).find(`#grid_${this.name}_rec_`+w2utils.escapeId(t)).toggleClass("w2ui-record-hover","mouseover"==e.type)})),w2utils.isIOS?t.append(e).on("click",{delegate:"tr"},e=>{var t=query(e.delegate).attr("recid");this.dblClick(t,e)}):t.add(e).on("click",{delegate:"tr"},e=>{var t=query(e.delegate).attr("recid");"-none-"!=t&&this.click(t,e)}).on("contextmenu",{delegate:"tr"},e=>{var t=query(e.delegate).attr("recid"),i=query(e.target).closest("td"),i=parseInt(i.attr("col")??-1);this.showContextMenu(t,i,e)}).on("mouseover",{delegate:"tr"},e=>{this.last.rec_out=!1;let t=query(e.delegate).attr("index"),i=query(e.delegate).attr("recid");t!==this.last.rec_over&&(this.last.rec_over=t,setTimeout(()=>{delete this.last.rec_out,this.trigger("mouseEnter",{target:this.name,originalEvent:e,index:t,recid:i}).finish()}))}).on("mouseout",{delegate:"tr"},t=>{let i=query(t.delegate).attr("index"),s=query(t.delegate).attr("recid");this.last.rec_out=!0,setTimeout(()=>{let e=()=>{this.trigger("mouseLeave",{target:this.name,originalEvent:t,index:i,recid:s}).finish()};i!==this.last.rec_over&&e(),setTimeout(()=>{this.last.rec_out&&(delete this.last.rec_out,delete this.last.rec_over,e())})})}),l.data("scroll",{lastDelta:0,lastTime:0}).find(".w2ui-grid-frecords").on("mousewheel DOMMouseScroll ",e=>{e.preventDefault();var t=l.data("scroll"),i=l.find(".w2ui-grid-records"),e=null!=typeof e.wheelDelta?-e.wheelDelta:e.detail||e.deltaY,s=i.prop("scrollTop");t.lastDelta+=e,e=Math.round(t.lastDelta),l.data("scroll",t),i.get(0).scroll({top:s+e,behavior:"smooth"})}),t.off(".body-global").on("scroll.body-global",{delegate:".w2ui-grid-records"},e=>{this.scroll(e)}),query(this.box).find(".w2ui-grid-body").off(".body-global").on("click.body-global dblclick.body-global contextmenu.body-global",{delegate:"td.w2ui-head"},e=>{var t=query(e.delegate).attr("col"),i=this.columns[t]??{field:t};switch(e.type){case"click":this.columnClick(i.field,e);break;case"dblclick":this.columnDblClick(i.field,e);break;case"contextmenu":this.columnContextMenu(i.field,e)}}).on("mouseover.body-global",{delegate:".w2ui-col-header"},e=>{let t=query(e.delegate).parent().attr("col");this.columnTooltipShow(t,e),query(e.delegate).off(".tooltip").on("mouseleave.tooltip",()=>{this.columnTooltipHide(t,e)})}).on("click.body-global",{delegate:"input.w2ui-select-all"},e=>{e.delegate.checked?this.selectAll():this.selectNone(),e.stopPropagation(),clearTimeout(this.last.kbd_timer)}).on("click.body-global",{delegate:".w2ui-show-children, .w2ui-col-expand"},e=>{e.stopPropagation(),this.toggle(query(e.target).parents("tr").attr("recid"))}).on("click.body-global mouseover.body-global",{delegate:".w2ui-info"},e=>{var t=query(e.delegate).closest("td"),i=t.parent(),s=this.columns[t.attr("col")],l=i.parents(".w2ui-grid-body").hasClass("w2ui-grid-summary");["mouseenter","mouseover"].includes(s.info?.showOn?.toLowerCase())&&"mouseover"==e.type?this.showBubble(i.attr("index"),t.attr("col"),l).then(()=>{query(e.delegate).off(".tooltip").on("mouseleave.tooltip",()=>{w2tooltip.hide(this.name+"-bubble")})}):"click"==e.type&&(w2tooltip.hide(this.name+"-bubble"),this.showBubble(i.attr("index"),t.attr("col"),l))}).on("mouseover.body-global",{delegate:".w2ui-clipboard-copy"},l=>{if(!l.delegate._tooltipShow){let t=query(l.delegate).parent(),i=t.parent();var e=this.columns[t.attr("col")];let s=i.parents(".w2ui-grid-body").hasClass("w2ui-grid-summary");w2tooltip.show({name:this.name+"-bubble",anchor:l.delegate,html:w2utils.lang("string"==typeof e.clipboardCopy?e.clipboardCopy:"Copy to clipboard"),position:"top|bottom",offsetY:-2}).hide(e=>{l.delegate._tooltipShow=!1,query(l.delegate).off(".tooltip")}),query(l.delegate).off(".tooltip").on("mouseleave.tooltip",e=>{w2tooltip.hide(this.name+"-bubble")}).on("click.tooltip",e=>{e.stopPropagation(),w2tooltip.update(this.name+"-bubble",w2utils.lang("Copied")),this.clipboardCopy(i.attr("index"),t.attr("col"),s)}),l.delegate._tooltipShow=!0}}).on("click.body-global",{delegate:".w2ui-editable-checkbox"},e=>{var t=query(e.delegate).data();this.editChange.call(this,e.delegate,t.changeind,t.colind,e),this.updateToolbar()}),0===this.records.length&&this.msgEmpty?query(this.box).find(`#grid_${this.name}_body`).append(`
    ${w2utils.lang(this.msgEmpty)}
    `):0=this.searches.length?(this.last.field="",this.last.label=""):(this.last.field=this.searches[e].field,this.last.label=this.searches[e].label)}if(query(this.box).attr("name",this.name).addClass("w2ui-reset w2ui-grid w2ui-inactive").html('
    "),"row"!=this.selectType&&query(this.box).addClass("w2ui-ss"),0{this.searchInitInput(this.last.field,1==e.length?e[0].value:null)},1)}query(this.box).find(`#grid_${this.name}_footer`).html(this.getFooterHTML()),this.last.state||(this.last.state=this.stateSave(!0)),this.stateRestore(),e&&(this.clear(),this.refresh());let t=!1;for(let e=0;e{this.searchReset()},1)):this.reload(),query(this.box).find(`#grid_${this.name}_focus`).on("focus",e=>{clearTimeout(this.last.kbd_timer),this.hasFocus||this.focus()}).on("blur",e=>{clearTimeout(this.last.kbd_timer),this.last.kbd_timer=setTimeout(()=>{this.hasFocus&&this.blur()},100)}).on("paste",i=>{var s=i.clipboardData||null;if(s){let e=s.items,t=[];for(var l in e=2==e.length&&2==(e=2==e.length&&"file"==e[1].kind?[e[1]]:e).length&&"text/plain"==e[0].type&&"text/html"==e[1].type?[e[1]]:e){l=e[l];if("file"===l.kind){var r=l.getAsFile();t.push({kind:"file",data:r})}else if("string"===l.kind&&("text/plain"===l.type||"text/html"===l.type)){i.preventDefault();let e=s.getData("text/plain");-1!=e.indexOf("\r")&&-1==e.indexOf("\n")&&(e=e.replace(/\r/g,"\n")),t.push({kind:"text/html"==l.type?"html":"text",data:e})}}1===t.length&&"file"!=t[0].kind&&(t=t[0].data),w2ui[this.name].paste(t,i),i.preventDefault()}}).on("keydown",function(e){w2ui[p.name].keydown.call(w2ui[p.name],e)});let c;return query(this.box).off("mousedown.mouseStart").on("mousedown.mouseStart",function(l){if(1==l.which&&("text"==p.last.userSelect&&(p.last.userSelect="",query(p.box).find(".w2ui-grid-body").css("user-select","none")),!("row"==p.selectType&&(query(l.target).parents().hasClass("w2ui-head")||query(l.target).hasClass("w2ui-head"))||p.last.move&&"expand"==p.last.move.type))){if(l.altKey)query(p.box).find(".w2ui-grid-body").css("user-select","text"),p.selectNone(),p.last.move={type:"text-select"},p.last.userSelect="text";else{let e=l.target;var r={x:l.offsetX-10,y:l.offsetY-10};let t=!1;for(;e&&(!e.classList||!e.classList.contains("w2ui-grid"));)e.tagName&&"TD"==e.tagName.toUpperCase()&&(t=!0),e.tagName&&"TR"!=e.tagName.toUpperCase()&&1==t&&(r.x+=e.offsetLeft,r.y+=e.offsetTop),e=e.parentNode;p.last.move={x:l.screenX,y:l.screenY,divX:0,divY:0,focusX:r.x,focusY:r.y,recid:query(l.target).parents("tr").attr("recid"),column:parseInt(("TD"==l.target.tagName.toUpperCase()?query(l.target):query(l.target).parents("td")).attr("col")),type:"select",ghost:!1,start:!0},null==p.last.move.recid&&(p.last.move.type="select-column");let i=l.target,s=query(p.box).find("#grid_"+p.name+"_focus");if(p.last.move){let e=p.last.move.focusX,t=p.last.move.focusY;var n=query(i).parents("table").parent();(n.hasClass("w2ui-grid-records")||n.hasClass("w2ui-grid-frecords")||n.hasClass("w2ui-grid-columns")||n.hasClass("w2ui-grid-fcolumns")||n.hasClass("w2ui-grid-summary"))&&(e=p.last.move.focusX-query(p.box).find("#grid_"+p.name+"_records").prop("scrollLeft"),t=p.last.move.focusY-query(p.box).find("#grid_"+p.name+"_records").prop("scrollTop")),(query(i).hasClass("w2ui-grid-footer")||0{p.last.inEditMode||(["INPUT","TEXTAREA","SELECT"].includes(i.tagName)?i.focus():s.get(0)!==document.active&&s.get(0)?.focus({preventScroll:!0}))},50),p.multiSelect||p.reorderRows||"drag"!=p.last.move.type||delete p.last.move}if(1==p.reorderRows){let e=l.target;var t,i,s,a;"TD"!=e.tagName.toUpperCase()&&(e=query(e).parents("td")[0]),query(e).hasClass("w2ui-col-number")||query(e).hasClass("w2ui-col-order")?(p.selectNone(),p.last.move.reorder=!0,n=query(p.box).find(".w2ui-even.w2ui-empty-record").css("background-color"),t=query(p.box).find(".w2ui-odd.w2ui-empty-record").css("background-color"),query(p.box).find(".w2ui-even td").filter(":not(.w2ui-col-number)").css("background-color",n),query(p.box).find(".w2ui-odd td").filter(":not(.w2ui-col-number)").css("background-color",t),t=p.last.move,i=query(p.box).find(".w2ui-grid-records"),t.ghost||(s=query(p.box).find(`#grid_${p.name}_rec_`+t.recid),a=s.parents("table").find("tr:first-child").get(0).cloneNode(!0),t.offsetY=l.offsetY,t.from=t.recid,t.pos={top:s.get(0).offsetTop-1,left:s.get(0).offsetLeft},t.ghost=query(s.get(0).cloneNode(!0)),t.ghost.removeAttr("id"),t.ghost.find("td").css({"border-top":"1px solid silver","border-bottom":"1px solid silver"}),s.find("td").remove(),s.append(`
    `),i.append('
    '),i.append('
    '),query(p.box).find("#grid_"+p.name+"_ghost").append(a).append(t.ghost)),query(p.box).find("#grid_"+p.name+"_ghost").css({top:t.pos.top+"px",left:t.pos.left+"px"})):p.last.move.reorder=!1}query(document).on("mousemove.w2ui-"+p.name,o).on("mouseup.w2ui-"+p.name,h),l.stopPropagation()}}),this.updateToolbar(),s.finish(),this.last.observeResize=new ResizeObserver(()=>{this.resize()}),this.last.observeResize.observe(this.box),Date.now()-i;function o(t){if(t.target.tagName){var r=p.last.move;if(r&&-1!=["select","select-column"].indexOf(r.type)&&(r.divX=t.screenX-r.x,r.divY=t.screenY-r.y,!(Math.abs(r.divX)<=1&&Math.abs(r.divY)<=1)))if(p.last.cancelClick=!0,1==p.reorderRows&&p.last.move.reorder){let e=query(t.target).parents("tr").attr("recid");(e="-none-"==e?"bottom":e)!=r.from&&(a=query(p.box).find("#grid_"+p.name+"_rec_"+e),query(p.box).find(".insert-before"),a.addClass("insert-before"),r.lastY=t.screenY,r.to=e,a={top:a.get(0)?.offsetTop,left:a.get(0)?.offsetLeft},query(p.box).find("#grid_"+p.name+"_ghost_line").css({top:a.top+"px",left:r.pos.left+"px","border-top":"2px solid #769EFC"})),void query(p.box).find("#grid_"+p.name+"_ghost").css({top:r.pos.top+r.divY+"px",left:r.pos.left+"px"})}else{r.start&&r.recid&&(p.selectNone(),r.start=!1);var n=[],a=("TR"==t.target.tagName.toUpperCase()?query(t.target):query(t.target).parents("tr")).attr("recid");if(null==a){if("row"!=p.selectType&&(!p.last.move||"select"!=p.last.move.type)){var o=parseInt(query(t.target).parents("td").attr("col"));if(isNaN(o))p.removeRange("column-selection"),query(p.box).find(".w2ui-grid-columns .w2ui-col-header, .w2ui-grid-fcolumns .w2ui-col-header").removeClass("w2ui-col-selected"),query(p.box).find(".w2ui-col-number").removeClass("w2ui-row-selected"),delete r.colRange;else{let e=o+"-"+o;r.columno?o+"-"+r.column:e).split("-");for(let e=parseInt(s[0]);e<=parseInt(s[1]);e++)i.push(e);if(r.colRange!=e&&!0!==(c=p.trigger("columnSelect",{target:p.name,columns:i})).isCancelled){null==r.colRange&&p.selectNone();var l=e.split("-");query(p.box).find(".w2ui-grid-columns .w2ui-col-header, .w2ui-grid-fcolumns .w2ui-col-header").removeClass("w2ui-col-selected");for(let e=parseInt(l[0]);e<=parseInt(l[1]);e++)query(p.box).find("#grid_"+p.name+"_column_"+e+" .w2ui-col-header").addClass("w2ui-col-selected");query(p.box).find(".w2ui-col-number").not(".w2ui-head").addClass("w2ui-row-selected"),r.colRange=e,p.removeRange("column-selection"),p.addRange({name:"column-selection",range:[{recid:p.records[0].recid,column:l[0]},{recid:p.records[p.records.length-1].recid,column:l[1]}],style:"background-color: rgba(90, 145, 234, 0.1)"})}}}}else{let l=p.get(r.recid,!0);if(!(null==l||p.records[l]&&p.records[l].recid!=r.recid)){let e=p.get(a,!0);if(null!=e){let i=parseInt(r.column),s=parseInt(("TD"==t.target.tagName.toUpperCase()?query(t.target):query(t.target).parents("td")).attr("col"));isNaN(i)&&isNaN(s)&&(i=0,s=p.columns.length-1),l>e&&(o=l,l=e,e=o);var h,a="ind1:"+l+",ind2;"+e+",col1:"+i+",col2:"+s;if(r.range!=a){r.range=a;for(let t=l;t<=e;t++)if(!(0s&&(h=i,i=s,s=h);for(let e=i;e<=s;e++)p.columns[e].hidden||n.push({recid:p.records[t].recid,column:parseInt(e)})}else n.push(p.records[t].recid);if("row"!=p.selectType){var d=p.getSelection();let e=[];for(let i=0;i{delete p.last.cancelClick},1),!query(t.target).parents().hasClass(".w2ui-head")&&!query(t.target).hasClass(".w2ui-head")){if(i&&-1!=["select","select-column"].indexOf(i.type)){if(null!=i.colRange&&!0!==c.isCancelled){var s=i.colRange.split("-"),l=[];for(let e=0;ee?p.records.splice(e,0,i):p.records.splice(e-1,0,i)),p.sortData=[],query(p.box).find(`#grid_${p.name}_columns .w2ui-col-header`).removeClass("w2ui-col-sorted"),a(),t.finish()}else a()}delete p.last.move,query(document).off(".w2ui-"+p.name)}}function a(){query(p.box).find(`#grid_${p.name}_ghost`).remove(),query(p.box).find(`#grid_${p.name}_ghost_line`).remove(),p.refresh(),delete p.last.move}}}destroy(){var e=this.trigger("destroy",{target:this.name});!0!==e.isCancelled&&(query(this.box).off(),"object"==typeof this.toolbar&&this.toolbar.destroy&&this.toolbar.destroy(),0`+w2utils.lang("records"),i.push({id:"w2ui-skip",text:e,group:!1,icon:"w2ui-icon-empty"})),this.show.saveRestoreState&&i.push({id:"w2ui-stateSave",text:w2utils.lang("Save Grid State"),icon:"w2ui-icon-empty",group:!1},{id:"w2ui-stateReset",text:w2utils.lang("Restore Default State"),icon:"w2ui-icon-empty",group:!1});let t=[];return i.forEach(e=>{e.text=w2utils.lang(e.text),e.checked&&t.push(e.id)}),this.toolbar.set("w2ui-column-on-off",{selected:t,items:i}),i}initColumnDrag(e){if(this.columnGroups&&this.columnGroups.length)throw"Draggable columns are not currently supported with column groups.";let r=this,n={pressed:!1,targetPos:null,columnHead:null},a=(t,e)=>{var i=["w2ui-col-number","w2ui-col-expand","w2ui-col-select"];!0!==e&&i.push("w2ui-head-last");for(let e=0;e{var e=query(r.box).find(".w2ui-grid-ghost");query(r.box).find(".w2ui-intersection-marker").hide(),query(n.ghost).remove(),e.remove(),query(document).off(".colDrag"),n={}};if(e.pageX==n.initialX&&e.pageY==n.initialY)r.columnClick(r.columns[n.originalPos].field,e),s();else{if(!0===(e=r.trigger("columnDragEnd",{originalEvent:e,target:n.columnHead[0],dragData:n})).isCancelled)return!1;t=r.columns[n.originalPos],i=r.columns,n.originalPos!=n.targetPos&&null!=n.targetPos&&(i.splice(n.targetPos,0,w2utils.clone(t)),i.splice(i.indexOf(t),1)),s(),r.refresh(),e.finish({targetColumn:NaN})}}}return query(r.box).off(".colDrag").on("mousedown.colDrag",function(e){if(!n.pressed&&0!==n.numberPreColumnsPresent&&0===e.button){var i,t;if(query(e.target).parents().hasClass("w2ui-head")&&!a(e.target)){if(n.pressed=!0,n.initialX=e.pageX,n.initialY=e.pageY,n.numberPreColumnsPresent=query(r.box).find(".w2ui-head.w2ui-col-number, .w2ui-head.w2ui-col-expand, .w2ui-head.w2ui-col-select").length,n.columnHead=s=query(e.target).closest(".w2ui-head"),n.originalPos=t=parseInt(s.attr("col"),10),!0===(t=r.trigger("columnDragStart",{originalEvent:e,origColumnNumber:t,target:s[0]})).isCancelled)return!1;i=n.columns=query(r.box).find(".w2ui-head:not(.w2ui-head-last)"),query(document).on("mouseup.colDrag",h),query(document).on("mousemove.colDrag",o);var s=r.columns[n.originalPos],s=w2utils.lang("function"==typeof s.text?s.text(s):s.text);n.ghost=query.html(`${s}`)[0],query(document.body).append(n.ghost),query(n.ghost).css({display:"none",left:e.pageX,top:e.pageY,opacity:1,margin:"3px 0 0 20px",padding:"3px","background-color":"white",position:"fixed","z-index":999999}).addClass(".w2ui-grid-ghost"),n.offsets=[];for(let e=0,t=i.length;e + ${this.buttons.search.html} +
    + + + x +
    + +
    + +
    + `,this.toolbar.items.push({id:"w2ui-search",type:"html",html:t,onRefresh:async e=>{await e.complete;var e=query(this.box).find(`#grid_${this.name}_search_all`),t=(w2utils.bindEvents(query(this.box).find(`#grid_${this.name}_search_all, .w2ui-action`),this),w2utils.debounce(e=>{var t=e.target.value;this.liveSearch&&this.last.liveText!=t&&(this.last.liveText=t,this.search(this.last.field,t)),40==e.keyCode&&this.searchSuggest(!0)},250));e.on("change",e=>{this.liveSearch||(this.search(this.last.field,e.target.value),this.searchSuggest(!0,!0,this))}).on("blur",()=>{this.last.liveText=""}).on("keyup",t)}})),Array.isArray(e)&&(t=e.map(e=>e.id),this.show.toolbarAdd&&!t.includes(this.buttons.add.id)&&this.toolbar.items.push(w2utils.extend({},this.buttons.add)),this.show.toolbarEdit&&!t.includes(this.buttons.edit.id)&&this.toolbar.items.push(w2utils.extend({},this.buttons.edit)),this.show.toolbarDelete&&!t.includes(this.buttons.delete.id)&&this.toolbar.items.push(w2utils.extend({},this.buttons.delete)),this.show.toolbarSave&&!t.includes(this.buttons.save.id)&&((this.show.toolbarAdd||this.show.toolbarDelete||this.show.toolbarEdit)&&this.toolbar.items.push({type:"break",id:"w2ui-break2"}),this.toolbar.items.push(w2utils.extend({},this.buttons.save))),e=e.map(e=>this.buttons[e.name]?w2utils.extend({},this.buttons[e.name],e):e)),this.toolbar.items.push(...e),this.toolbar.on("click",e=>{var i=this.trigger("toolbar",{target:e.target,originalEvent:e});if(!0!==i.isCancelled){let t;switch(e.detail.item.id){case"w2ui-reload":if(!0===(t=this.trigger("reload",{target:this.name})).isCancelled)return!1;this.reload(),t.finish();break;case"w2ui-column-on-off":e.detail.subItem?(s=e.detail.subItem.id,["w2ui-stateSave","w2ui-stateReset"].includes(s)?this[s.substring(5)]():"w2ui-skip"!=s&&this.columnOnOff(e,e.detail.subItem.id)):(this.initColumnOnOff(),setTimeout(()=>{query(`#w2overlay-${this.name}_toolbar-drop .w2ui-grid-skip`).off(".w2ui-grid").on("click.w2ui-grid",e=>{e.stopPropagation()}).on("keypress",e=>{13==e.keyCode&&(this.skip(e.target.value),this.toolbar.click("w2ui-column-on-off"))})},100));break;case"w2ui-add":if(!0===(t=this.trigger("add",{target:this.name,recid:null})).isCancelled)return!1;t.finish();break;case"w2ui-edit":{var s=this.getSelection();let e=null;if(1==s.length&&(e=s[0]),!0===(t=this.trigger("edit",{target:this.name,recid:e})).isCancelled)return!1;t.finish();break}case"w2ui-delete":this.delete();break;case"w2ui-save":this.save()}i.finish()}}),this.toolbar.on("refresh",e=>{if("w2ui-search"==e.target){let e=this.searchData;setTimeout(()=>{this.searchInitInput(this.last.field,1==e.length?e[0].value:null)},1)}})}}initResize(){let r=this;query(this.box).find(".w2ui-resizer").off(".grid-col-resize").on("click.grid-col-resize",function(e){e.stopPropagation?e.stopPropagation():e.cancelBubble=!0,e.preventDefault&&e.preventDefault()}).on("mousedown.grid-col-resize",function(e){e=e||window.event,r.last.colResizing=!0,r.last.tmp={x:e.screenX,y:e.screenY,gx:e.screenX,gy:e.screenY,col:parseInt(query(this).attr("name"))},r.last.tmp.tds=query(r.box).find("#grid_"+r.name+'_body table tr:first-child td[col="'+r.last.tmp.col+'"]'),e.stopPropagation?e.stopPropagation():e.cancelBubble=!0,e.preventDefault&&e.preventDefault();for(let e=0;e{r.resizeRecords(),r.scroll()},100),r.last.tmp.tds.css({width:t}),r.last.tmp.x=e.screenX,r.last.tmp.y=e.screenY))}).on("mouseup.grid-col-resize",function(e){query(document).off(".grid-col-resize"),r.resizeRecords(),r.scroll(),i.finish({originalEvent:e}),setTimeout(()=>{r.last.colResizing=!1},1)})}).on("dblclick.grid-col-resize",function(e){let t=parseInt(query(this).attr("name")),i=r.columns[t],s=0;if(!1===i.autoResize)return!0;e.stopPropagation?e.stopPropagation():e.cancelBubble=!0,e.preventDefault&&e.preventDefault(),query(r.box).find('.w2ui-grid-records td[col="'+t+'"] > div',r.box).each(()=>{var e=this.offsetWidth-this.scrollWidth;e{var t=query(e).get(0).parentNode;query(e).css({height:t.clientHeight+"px","margin-left":t.clientWidth-3+"px"})})}resizeBoxes(){var e=query(this.box).find(`#grid_${this.name}_header`),t=query(this.box).find(`#grid_${this.name}_toolbar`),i=query(this.box).find(`#grid_${this.name}_fsummary`),s=query(this.box).find(`#grid_${this.name}_summary`),l=query(this.box).find(`#grid_${this.name}_footer`),r=query(this.box).find(`#grid_${this.name}_body`);this.show.header&&e.css({top:"0px",left:"0px",right:"0px"}),this.show.toolbar&&t.css({top:0+(this.show.header?w2utils.getSize(e,"height"):0)+"px",left:"0px",right:"0px"}),0 div.w2ui-grid-box"),r=query(this.box).find(`#grid_${this.name}_header`),n=query(this.box).find(`#grid_${this.name}_toolbar`),a=query(this.box).find(`#grid_${this.name}_summary`),o=query(this.box).find(`#grid_${this.name}_fsummary`),h=query(this.box).find(`#grid_${this.name}_footer`),d=query(this.box).find(`#grid_${this.name}_body`),u=query(this.box).find(`#grid_${this.name}_columns`),c=query(this.box).find(`#grid_${this.name}_fcolumns`),p=query(this.box).find(`#grid_${this.name}_records`),f=query(this.box).find(`#grid_${this.name}_frecords`),m=query(this.box).find(`#grid_${this.name}_scroll1`);let g=8*String(this.total).length+10,y=(g<34&&(g=34),null!=this.lineNumberWidth&&(g=this.lineNumberWidth),!1),w=!1,b=0;for(let e=0;e table")[0]?.clientHeight??0)+(y?w2utils.scrollBarSize():0)&&(w=!0),this.fixedBody?(e=l[0]?.clientHeight-(this.show.header?w2utils.getSize(r,"height"):0)-(this.show.toolbar?w2utils.getSize(n,"height"):0)-("none"!=a.css("display")?w2utils.getSize(a,"height"):0)-(this.show.footer?w2utils.getSize(h,"height"):0),d.css("height",e+"px")):(r=(e=w2utils.getSize(u,"height")+w2utils.getSize(query(this.box).find("#grid_"+this.name+"_records table"),"height")+(y?w2utils.scrollBarSize():0))+(this.show.header?w2utils.getSize(r,"height"):0)+(this.show.toolbar?w2utils.getSize(n,"height"):0)+("none"!=a.css("display")?w2utils.getSize(a,"height"):0)+(this.show.footer?w2utils.getSize(h,"height"):0),l.css("height",r+"px"),d.css("height",e+"px"),s.css("height",w2utils.getSize(l,"height")+"px"));let v=this.records.length;n="object"!=typeof this.url?this.url:this.url.get;if(0==this.searchData.length||n||(v=this.last.searchIds.length),this.fixedBody||(w=!1),y||w?(u.find(":scope > table > tbody > tr:nth-child(1) td.w2ui-head-last").css("width",w2utils.scrollBarSize()+"px").show(),p.css({top:(0 table > tbody > tr:nth-child(1) td.w2ui-head-last").hide(),p.css({top:(0=this.recordHeight&&(e-=this.recordHeight,t++),this.fixedBody){for(let e=v;e',l+='',i.show.lineNumbers&&(s+=''),i.show.selectColumn&&(s+=''),i.show.expandColumn&&(s+=''),l+='',i.reorderRows&&(l+='');for(let e=0;ei.last.colEnd)&&!n.frozen||(r='',n.frozen?s+=r:l+=r)}s+=' ',l+=' ',query(i.box).find("#grid_"+i.name+"_frecords > table").append(s),query(i.box).find("#grid_"+i.name+"_records > table").append(l)}let _,q;if(0_&&!0!==C.hidden&&(C.hidden=!0,i=!0),C.gridMinWidth<_)&&!0===C.hidden&&(C.hidden=!1,i=!0)}if(!0===i)return void this.refresh();for(let e=0;eparseInt(E.max)&&(E.sizeCalculated=E.max+"px"),$+=parseInt(E.sizeCalculated))}let z=parseInt(_)-parseInt($);if(0 table > tbody > tr:nth-child(1) td.w2ui-head-last").css("width",w2utils.scrollBarSize()+"px").show();let O=1;this.show.lineNumbers&&(O+=g),this.show.selectColumn&&(O+=26),this.show.expandColumn&&(O+=26);for(let e=0;e table > tbody > tr:nth-child(1) td").add(c.find(":scope > table > tbody > tr:nth-child(1) td")).each(e=>{query(e).hasClass("w2ui-col-number")&&query(e).css("width",g+"px");var t=query(e).attr("col");if(null!=t){if("start"==t){let t=0;for(let e=0;e table > tbody > tr").length&&u.find(":scope > table > tbody > tr:nth-child(1) td").add(c.find(":scope > table > tbody > tr:nth-child(1) td")).html("").css({height:"0",border:"0",padding:"0",margin:"0"}),p.find(":scope > table > tbody > tr:nth-child(1) td").add(f.find(":scope > table > tbody > tr:nth-child(1) td")).each(e=>{query(e).hasClass("w2ui-col-number")&&query(e).css("width",g+"px");var t=query(e).attr("col");if(null!=t){if("start"==t){let t=0;for(let e=0;e table > tbody > tr:nth-child(1) td").add(o.find(":scope > table > tbody > tr:nth-child(1) td")).each(e=>{query(e).hasClass("w2ui-col-number")&&query(e).css("width",g+"px");var t=query(e).attr("col");if(null!=t){if("start"==t){let t=0;for(let e=0;e + ${w2utils.lang("Advanced Search")} + + + + + + `;for(let t=0;t",s),s.label=s.caption);var l=``;i+=` + + + "}}return i+=` + + +
    ${w2utils.lang(s.label)||""}${l}`;let e;switch(s.type){case"text":case"alphanumeric":case"hex":case"color":case"list":case"combo":case"enum":e="width: 250px;",-1!=["hex","color"].indexOf(s.type)&&(e="width: 90px;"),i+=``;break;case"int":case"float":case"money":case"currency":case"percent":case"date":case"time":case"datetime":e="width: 90px;","datetime"==s.type&&(e="width: 140px;"),i+=` + `;break;case"select":i+=``}i+=s.text+"
    + + + + +
    `}getOperators(e,t){let i=this.operators[this.operatorsMap[e]]||[],s=(null!=t&&Array.isArray(t)&&(i=t),"");return i.forEach(e=>{let t=e,i=e;Array.isArray(e)?(t=e[1],i=e[0]):w2utils.isPlainObject(e)&&(t=e.text,i=e.oper),null==t&&(t=e),s+=` +`}),s}initOperator(e){let i;var t=this.searches[e],s=this.getSearchData(t.field),l=query(`#w2overlay-${this.name}-search-overlay`),r=l.find(`#grid_${this.name}_range_`+e);let n=l.find(`#grid_${this.name}_field_`+e),a=l.find(`#grid_${this.name}_field2_`+e);var o=l.find(`#grid_${this.name}_operator_`+e).val();switch(n.show(),r.hide(),o){case"between":r.show();break;case"null":case"not null":n.hide(),n.val(o),n.trigger("change")}switch(t.type){case"text":case"alphanumeric":var h=n[0]._w2field;h&&h.reset();break;case"int":case"float":case"hex":case"color":case"money":case"currency":case"percent":case"date":case"time":case"datetime":n[0]._w2field||(new w2field(t.type,{el:n[0],...t.options}),new w2field(t.type,{el:a[0],...t.options}),setTimeout(()=>{n.trigger("keydown"),a.trigger("keydown")},1));break;case"list":case"combo":case"enum":i=t.options,"list"==t.type&&(i.selected={}),"enum"==t.type&&(i.selected=[]),s&&(i.selected=s.value),n[0]._w2field||(h=new w2field(t.type,{el:n[0],...i}),s&&null!=s.text&&h.set({id:s.value,text:s.text}));break;case"select":i='';for(let e=0;e'+t+""}else i+='"}n.html(i)}}initSearches(){var s=query(`#w2overlay-${this.name}-search-overlay`);for(let t=0;t{w2utils.isPlainObject(e)&&(i[t]=e.oper)}),r&&r.operator&&(e=r.operator);var l=this.defaultOperator[this.operatorsMap[l.type]],l=(-1==i.indexOf(e)&&(e=l),s.find(`#grid_${this.name}_operator_`+t).val(e),this.initOperator(t),s.find(`#grid_${this.name}_field_`+t)),n=s.find(`#grid_${this.name}_field2_`+t);null!=r&&(Array.isArray(r.value)?["in","not in"].includes(r.operator)?l[0]._w2field.set(r.value):(l.val(r.value[0]).trigger("change"),n.val(r.value[1]).trigger("change")):null!=r.value&&l.val(r.value).trigger("change"))}s.find(".w2ui-grid-search-advanced *[rel=search]").on("keypress",e=>{13==e.keyCode&&(this.search(),w2tooltip.hide(this.name+"-search-overlay"))})}getColumnsHTML(){let h=this,e="",t="";var i,s,l;return this.show.columnHeaders&&(t=0 ",h.columnGroups[e]),h.columnGroups[e].text=h.columnGroups[e].caption);""!=h.columnGroups[h.columnGroups.length-1].text&&h.columnGroups.push({text:""});h.show.lineNumbers&&(t+='
     
    ');h.show.selectColumn&&(t+='
     
    ');h.show.expandColumn&&(t+='
     
    ');let r=0;s+=``,h.reorderRows&&(s+='
     
    ');for(let e=0;e",a),a.text=a.caption);let i=0;for(let e=r;e`);var o=w2utils.lang("function"==typeof a.text?a.text(a):a.text);l=``+e+`
    `+`
    `+(o||" ")+"
    "}else{o=w2utils.lang("function"==typeof n.text?n.text(n):n.text);l=``+`
    ${o||" "}
    `+""}a&&a.frozen?t+=l:s+=l}r+=n.span}return t+="",s+=``,[t,s]}(),s=r(!1),e=l[0]+i[0]+s[0],l[1]+i[1]+s[1]):(l=r(!0),e=l[0],l[1])),[e,t];function r(t){let i="",s="",l=(h.show.lineNumbers&&(i+='
    #
    '),h.show.selectColumn&&(i+='
    '+`
    "),h.show.expandColumn&&(i+='
     
    '),0),r=0,n;s+=``,h.reorderRows&&(s+='
     
    ');for(let e=0;e ",o),o.text=o.caption),null==o.size&&(o.size="100%"),e==r&&(n=h.columnGroups[l++]||{},r+=n.span),(eh.last.colEnd)&&!o.frozen||o.hidden||!0===n.main&&!t||(a=h.getColumnCellHTML(e),o&&o.frozen?i+=a:s+=a)}return i+='
     
    ',s+='
     
    ',i+="",s+="",[i,s]}}getColumnCellHTML(t){var i=this.columns[t];if(null==i)return"";var e=!this.reorderColumns||this.columnGroups&&this.columnGroups.length?"":" w2ui-col-reorderable ";let s="";for(let e=0;e'+(!1!==i.resizable?'
    ':"")+'
    '+(a||" ")+"
    "}columnTooltipShow(e,t){var i=query(this.box).find("#grid_"+this.name+"_column_"+e),e=this.columns[e],s=this.columnTooltip;w2tooltip.show({name:this.name+"-column-tooltip",anchor:i.get(0),html:e?.tooltip,position:s})}columnTooltipHide(e,t){w2tooltip.hide(this.name+"-column-tooltip")}getRecordsHTML(){let e=this.records.length;var t="object"!=typeof this.url?this.url:this.url.get,t=((e=0==this.searchData.length||t?e:this.last.searchIds.length)>this.vs_start?this.last.show_extra=this.vs_extra:this.last.show_extra=this.vs_start,query(this.box).find(`#grid_${this.name}_records`));let i=Math.floor((t.get(0)?.clientHeight||0)/this.recordHeight)+this.last.show_extra+1;(!this.fixedBody||i>e)&&(i=e);var s=this.getRecordHTML(-1,0);let l=""+s[0],r="
    "+s[1];l+='',r+='';for(let e=0;e
    ',r+=' ',this.last.range_start=0,this.last.range_end=i,[l,r]}getSummaryHTML(){if(0!==this.summary.length){var s=this.getRecordHTML(-1,0);let t=""+s[0],i="
    "+s[1];for(let e=0;ethis.last.scrollLeft&&null==l&&(l=e),t+s-30>this.last.scrollLeft+n&&null==r&&(r=e),t+=s);null==r&&(r=this.columns.length-1)}if(null!=l&&(l<0&&(l=0),r<0&&(r=0),l==r&&(0this.last.colStart)for(let e=this.last.colStart;er;e--)a.find("#grid_"+this.name+"_columns #grid_"+this.name+"_column_"+e).remove(),a.find("#grid_"+this.name+'_records td[col="'+e+'"]').remove(),a.find("#grid_"+this.name+'_summary td[col="'+e+'"]').remove();if(l=l;s--)this.columns[s]&&(this.columns[s].frozen||this.columns[s].hidden)||(e.after(this.getColumnCellHTML(s)),f.each(e=>{var t=query(e).parent().attr("index");let i='';null!=t&&(i=this.getCellHTML(parseInt(t),s,!1)),query(e).after(i)}),g.each(e=>{var t=query(e).parent().attr("index");let i='';null!=t&&(i=this.getCellHTML(parseInt(t),s,!0)),query(e).after(i)}));if(r>this.last.colEnd)for(let s=this.last.colEnd+1;s<=r;s++)this.columns[s]&&(this.columns[s].frozen||this.columns[s].hidden)||(t.before(this.getColumnCellHTML(s)),m.each(e=>{var t=query(e).parent().attr("index");let i='';null!=t&&(i=this.getCellHTML(parseInt(t),s,!1)),query(e).before(i)}),y.each(e=>{var t=query(e).parent().attr("index")||-1,t=this.getCellHTML(parseInt(t),s,!0);query(e).before(t)}));this.last.colStart=l,this.last.colEnd=r}else{this.last.colStart=l,this.last.colEnd=r;var o=this.getColumnsHTML(),w=this.getRecordsHTML(),c=this.getSummaryHTML(),p=a.find(`#grid_${this.name}_columns`);let e=a.find(`#grid_${this.name}_records`);var b=a.find(`#grid_${this.name}_frecords`);let t=a.find(`#grid_${this.name}_summary`);p.find("tbody").html(o[1]),b.html(w[0]),e.prepend(w[1]),null!=c&&t.html(c[1]),setTimeout(()=>{e.find(":scope > table").filter(":not(table:first-child)").remove(),t[0]&&(t[0].scrollLeft=this.last.scrollLeft)},1)}this.resizeRecords()}let v=this.records.length;if(v>this.total&&-1!==this.total&&(v=this.total),0!==(v=0==this.searchData.length||i?v:this.last.searchIds.length)&&0!==d.length&&0!==d.prop("clientHeight")){v>this.vs_start?this.last.show_extra=this.vs_extra:this.last.show_extra=this.vs_start;let e=Math.round(d.prop("scrollTop")/this.recordHeight+1),t=e+(Math.round(d.prop("clientHeight")/this.recordHeight)-1);if(e>v&&(e=v),t>=v-1&&(t=v),query(this.box).find("#grid_"+this.name+"_footer .w2ui-footer-right").html((this.show.statusRange?w2utils.formatNumber(this.offset+e)+"-"+w2utils.formatNumber(this.offset+t)+(-1!=this.total?" "+w2utils.lang("of")+" "+w2utils.formatNumber(this.total):""):"")+(i&&this.show.statusBuffered?" ("+w2utils.lang("buffered")+" "+w2utils.formatNumber(v)+(0this.total&&-1!=this.total&&(i=this.total);var x=d.find("#grid_"+this.name+"_rec_top"),_=d.find("#grid_"+this.name+"_rec_bottom"),q=u.find("#grid_"+this.name+"_frec_top"),C=u.find("#grid_"+this.name+"_frec_bottom"),p=(-1!=String(x.next().prop("id")).indexOf("_expanded_row")&&(x.next().remove(),q.next().remove()),this.total>i&&-1!=String(_.prev().prop("id")).indexOf("_expanded_row")&&(_.prev().remove(),C.prev().remove()),parseInt(x.next().attr("line"))),o=parseInt(_.prev().attr("line"));let e,s,l,r,n;if(p=p-this.last.show_extra+2&&1i))break;s.remove(),l.remove()}e=d.find("#grid_"+this.name+"_rec_top").next(),"bottom"==(r=e.attr("line"))&&(r=i);for(let e=parseInt(r)-1;e>=t;e--)this.records[e-1]&&((l=this.records[e-1].w2ui)&&!Array.isArray(l.children)&&(l.expanded=!1),n=this.getRecordHTML(e-1,e),x.after(n[1]),q.after(n[0]))}k(),setTimeout(()=>{this.refreshRanges()},0);b=(t-1)*this.recordHeight;let a=(v-i)*this.recordHeight;function k(){h.markSearch&&(clearTimeout(h.last.marker_timer),h.last.marker_timer=setTimeout(()=>{var t=[];for(let e=0;e{var t=query(h.box).find('td[col="'+e.col+'"]:not(.w2ui-head)');w2utils.marker(t,e.search)})},50))}a<0&&(a=0),x.css("height",b+"px"),q.css("height",b+"px"),_.css("height",a+"px"),C.css("height",a+"px"),this.last.range_start=t,this.last.range_end=i,Math.floor(d.prop("scrollTop")/this.recordHeight)+Math.floor(d.prop("clientHeight")/this.recordHeight)+10>v&&!0!==this.last.pull_more&&(v
    '),h.last.pull_more=!0,h.last.fetch.offset+=h.limit,h.request("load")}).find("td").html(h.autoLoad?'
    ':'
    '+w2utils.lang("Load ${count} more...",{count:h.limit})+"
    "))}}}getRecordHTML(r,n,a){let o="",h="";var d=this.last.selection;let u;if(-1==r){o+='
    ',h+='',this.show.lineNumbers&&(o+=''),this.show.selectColumn&&(o+=''),this.show.expandColumn&&(o+=''),h+='',this.reorderRows&&(h+='');for(let e=0;e';t.frozen&&!t.hidden?o+=i:t.hidden||ethis.last.colEnd||(h+=i)}o+='',h+=''}else{var c="object"!=typeof this.url?this.url:this.url.get;if(!0!==a){if(0=this.last.searchIds.length)return"";r=this.last.searchIds[r]}else if(r>=this.records.length)return"";u=this.records[r]}else{if(r>=this.summary.length)return"";u=this.summary[r]}if(!u)return"";null==u.recid&&null!=this.recid&&null!=(c=this.parseField(u,this.recid))&&(u.recid=c);let e=!1,t=(-1!=d.indexes.indexOf(r)&&(e=!0),u.w2ui?u.w2ui.style:""),i=(null!=t&&"string"==typeof t||(t=""),u.w2ui?u.w2ui.class:"");if(null!=i&&"string"==typeof i||(i=""),o+='",h+='",this.show.lineNumbers&&(o+='"),this.show.selectColumn&&(o+='"),this.show.expandColumn){let e="";e=!0===u.w2ui?.expanded?"-":"+","none"!=u.w2ui?.expanded&&Array.isArray(u.w2ui?.children)&&u.w2ui?.children.length||(e="+"),"spinner"==u.w2ui?.expanded&&(e='
    '),o+='"}h+='',this.reorderRows&&(h+='");let s=0,l=0;for(;;){let e=1;var p,f=this.columns[s];if(null==f)break;if(f.hidden)s++,0this.last.colEnd)||f.frozen){if(u.w2ui&&"object"==typeof u.w2ui.colspan){var m=parseInt(u.w2ui.colspan[f.field])||null;if(1=this.columns.length);e++)this.columns[e].hidden&&t++;e=m-t,l=m-1}}var g=this.getCellHTML(r,s,a,e);f.frozen?o+=g:h+=g}s++}}o+='',h+=''}return o+="",h+="",[o,h]}getLineHTML(e){return"
    "+e+"
    "}getCellHTML(i,s,l,e){let r=this,n=this.columns[s];if(null==n)return"";let a=(!0!==l?this.records:this.summary)[i],{value:t,style:o,className:h,attr:d,divAttr:u}=this.getCellValue(i,s,l,!0);var c=-1!==i?this.getCellEditable(i,s):"";let p="max-height: "+parseInt(this.recordHeight)+"px;"+(n.clipboardCopy?"margin-right: 20px":"");var f=!l&&a?.w2ui?.changes&&null!=a.w2ui.changes[n.field],m=this.last.selection;let g=!1,y="";if(-1!=m.indexes.indexOf(i)&&(g=!0),null==e&&(e=a?.w2ui?.colspan&&a.w2ui.colspan[n.field]?a.w2ui.colspan[n.field]:1),0===s&&Array.isArray(a?.w2ui?.children)){let t=0,e=this.get(a.w2ui.parent_recid,!0);for(;;){if(null==e)break;t++;var w=this.records[e].w2ui;if(null==w||null==w.parent_recid)break;e=this.get(w.parent_recid,!0)}if(a.w2ui.parent_recid)for(let e=0;e';var b=0`}if(!0===n.info&&(n.info={}),null!=n.info){let e="w2ui-icon-info",t=("function"==typeof n.info.icon?e=n.info.icon(a,{self:this,index:i,colIndex:s,summary:!!l}):"object"==typeof n.info.icon?e=n.info.icon[this.parseField(a,n.field)]||"":"string"==typeof n.info.icon&&(e=n.info.icon),n.info.style||"");"function"==typeof n.info.style?t=n.info.style(a,{self:this,index:i,colIndex:s,summary:!!l}):"object"==typeof n.info.style?t=n.info.style[this.parseField(a,n.field)]||"":"string"==typeof n.info.style&&(t=n.info.style),y+=``}let v=t,x=(c&&-1!=["checkbox","check"].indexOf(c.type)&&(p+="text-align: center;",v=``,y=""),null==(v=`
    ${y}${String(v)}
    `)&&(v=""),"string"==typeof n.render&&(b=n.render.toLowerCase().split(":"),-1!=["number","int","float","money","currency","percent","size"].indexOf(b[0]))&&(o+="text-align: right;"),a?.w2ui&&("object"==typeof a.w2ui.style&&("string"==typeof a.w2ui.style[s]&&(o+=a.w2ui.style[s]+";"),"string"==typeof a.w2ui.style[n.field])&&(o+=a.w2ui.style[n.field]+";"),"object"==typeof a.w2ui.class)&&("string"==typeof a.w2ui.class[s]&&(h+=a.w2ui.class[s]+" "),"string"==typeof a.w2ui.class[n.field])&&(h+=a.w2ui.class[n.field]+" "),!1);g&&m.columns[i]?.includes(s)&&(x=!0);let _;return n.clipboardCopy&&(_=''),v='
    ",v=-1===i&&!0===l?'":v}clipboardCopy(e,t,i){var s=(i?this.summary:this.records)[e],l=this.columns[t];let r=l?this.parseField(s,l.field):"";"function"==typeof l.clipboardCopy&&(r=l.clipboardCopy(s,{self:this,index:e,colIndex:t,summary:!!i})),query(this.box).find("#grid_"+this.name+"_focus").text(r).get(0).select(),document.execCommand("copy")}showBubble(s,l,r){var n=this.columns[l].info;if(n){let i="";var a=this.records[s],e=query(this.box).find(`${r?".w2ui-grid-summary":""} #grid_${this.name}_data_${s}_${l} .w2ui-info`);if(this.last.bubbleEl&&w2tooltip.hide(this.name+"-bubble"),this.last.bubbleEl=e,null==n.fields){n.fields=[];for(let e=0;e';else{let e=this.getColumn(h[0]),t=(e=null==e?{field:h[0],caption:h[0]}:e)?this.parseField(a,e.field):"";1n.maxLength&&(t=t.substr(0,n.maxLength)+"..."),i+="")}}i+="
    "+(!0!==a?this.getLineHTML(n,u):"")+"'+(!0===a||u.w2ui&&!0===u.w2ui.hideCheckBox?"":'
    ')+"
    '+(!0!==a?`
    ${e}
    `:"")+"
    '+(!0!==a?'
     
    ':"")+"
    "+v+(_&&w2utils.stripTags(v)?_:"")+"
    "+e.text+""+((0===t?"0":t)||"")+"
    "}else if(w2utils.isPlainObject(t)){for(var d in i='',t){var u=t[d];if(""==u||"-"==u||"--"==u||"---"==u)i+='';else{var c=String(u).split(":");let e=this.getColumn(c[0]),t=(e=null==e?{field:c[0],caption:c[0]}:e)?this.parseField(a,e.field):"";1n.maxLength&&(t=t.substr(0,n.maxLength)+"..."),i+="")}}i+="
    "+d+""+((0===t?"0":t)||"")+"
    "}return w2tooltip.show(w2utils.extend({name:this.name+"-bubble",html:i,anchor:e.get(0),position:"top|bottom",class:"w2ui-info-bubble",style:"",hideOn:["doc-click"]},n.options??{})).hide(()=>[this.last.bubbleEl=null])}}getCellEditable(e,t){var i=this.columns[t],s=this.records[e];if(!s||!i)return null;let l=s.w2ui?s.w2ui.editable:null;return!1===l?null:(null!=l&&!0!==l||"function"==typeof(l=0 '}status(i){if(null!=i)query(this.box).find(`#grid_${this.name}_footer`).find(".w2ui-footer-left").html(i);else{let t="";i=this.getSelection();if(0{query(this.box).find("#grid_"+this.name+"_empty_msg").remove(),w2utils.lock(...i)},10)}unlock(e){setTimeout(()=>{query(this.box).find(".w2ui-message").hasClass("w2ui-closing")||w2utils.unlock(this.box,e)},25)}stateSave(e){var t={columns:[],show:w2utils.clone(this.show),last:{search:this.last.search,multi:this.last.multi,logic:this.last.logic,label:this.last.label,field:this.last.field,scrollTop:this.last.scrollTop,scrollLeft:this.last.scrollLeft},sortData:[],searchData:[]};let l;for(let e=0;e{this.stateColProps[e]&&(l=void 0!==i[e]?i[e]:this.colTemplate[e]||null,s[e]=l)}),t.columns.push(s)}for(let e=0;e{s||(0=this.columns.length)return null==(e=this.nextRow(e))?e:this.nextCell(e,-1,i);var s=this.records[e].w2ui,l=this.columns[t],s=s&&s.colspan&&!isNaN(s.colspan[l.field])?parseInt(s.colspan[l.field]):1;if(null==l)return null;if(l&&l.hidden||0===s)return this.nextCell(e,t,i);if(i){l=this.getCellEditable(e,t);if(null==l||-1!=["checkbox","check"].indexOf(l.type))return this.nextCell(e,t,i)}return{index:e,colIndex:t}}prevCell(e,t,i){t-=1;if(t<0)return null==(e=this.prevRow(e))?e:this.prevCell(e,this.columns.length,i);if(t<0)return null;var s=this.records[e].w2ui,l=this.columns[t],s=s&&s.colspan&&!isNaN(s.colspan[l.field])?parseInt(s.colspan[l.field]):1;if(null==l)return null;if(l&&l.hidden||0===s)return this.prevCell(e,t,i);if(i){l=this.getCellEditable(e,t);if(null==l||-1!=["checkbox","check"].indexOf(l.type))return this.prevCell(e,t,i)}return{index:e,colIndex:t}}nextRow(e,t,i){var s=this.last.searchIds;let l=null;if(-1==(i=null==i?1:i))return this.records.length-1;if(e+ithis.records.length)break;e+=i}var r=this.records[e].w2ui,n=this.columns[t],r=r&&r.colspan&&null!=n&&!isNaN(r.colspan[n.field])?parseInt(r.colspan[n.field]):1;l=0===r?this.nextRow(e,t,i):e}return l}prevRow(e,t,i){var s=this.last.searchIds;let l=null;if(-1==(i=null==i?1:i))return 0;if(0<=e-i&&0===s.length||0s[0]){if(e-=i,0{-1==i.indexOf(e)&&-1!=["label","attr","style","text","span","page","column","anchor","group","groupStyle","groupTitleStyle","groupCollapsible"].indexOf(e)&&(t.html[e]=t[e],delete t[e])}),t}function h(t,i){let s=["style","html"];Object.keys(t).forEach(e=>{-1==s.indexOf(e)&&-1!=["span","column","attr","text","label"].indexOf(e)&&t[e]&&!i.html[e]&&(i.html[e]=t[e])})}r=[],Object.keys(e).forEach(i=>{let s=e[i];if("group"==s.type){if(s.text=i,w2utils.isPlainObject(s.fields)){let i=s.fields;s.fields=[],Object.keys(i).forEach(e=>{let t=i[e];t.field=e,s.fields.push(o(t))})}r.push(s)}else if("tab"==s.type){let e={id:i,text:i},t=(s.style&&(e.style=s.style),a.push(e),l(s.fields).fields);t.forEach(e=>{e.html=e.html||{},e.html.page=a.length-1,h(s,e)}),r.push(...t)}else s.field=i,r.push(o(s))})}r.forEach(s=>{if("group"==s.type){let i={group:s.text||"",groupStyle:s.style||"",groupTitleStyle:s.titleStyle||"",groupCollapsible:!0===s.collapsible};Array.isArray(s.fields)&&s.fields.forEach(e=>{let t=w2utils.clone(e);null==t.html&&(t.html={}),w2utils.extend(t.html,i),Array("span","column","attr","label","page").forEach(e=>{null==t.html[e]&&null!=s[e]&&(t.html[e]=s[e])}),null==t.field&&null!=t.name&&(console.log("NOTICE: form field.name property is deprecated, please use field.field. Field ->",s),t.field=t.name),n.push(t)})}else{let e=w2utils.clone(s);null==e.field&&null!=e.name&&(console.log("NOTICE: form field.name property is deprecated, please use field.field. Field ->",s),e.field=e.name),n.push(e)}});return{fields:n,tabs:a}}(r),this.fields=e.fields,!a)&&0e.text()).then(e=>{this.formHTML=e,this.isGenerated=!0,this.box&&this.render(this.box)}):this.formURL||this.formHTML?this.formHTML&&(this.isGenerated=!0):(this.formHTML=this.generateHTML(),this.isGenerated=!0),"string"==typeof this.box&&(this.box=query(this.box).get(0)),this.box&&this.render(this.box)}get(t,i){if(0===arguments.length){var s=[];for(let e=0;ee[t],s)}catch(e){}return e}return this.record[t]}setValue(e,l){if((""===l||null==l||Array.isArray(l)&&0===l.length||w2utils.isPlainObject(l)&&0==Object.keys(l).length)&&(l=null),!this.nestedFields)return this.record[e]=l,!0;try{let s=this.record;return String(e).split(".").map((e,t,i)=>{i.length-1!==t?s=s[e]||(s[e]={},s[e]):s[e]=l}),!0}catch(e){return!1}}getFieldValue(e){let s=this.get(e);if(null!=s){var l=s.el;let t=this.getValue(e);e=this.getValue(e,!0);let i=l.value;["int","float","percent","money","currency"].includes(s.type)&&(i=s.w2field.clean(i)),["radio"].includes(s.type)&&(r=query(l).closest("div").find("input:checked").get(0),i=r?s.options.items[query(r).data("index")].id:null),["toggle","checkbox"].includes(s.type)&&(i=l.checked),-1!==["check","checks"].indexOf(s.type)&&(i=[],0<(r=query(l).closest("div").find("input:checked")).length&&r.each(e=>{e=s.options.items[query(e).data("index")];i.push(e.id)}),Array.isArray(t)||(t=[]));var r=l._w2field?.selected;if(["list","enum","file"].includes(s.type)&&r){var n=r,a=t;if(Array.isArray(n)){i=[];for(let e=0;e{var t=query(e).find(".w2ui-map.key").val(),e=query(e).find(".w2ui-map.value").val();"map"==s.type?i[t]=e:i.push(e)})),{current:i,previous:t,original:e}}}setFieldValue(e,r){let n=this.get(e);if(null!=n){var s=n.el;switch(n.type){case"toggle":case"checkbox":s.checked=!!r;break;case"radio":{r=r?.id??r;let i=query(s).closest("div").find("input");n.options.items.forEach((e,t)=>{e.id===r&&i.filter(`[data-index="${t}"]`).prop("checked",!0)});break}case"check":case"checks":{r=(r=Array.isArray(r)?r:null!=r?[r]:[]).map(e=>e?.id??e);let i=query(s).closest("div").find("input");n.options.items.forEach((e,t)=>{i.filter(`[data-index="${t}"]`).prop("checked",!!r.includes(e.id))});break}case"list":case"combo":let t=r;null==t?.id&&Array.isArray(n.options?.items)&&n.options.items.forEach(e=>{e.id===r&&(t=e)}),t!=r&&this.setValue(n.name,t),"list"==n.type?(n.w2field.selected=t,n.w2field.refresh()):n.el.value=t?.text??r;break;case"enum":case"file":{let s=[...r=Array.isArray(r)?r:null!=r?[r]:[]],l=!1;s.forEach((t,i)=>{null==t?.id&&Array.isArray(n.options.items)&&n.options.items.forEach(e=>{e.id==t&&(s[i]=e,l=!0)})}),l&&this.setValue(n.name,s),n.w2field.selected=s,n.w2field.refresh();break}case"map":case"array":"map"!=n.type||null!=r&&w2utils.isPlainObject(r)||(this.setValue(n.field,{}),r=this.getValue(n.field)),"array"!=n.type||null!=r&&Array.isArray(r)||(this.setValue(n.field,[]),r=this.getValue(n.field));var i=query(n.el).parent().find(".w2ui-map-container");n.el.mapRefresh(r,i);break;case"div":case"custom":query(s).html(r);break;case"html":case"empty":break;default:s.value=r??""}}}show(){var t=[];for(let e=0;e{!function(e){let t=!0;return e.each(e=>{"none"!=e.style.display&&(t=!1)}),t}(query(e).find(".w2ui-field"))?query(e).show():query(e).hide()})}change(){Array.from(arguments).forEach(e=>{e=this.get(e);e.$el&&e.$el.change()})}reload(e){return("object"!=typeof this.url?this.url:this.url.get)&&null!=this.recid?this.request(e):("function"==typeof e&&e(),new Promise(e=>{e()}))}clear(){0!=arguments.length?Array.from(arguments).forEach(e=>{let s=this.record;String(e).split(".").map((e,t,i)=>{i.length-1!==t?s=s[e]:delete s[e]}),this.refresh(e)}):(this.recid=null,this.record={},this.original=null,this.refresh(),this.hideErrors())}error(e){var t=this.trigger("error",{target:this.name,message:e,fetchCtrl:this.last.fetchCtrl,fetchOptions:this.last.fetchOptions});!0!==t.isCancelled&&(setTimeout(()=>{this.message(e)},1),t.finish())}message(e){return w2utils.message({owner:this,box:this.box,after:".w2ui-form-header"},e)}confirm(e){return w2utils.confirm({owner:this,box:this.box,after:".w2ui-form-header"},e)}validate(e){null==e&&(e=!0);var t=[];for(let e=0;e{var i=w2utils.extend({anchorClass:"w2ui-error",class:"w2ui-light",position:"right|left",hideOn:["input"]},t.options);if(null!=t.field){let e=t.field.el;"radio"===t.field.type?e=query(t.field.el).closest("div").get(0):["enum","file"].includes(t.field.type),w2tooltip.show(w2utils.extend({anchor:e,name:`${this.name}-${t.field.field}-error`,html:t.error},i))}}),query(e[0].field.$el).parents(".w2ui-page").off(".hideErrors").on("scroll.hideErrors",e=>{this.hideErrors()}))}hideErrors(){this.fields.forEach(e=>{w2tooltip.hide(`${this.name}-${e.field}-error`)})}getChanges(){let e={};return e=null!=this.original&&"object"==typeof this.original&&0!==Object.keys(this.record).length?function e(t,i,s){if(Array.isArray(t)&&Array.isArray(i))for(;t.length{if(-1!=["list","combo","enum"].indexOf(e.type)){var t={nestedFields:!0,record:s};let i=this.getValue.call(t,e.field);w2utils.isPlainObject(i)&&null!=i.id&&this.setValue.call(t,e.field,i.id),Array.isArray(i)&&i.forEach((e,t)=>{w2utils.isPlainObject(e)&&e.id&&(i[t]=e.id)})}var i;"map"==e.type&&(t={nestedFields:!0,record:s},(t=this.getValue.call(t,e.field))._order)&&delete t._order,"file"==e.type&&(t={nestedFields:!0,record:s},(i=this.getValue.call(t,e.field)??[]).forEach(e=>{delete e.file,delete e.modified}),this.setValue.call(t,e.field,i))}),!0===e&&Object.keys(s).forEach(e=>{this.get(e)||delete s[e]}),s}request(e,i){let s=this,l,r;var n=new Promise((e,t)=>{l=e,r=t});if("function"==typeof e&&(i=e,e=null),null==e&&(e={}),this.url&&("object"!=typeof this.url||this.url.get)){var a={action:"get"},e=(a.recid=this.recid,a.name=this.name,w2utils.extend(a,this.postData),w2utils.extend(a,e),this.trigger("request",{target:this.name,url:this.url,httpMethod:"GET",postData:a,httpHeaders:this.httpHeaders}));if(!0!==e.isCancelled){this.record={},this.original=null,this.lock(w2utils.lang(this.msgRefresh));let t=e.detail.url;if("object"==typeof t&&t.get&&(t=t.get),this.last.fetchCtrl)try{this.last.fetchCtrl.abort()}catch(e){}if(0!=Object.keys(this.routeData).length){var o=w2utils.parseRoute(t);if(0{200!=e?.status?e&&h(e):e.json().catch(h).then(e=>{var t=s.trigger("load",{target:s.name,fetchCtrl:this.last.fetchCtrl,fetchOptions:this.last.fetchOptions,data:e});!0!==t.isCancelled&&(null==e.error&&"error"===e.status&&(e.error=!0),e.record||Object.assign(e,{record:w2utils.clone(e)}),!0===e.error?s.error(w2utils.lang(e.message??this.msgServerError)):s.record=w2utils.clone(e.record),s.unlock(),t.finish(),s.refresh(),s.setFocus(),"function"==typeof i&&i(e),l(e))})}),e.finish(),n;function h(e){var t;"AbortError"!==e.name&&(s.unlock(),!0!==(t=s.trigger("error",{response:e,fetchCtrl:s.last.fetchCtrl,fetchOptions:s.last.fetchOptions})).isCancelled)&&(e.status&&200!=e.status?s.error(e.status+": "+e.statusText):(console.log("ERROR: Server request failed.",e,". ","Expected Response:",{error:!1,record:{field1:1,field2:"item"}},"OR:",{error:!0,message:"Error description"}),s.error(String(e))),t.finish(),r(e))}}}}submit(e,t){return this.save(e,t)}save(e,i){let s=this,l,r;var n=new Promise((e,t)=>{l=e,r=t}),a=("function"==typeof e&&(i=e,e=null),s.validate(!0));if(0===a.length)if(null==e&&(e={}),!s.url||"object"==typeof s.url&&!s.url.save)console.log("ERROR: Form cannot be saved because no url is defined.");else{s.lock(w2utils.lang(s.msgSaving)+' ');a={action:"save"},e=(a.recid=s.recid,a.name=s.name,w2utils.extend(a,s.postData),w2utils.extend(a,e),a.record=w2utils.clone(s.record),s.trigger("submit",{target:s.name,url:s.url,httpMethod:this.method??"POST",postData:a,httpHeaders:s.httpHeaders}));if(!0!==e.isCancelled){let t=e.detail.url;if("object"==typeof t&&t.save&&(t=t.save),s.last.fetchCtrl&&s.last.fetchCtrl.abort(),0{s.unlock(),200!=e?.status?h(e??{}):e.json().catch(h).then(e=>{var t=s.trigger("save",{target:s.name,fetchCtrl:this.last.fetchCtrl,fetchOptions:this.last.fetchOptions,data:e});!0!==t.isCancelled&&(!0===e.error?s.error(w2utils.lang(e.message??this.msgServerError)):s.original=null,t.finish(),s.refresh(),"function"==typeof i&&i(e),l(e))})}),e.finish(),n;function h(e){var t;"AbortError"!==e?.name&&(s.unlock(),!0!==(t=s.trigger("error",{response:e,fetchCtrl:s.last.fetchCtrl,fetchOptions:s.last.fetchOptions})).isCancelled)&&(e.status&&200!=e.status?s.error(e.status+": "+e.statusText):(console.log("ERROR: Server request failed.",e,". ","Expected Response:",{error:!1,record:{field1:1,field2:"item"}},"OR:",{error:!0,message:"Error description"}),s.error(String(e))),t.finish(),r())}}}}lock(e,t){var i=Array.from(arguments);i.unshift(this.box),w2utils.lock(...i)}unlock(e){var t=this.box;w2utils.unlock(t,e)}lockPage(e,t,i){e=query(this.box).find(".page-"+e);return!!e.length&&(w2utils.lock(e,t,i),!0)}unlockPage(e,t){e=query(this.box).find(".page-"+e);return!!e.length&&(w2utils.unlock(e,t),!0)}goto(e){this.page!==e&&(null!=e&&(this.page=e),!0===query(this.box).data("autoSize")&&(query(this.box).get(0).clientHeight=0),this.refresh())}generateHTML(){let s=[],t="",l,r,n,a;for(let e=0;e",h),h.html.label=h.html.caption),null==h.html.label&&(h.html.label=h.field),h.html=w2utils.extend({label:"",span:6,attr:"",text:"",style:"",page:0,column:0},h.html),null==l&&(l=h.html.page),null==r&&(r=h.html.column);let i=``;switch(h.type){case"pass":case"password":i=i.replace('type="text"','type="password"');break;case"checkbox":i=` + `;break;case"check":case"checks":{null==h.options.items&&null!=h.html.items&&(h.options.items=h.html.items);let t=h.options.items;i="",0<(t=Array.isArray(t)?t:[]).length&&(t=w2utils.normMenu.call(this,t,h));for(let e=0;e + +  ${t[e].text} + +
    `;break}case"radio":{i="",null==h.options.items&&null!=h.html.items&&(h.options.items=h.html.items);let t=h.options.items;0<(t=Array.isArray(t)?t:[]).length&&(t=w2utils.normMenu.call(this,t,h));for(let e=0;e + +  ${t[e].text} + +
    `;break}case"select":{i=`";break}case"textarea":i=``;break;case"toggle":i=` +
    `;break;case"map":case"array":h.html.key=h.html.key||{},h.html.value=h.html.value||{},h.html.tabindex_str=o,i=''+(h.html.text||"")+'
    ';break;case"div":case"custom":i='
    '+(h&&h.html&&h.html.html?h.html.html:"")+"
    ";break;case"html":case"empty":i=h&&h.html?(h.html.html||"")+(h.html.text||""):""}if(""!==t&&(l!=h.html.page||r!=h.html.column||h.html.group&&t!=h.html.group)&&(s[l][r]+="\n \n ",t=""),h.html.group&&t!=h.html.group){let e="";h.html.groupCollapsible&&(e=''),n+='\n
    \n
    "+e+w2utils.lang(h.html.group)+'
    \n
    ',t=h.html.group}if(null==h.html.anchor){let e=null!=h.html.span?"w2ui-span"+h.html.span:"",t=""+w2utils.lang("checkbox"!=h.type?h.html.label:h.html.text)+"";h.html.label||(t=""),n+='\n
    \n '+t+("empty"===h.type?i:"\n
    "+i+("array"!=h.type&&"map"!=h.type?w2utils.lang("checkbox"!=h.type?h.html.text:""):"")+"
    ")+"\n
    "}else s[h.html.page].anchors=s[h.html.page].anchors||{},s[h.html.page].anchors[h.html.anchor]='
    '+("empty"===h.type?i:"
    "+w2utils.lang("checkbox"!=h.type?h.html.label:h.html.text,!0)+i+w2utils.lang("checkbox"!=h.type?h.html.text:"")+"
    ")+"
    ";null==s[h.html.page]&&(s[h.html.page]={}),null==s[h.html.page][h.html.column]&&(s[h.html.page][h.html.column]=""),s[h.html.page][h.html.column]+=n,l=h.html.page,r=h.html.column}if(""!==t&&(s[l][r]+="\n
    \n
    "),this.tabs.tabs)for(let e=0;e",d),d.text=d.caption),d.text&&(u.text=d.text),d.style&&(u.style=d.style),d.class&&(u.class=d.class)):(u.text=i,-1!==["save","update","create"].indexOf(i.toLowerCase())?u.class="w2ui-btn-blue":u.class=""),e+='\n ",a++}e+="\n"}n="";for(let i=0;i',!s[i])return console.log(`ERROR: Page ${i} does not exist`),!1;s[i].before&&(n+=s[i].before),n+='
    ',Object.keys(s[i]).sort().forEach((e,t)=>{e==parseInt(e)&&(n+='
    '+(s[i][e]||"")+"\n
    ")}),n+="\n
    ",s[i].after&&(n+=s[i].after),n+="\n",s[i].anchors&&Object.keys(s[i].anchors).forEach((e,t)=>{n=n.replace(e,s[i].anchors[e])})}return n+=e}toggleGroup(e,t){var i,e=query(this.box).find('.w2ui-group-title[data-group="'+w2utils.base64encode(e)+'"]');0!==e.length&&(i=query(e.prop("nextElementSibling")),(t=void 0===t?"none"==i.css("display"):t)?(i.show(),e.find("span").addClass("w2ui-icon-collapse").removeClass("w2ui-icon-expand")):(i.hide(),e.find("span").addClass("w2ui-icon-expand").removeClass("w2ui-icon-collapse")))}action(e,t){var i=this.actions[e];let s=i;w2utils.isPlainObject(i)&&i.onClick&&(s=i.onClick);e=this.trigger("action",{target:e,action:i,originalEvent:t});!0!==e.isCancelled&&("function"==typeof s&&s.call(this,t),e.finish())}resize(){let o=this;var e=this.trigger("resize",{target:this.name});if(!0!==e.isCancelled){let s=query(this.box).find(":scope > div .w2ui-form-header"),l=query(this.box).find(":scope > div .w2ui-form-toolbar"),r=query(this.box).find(":scope > div .w2ui-form-tabs"),n=query(this.box).find(":scope > div .w2ui-page");var t=query(this.box).find(":scope > div .w2ui-page.page-"+this.page+" > div");let a=query(this.box).find(":scope > div .w2ui-buttons");var{headerHeight:i,tbHeight:h,tabsHeight:d}=u();function u(){var e=""!==o.header?w2utils.getSize(s,"height"):0,t=Array.isArray(o.toolbar?.items)&&0("string"!=typeof e&&console.log("ERROR: Arguments in refresh functions should be field names"),this.get(e,!0))).filter((e,t)=>null!=e):(query(this.box).find("input, textarea, select").each(e=>{var t=null!=query(e).attr("name")?query(e).attr("name"):query(e).attr("id"),i=this.get(t);if(i){var s=query(e).closest(".w2ui-page");if(0{query(e).off("click").on("click",function(e){let t=this.value;this.id&&(t=this.id),this.name&&(t=this.name),c.action(t,e)})});for(let e=0;e{t+=``}),s.$el.html(t)}this.W2FIELD_TYPES.includes(s.type)&&(s.w2field=s.w2field??new w2field(w2utils.extend({},s.options,{type:s.type})),s.w2field.render(s.el)),["map","array"].includes(s.type)&&!function(d){let u;d.el.mapAdd=function(e,t,i){var s=(e.disabled?" readOnly ":"")+(e.html.tabindex_str||""),i=` +
    + ${"map"==e.type?` + ${e.html.key.text||""} + `:""} + + ${e.html.value.text||""} +
    `;t.append(i)},d.el.mapRefresh=function(l,r){let n,a,o;var h;"map"==d.type&&(null==(l=w2utils.isPlainObject(l)?l:{})._order&&(l._order=Object.keys(l)),n=l._order),"array"==d.type&&(Array.isArray(l)||(l=[]),n=l.map((e,t)=>t));for(let e=r.find(".w2ui-map-field").length-1;e>=n.length;e--)r.find(`div[data-index='${e}']`).remove();for(let s=0;se.key==t)).length&&(i=h[0].value),a.val(t),o.val(i),!0!==d.disabled&&!1!==d.disabled||(a.prop("readOnly",!!d.disabled),o.prop("readOnly",!!d.disabled))}var e=n.length,t=r.find(`div[data-index='${e}']`),e=(0!==t.length||a&&""==a.val()&&""==o.val()||a&&(!0===a.prop("readOnly")||!0===a.prop("disabled"))||d.el.mapAdd(d,r,e),!0!==d.disabled&&!1!==d.disabled||(t.find(".key").prop("readOnly",!!d.disabled),t.find(".value").prop("readOnly",!!d.disabled)),query(d.el).get(0)?.nextSibling);query(e).find("input.w2ui-map").off(".mapChange").on("keyup.mapChange",function(e){var t=query(e.target).closest(".w2ui-map-field"),i=t.get(0).nextElementSibling,t=t.get(0).previousElementSibling,s=(13==e.keyCode&&((s=u??i)instanceof HTMLElement&&0<(s=query(s).find("input")).length&&s.get(0).focus(),u=void 0),query(e.target).hasClass("key")?"key":"value");38==e.keyCode&&t&&(query(t).find("input."+s).get(0).select(),e.preventDefault()),40==e.keyCode&&i&&(query(i).find("input."+s).get(0).select(),e.preventDefault())}).on("keydown.mapChange",function(e){38!=e.keyCode&&40!=e.keyCode||e.preventDefault()}).on("input.mapChange",function(e){var e=query(e.target).closest("div"),t=e.data("index"),i=e.get(0).nextElementSibling;if(""==e.find("input").val()||i){if(""==e.find("input").val()&&i){let t=!0;query(i).find("input").each(e=>{""!=e.value&&(t=!1)}),t&&query(i).remove()}}else d.el.mapAdd(d,r,parseInt(t)+1)}).on("change.mapChange",function(e){null==c.original&&(0{t._order.push(e.value)}),c.trigger("change",{target:d.field,field:d.field,originalEvent:e,value:{current:t,previous:i,original:s}}));!0!==l.isCancelled&&("map"==d.type&&(t._order=t._order.filter(e=>""!==e),delete t[""]),"array"==d.type&&(t=t.filter(e=>""!==e)),""==query(e.target).parent().find("input").val()&&(u=e.target),c.setValue(d.field,t),d.el.mapRefresh(t,r),l.finish())})}}(s),this.setFieldValue(s.field,this.getValue(s.name))}}return t.finish(),this.resize(),Date.now()-e}}}render(e){var t=Date.now();let i=this;"string"==typeof e&&(e=query(e).get(0));var s=this.trigger("render",{target:this.name,box:e??this.box});if(!0!==s.isCancelled&&(null!=e&&(0'+(""!==this.header?'
    '+w2utils.lang(this.header)+"
    ":"")+' '+this.formHTML+"",e=(query(this.box).attr("name",this.name).addClass("w2ui-reset w2ui-form").html(e),0this.refresh()):this.refresh(),this.last.observeResize=new ResizeObserver(()=>{this.resize()}),this.last.observeResize.observe(this.box),-1!=this.focus){let e=0,t=()=>{0 input, select, textarea, div > label:nth-child(1) > [type=radio]").filter(":not(.file-input)");null==i[e].offsetParent&&i.length>=e;)e++;i[e]&&(t=query(i[e]))}else"string"==typeof e&&(t=query(this.box).find(`[name='${e}']`));return 0 `,arrow:!1,advanced:null,transparent:!0},this.options=w2utils.extend({},e,t),t=this.options;break;case"date":e={format:w2utils.settings.dateFormat,keyboard:!0,autoCorrect:!0,start:null,end:null,blockDates:[],blockWeekdays:[],colored:{},btnNow:!0},this.options=w2utils.extend({type:"date"},e,t),t=this.options,null==query(this.el).attr("placeholder")&&query(this.el).attr("placeholder",t.format);break;case"time":e={format:w2utils.settings.timeFormat,keyboard:!0,autoCorrect:!0,start:null,end:null,btnNow:!0,noMinutes:!1},this.options=w2utils.extend({type:"time"},e,t),t=this.options,null==query(this.el).attr("placeholder")&&query(this.el).attr("placeholder",t.format);break;case"datetime":e={format:w2utils.settings.dateFormat+"|"+w2utils.settings.timeFormat,keyboard:!0,autoCorrect:!0,start:null,end:null,startTime:null,endTime:null,blockDates:[],blockWeekdays:[],colored:{},btnNow:!0,noMinutes:!1},this.options=w2utils.extend({type:"datetime"},e,t),t=this.options,null==query(this.el).attr("placeholder")&&query(this.el).attr("placeholder",t.placeholder||t.format);break;case"list":case"combo":e={items:[],selected:{},url:null,recId:null,recText:null,method:null,debounce:250,postData:{},minLength:1,cacheMax:250,maxDropHeight:350,maxDropWidth:null,minDropWidth:null,match:"begins",icon:null,iconStyle:"",align:"both",altRows:!0,renderDrop:null,compare:null,filter:!0,hideSelected:!1,prefix:"",suffix:"",msgNoItems:"No matches",msgSearch:"Type to search...",openOnFocus:!1,markSearch:!1,onSearch:null,onRequest:null,onLoad:null,onError:null},"function"==typeof t.items&&(t._items_fun=t.items),t.items=w2utils.normMenu.call(this,t.items),"list"===this.type&&(query(this.el).addClass("w2ui-select"),!w2utils.isPlainObject(t.selected))&&Array.isArray(t.items)&&t.items.forEach(e=>{e&&e.id===t.selected&&(t.selected=w2utils.clone(e))}),t=w2utils.extend({},e,t),this.options=t,w2utils.isPlainObject(t.selected)||(t.selected={}),this.selected=t.selected,query(this.el).attr("autocapitalize","off").attr("autocomplete","off").attr("autocorrect","off").attr("spellcheck","false"),null!=t.selected.text&&query(this.el).val(t.selected.text);break;case"enum":e={items:[],selected:[],max:0,url:null,recId:null,recText:null,debounce:250,method:null,postData:{},minLength:1,cacheMax:250,maxItemWidth:250,maxDropHeight:350,maxDropWidth:null,match:"contains",align:"",altRows:!0,openOnFocus:!1,markSearch:!1,renderDrop:null,renderItem:null,compare:null,filter:!0,hideSelected:!0,style:"",msgNoItems:"No matches",msgSearch:"Type to search...",onSearch:null,onRequest:null,onLoad:null,onError:null,onClick:null,onAdd:null,onNew:null,onRemove:null,onMouseEnter:null,onMouseLeave:null,onScroll:null},"function"==typeof(t=w2utils.extend({},e,t,{suffix:""})).items&&(t._items_fun=t.items),t.items=w2utils.normMenu.call(this,t.items),t.selected=w2utils.normMenu.call(this,t.selected),this.options=t,Array.isArray(t.selected)||(t.selected=[]),this.selected=t.selected;break;case"file":e={selected:[],max:0,maxSize:0,maxFileSize:0,maxItemWidth:250,maxDropHeight:350,maxDropWidth:null,readContent:!0,silent:!0,align:"both",altRows:!0,renderItem:null,style:"",onClick:null,onAdd:null,onRemove:null,onMouseEnter:null,onMouseLeave:null},t=w2utils.extend({},e,t),this.options=t,Array.isArray(t.selected)||(t.selected=[]),this.selected=t.selected,null==query(this.el).attr("placeholder")&&query(this.el).attr("placeholder",w2utils.lang("Attach files by dragging and dropping or Click to Select"))}query(this.el).css("box-sizing","border-box").addClass("w2field w2ui-input").off(".w2field").on("change.w2field",e=>{this.change(e)}).on("click.w2field",e=>{this.click(e)}).on("focus.w2field",e=>{this.focus(e)}).on("blur.w2field",e=>{"list"!==this.type&&this.blur(e)}).on("keydown.w2field",e=>{this.keyDown(e)}).on("keyup.w2field",e=>{this.keyUp(e)}),this.addPrefix(),this.addSuffix(),this.addSearch(),this.addMultiSearch(),this.change(new Event("change"))}else console.log("ERROR: w2field could only be applied to INPUT or TEXTAREA.",this.el)}get(){let e;return e=-1!==["list","enum","file"].indexOf(this.type)?this.selected:query(this.el).val()}set(e,t){-1!==["list","enum","file"].indexOf(this.type)?("list"!==this.type&&t?(Array.isArray(this.selected)||(this.selected=[]),this.selected.push(e),(t=w2menu.get(this.el.id+"_menu"))&&(t.options.selected=this.selected)):(null==e&&(e=[]),t="enum"!==this.type||Array.isArray(e)?e:[e],this.selected=t),query(this.el).trigger("input").trigger("change"),this.refresh()):query(this.el).val(e)}setIndex(e,t){if(-1!==["list","enum"].indexOf(this.type)){var i=this.options.items;if(i&&i[e])return"list"==this.type&&(this.selected=i[e]),"enum"==this.type&&(t||(this.selected=[]),this.selected.push(i[e])),(t=w2menu.get(this.el.id+"_menu"))&&(t.options.selected=this.selected),query(this.el).trigger("input").trigger("change"),this.refresh(),!0}return!1}refresh(){let s=this.options;var e=Date.now(),t=getComputedStyle(this.el);if("list"==this.type){if(query(this.el).parent().css("white-space","nowrap"),this.helpers.prefix&&this.helpers.prefix.hide(),!this.helpers.search)return;null==this.selected&&s.icon?s.prefix=` + + `:s.prefix="",this.addPrefix();let e=query(this.helpers.search_focus);var i=query(e[0].previousElementSibling);e.css({outline:"none"}),""===e.val()?(e.css("opacity",0),i.css("opacity",0),this.selected?.id?(n=this.selected.text,r=this.findItemIndex(s.items,this.selected.id),null!=n&&query(this.el).val(w2utils.lang(n)).data({selected:n,selectedIndex:r[0]})):(this.el.value="",query(this.el).removeData("selected selectedIndex"))):(e.css("opacity",1),i.css("opacity",1),query(this.el).val(""),setTimeout(()=>{this.helpers.prefix&&this.helpers.prefix.hide(),s.icon?(e.css("margin-left","17px"),query(this.helpers.search).find(".w2ui-icon-search").addClass("show-search")):(e.css("margin-left","0px"),query(this.helpers.search).find(".w2ui-icon-search").removeClass("show-search"))},1)),query(this.el).prop("readOnly")||query(this.el).prop("disabled")?setTimeout(()=>{this.helpers.prefix&&query(this.helpers.prefix).css("opacity","0.6"),this.helpers.suffix&&query(this.helpers.suffix).css("opacity","0.6")},1):setTimeout(()=>{this.helpers.prefix&&query(this.helpers.prefix).css("opacity","1"),this.helpers.suffix&&query(this.helpers.suffix).css("opacity","1")},1)}let l=this.helpers.multi;if(["enum","file"].includes(this.type)&&l){let i="";Array.isArray(this.selected)&&this.selected.forEach((e,t)=>{null!=e&&(i+=` +
    + ${"function"==typeof s.renderItem?s.renderItem(e,t,`
      
    `):` + ${e.icon?``:""} +
      
    + ${("enum"===this.type?e.text:e.name)??e.id??e} + ${e.size?` - ${w2utils.formatSize(e.size)}`:""} + `} +
    `)});var r,n=l.find(".w2ui-multi-items");s.style&&l.attr("style",l.attr("style")+";"+s.style),query(this.el).css("z-index","-1"),query(this.el).prop("readOnly")||query(this.el).prop("disabled")?setTimeout(()=>{l[0].scrollTop=0,l.addClass("w2ui-readonly").find(".li-item").css("opacity","0.9").parent().find(".li-search").hide().find("input").prop("readOnly",!0).closest(".w2ui-multi-items").find(".w2ui-list-remove").hide()},1):setTimeout(()=>{l.removeClass("w2ui-readonly").find(".li-item").css("opacity","1").parent().find(".li-search").show().find("input").prop("readOnly",!1).closest(".w2ui-multi-items").find(".w2ui-list-remove").show()},1),0${query(this.el).attr("placeholder")}`)),l.off(".w2item").on("scroll.w2item",e=>{e=this.trigger("scroll",{target:this.el,originalEvent:e});!0!==e.isCancelled&&(w2tooltip.hide(this.el.id+"_preview"),e.finish())}).find(".li-item").on("click.w2item",e=>{var i=query(e.target).closest(".li-item"),s=i.attr("index"),l=this.selected[s];if(!query(i).hasClass("li-search")){e.stopPropagation();let t;if(query(e.target).hasClass("w2ui-list-remove"))query(this.el).prop("readOnly")||query(this.el).prop("disabled")||!0!==(t=this.trigger("remove",{target:this.el,originalEvent:e,item:l})).isCancelled&&(this.selected.splice(s,1),query(this.el).trigger("input").trigger("change"),query(e.target).remove());else if(!0!==(t=this.trigger("click",{target:this.el,originalEvent:e.originalEvent,item:l})).isCancelled){let e=l.tooltip;if("file"===this.type&&(/image/i.test(l.type)&&(e=` +
    + +
    `),e+=` +
    +
    ${w2utils.lang("Name")}:
    +
    ${l.name}
    +
    ${w2utils.lang("Size")}:
    +
    ${w2utils.formatSize(l.size)}
    +
    ${w2utils.lang("Type")}:
    +
    ${l.type}
    +
    ${w2utils.lang("Modified")}:
    +
    ${w2utils.date(l.modified)}
    +
    `),e){let t=this.el.id+"_preview";w2tooltip.show({name:t,anchor:i.get(0),html:e,hideOn:["doc-click"],class:""}).show(e=>{query(`#w2overlay-${t} img`).on("load",function(e){var t=this.clientWidth,i=this.clientHeight;t<300&i<300||(i<=t&&300{var t=query(e.target).closest(".li-item");query(t).hasClass("li-search")||(t=this.selected[query(e.target).attr("index")],!0!==(e=this.trigger("mouseEnter",{target:this.el,originalEvent:e,item:t})).isCancelled&&e.finish())}).on("mouseleave.w2item",e=>{var t=query(e.target).closest(".li-item");query(t).hasClass("li-search")||(t=this.selected[query(e.target).attr("index")],!0!==(e=this.trigger("mouseLeave",{target:this.el,originalEvent:e,item:t})).isCancelled&&e.finish())}),"enum"===this.type?this.helpers.multi.find("input").css({width:"15px"}):this.helpers.multi.find(".li-search").hide(),this.resize()}return Date.now()-e}resize(){var e=this.el.clientWidth,t=getComputedStyle(this.el),i=this.helpers.search,s=this.helpers.multi,l=this.helpers.suffix,r=this.helpers.prefix,i=(i&&query(i).css("width",e),s&&query(s).css("width",e-parseInt(t["margin-left"],10)-parseInt(t["margin-right"],10)),l&&this.addSuffix(),r&&this.addPrefix(),this.helpers.multi);if(["enum","file"].includes(this.type)&&i){query(this.el).css("height","auto");let e=query(i).find(":scope div.w2ui-multi-items").get(0).clientHeight+5;(e=(e=e<20?20:e)>this.tmp["max-height"]?this.tmp["max-height"]:e)e&&(e=s),query(i).css({height:e+"px",overflow:e==this.tmp["max-height"]?"auto":"hidden"}),query(i).css("height",e+"px"),query(this.el).css({height:e+"px"})}this.tmp.current_width=e}reset(){null!=this.tmp&&(query(this.el).css("height","auto"),Array("padding-left","padding-right","background-color","border-color").forEach(e=>{this.tmp&&null!=this.tmp["old-"+e]&&(query(this.el).css(e,this.tmp["old-"+e]),delete this.tmp["old-"+e])}),clearInterval(this.tmp.sizeTimer)),query(this.el).val(this.clean(query(this.el).val())).removeClass("w2field").removeData("selected selectedIndex").off(".w2field"),Object.keys(this.helpers).forEach(e=>{query(this.helpers[e]).remove()}),this.helpers={}}clean(e){var t;return e="number"!=typeof e&&(t=this.options,e=String(e).trim(),["int","float","money","currency","percent"].includes(this.type))?""!==(e="string"==typeof e?(e=t.autoFormat&&(["money","currency"].includes(this.type)&&(e=String(e).replace(t.moneyRE,"")),"percent"===this.type&&(e=String(e).replace(t.percentRE,"")),["int","float"].includes(this.type))?String(e).replace(t.numberRE,""):e).replace(/\s+/g,"").replace(new RegExp(t.groupSymbol,"g"),"").replace(t.decimalSymbol,"."):e)&&w2utils.isFloat(e)?Number(e):"":e}format(e){var t=this.options;if(t.autoFormat&&""!==e){switch(this.type){case"money":case"currency":""!==(e=w2utils.formatNumber(e,t.currencyPrecision,!0))&&(e=t.currencyPrefix+e+t.currencySuffix);break;case"percent":""!==(e=w2utils.formatNumber(e,t.precision,!0))&&(e+="%");break;case"float":e=w2utils.formatNumber(e,t.precision,!0);break;case"int":e=w2utils.formatNumber(e,0,!0)}var i=parseInt(1e3).toLocaleString(w2utils.settings.locale,{useGrouping:!0}).slice(1,2);i!==this.options.groupSymbol&&(e=e.replaceAll(i,this.options.groupSymbol))}return e}change(e){if(-1!==["int","float","money","currency","percent"].indexOf(this.type)){var t=query(this.el).val(),i=this.format(this.clean(query(this.el).val()));if(""!==t&&t!=i)return query(this.el).val(i),e.stopPropagation(),e.preventDefault(),!1}if("color"===this.type){let e=query(this.el).val();"rgb"!==e.substr(0,3).toLowerCase()&&(e="#"+e,8!==(t=query(this.el).val().length))&&6!==t&&3!==t&&(e="");i=query(this.el).get(0).nextElementSibling;query(i).find("div").css("background-color",e),query(this.el).hasClass("has-focus")&&this.updateOverlay()}if(-1!==["list","enum","file"].indexOf(this.type)&&this.refresh(),-1!==["date","time","datetime"].indexOf(this.type)){let e=parseInt(this.el.value);w2utils.isInt(this.el.value)&&3e3{this.updateOverlay()},100)}var t;"file"==this.type&&(t=query(this.el).get(0).previousElementSibling,query(t).addClass("has-focus")),query(this.el).addClass("has-focus")}}blur(e){var i,s=query(this.el).val().trim();if(query(this.el).removeClass("has-focus"),["int","float","money","currency","percent"].includes(this.type)&&""!==s){let e=s,t="";this.isStrValid(s)?(i=this.clean(s),null!=this.options.min&&i= "+this.options.min),null!=this.options.max&&i>this.options.max&&(e=this.options.max,t="Should be <= "+this.options.max)):e="",this.options.autoCorrect&&(query(this.el).val(e).trigger("input").trigger("change"),t)&&(w2tooltip.show({name:this.el.id+"_error",anchor:this.el,html:t}),setTimeout(()=>{w2tooltip.hide(this.el.id+"_error")},3e3))}["date","time","datetime"].includes(this.type)&&this.options.autoCorrect&&""!==s&&(i="date"==this.type?w2utils.isDate:"time"==this.type?w2utils.isTime:w2utils.isDateTime,w2date.inRange(this.el.value,this.options)&&i.bind(w2utils)(this.el.value,this.options.format)||query(this.el).val("").trigger("input").trigger("change")),"enum"===this.type&&query(this.helpers.multi).find("input").val("").css("width","15px"),"file"==this.type&&(s=this.el.previousElementSibling,query(s).removeClass("has-focus")),"list"===this.type&&(this.el.value=this.selected?.text??"")}keyDown(t,i){var e,s=this.options,i=t.keyCode||i&&i.keyCode;let l=!1,r,n,a,o,h,d;if(["int","float","money","currency","percent","hex","bin","color","alphanumeric"].includes(this.type)&&!(t.metaKey||t.ctrlKey||t.altKey||this.isStrValid(t.key??"1",!0)||[9,8,13,27,37,38,39,40,46].includes(t.keyCode)))return t.preventDefault(),t.stopPropagation?t.stopPropagation():t.cancelBubble=!0,!1;if(["int","float","money","currency","percent"].includes(this.type)){if(!s.keyboard||query(this.el).prop("readOnly")||query(this.el).prop("disabled"))return;switch(r=parseFloat(query(this.el).val().replace(s.moneyRE,""))||0,n=s.step,(t.ctrlKey||t.metaKey)&&(n=10*s.step),i){case 38:t.shiftKey||(h=r+n<=s.max||null==s.max?Number((r+n).toFixed(12)):s.max,query(this.el).val(h).trigger("input").trigger("change"),l=!0);break;case 40:t.shiftKey||(h=r-n>=s.min||null==s.min?Number((r-n).toFixed(12)):s.min,query(this.el).val(h).trigger("input").trigger("change"),l=!0)}l&&(t.preventDefault(),this.moveCaret2end())}if(["date","datetime"].includes(this.type)){if(!s.keyboard||query(this.el).prop("readOnly")||query(this.el).prop("disabled"))return;var u=("date"==this.type?w2utils.isDate:w2utils.isDateTime).bind(w2utils),c=("date"==this.type?w2utils.formatDate:w2utils.formatDateTime).bind(w2utils);switch(a=864e5,n=1,(t.ctrlKey||t.metaKey)&&(n=10),(o=u(query(this.el).val(),s.format,!0))||(o=new Date,a=0),i){case 38:t.shiftKey||(10==n?o.setMonth(o.getMonth()+1):o.setTime(o.getTime()+a),d=c(o.getTime(),s.format),query(this.el).val(d).trigger("input").trigger("change"),l=!0);break;case 40:t.shiftKey||(10==n?o.setMonth(o.getMonth()-1):o.setTime(o.getTime()-a),d=c(o.getTime(),s.format),query(this.el).val(d).trigger("input").trigger("change"),l=!0)}l&&(t.preventDefault(),this.moveCaret2end(),this.updateOverlay())}if("time"===this.type){if(!s.keyboard||query(this.el).prop("readOnly")||query(this.el).prop("disabled"))return;n=t.ctrlKey||t.metaKey?60:1,r=query(this.el).val();let e=w2date.str2min(r)||w2date.str2min((new Date).getHours()+":"+((new Date).getMinutes()-1));switch(i){case 38:t.shiftKey||(e+=n,l=!0);break;case 40:t.shiftKey||(e-=n,l=!0)}l&&(t.preventDefault(),query(this.el).val(w2date.min2str(e)).trigger("input").trigger("change"),this.moveCaret2end())}if(["list","enum"].includes(this.type))switch(i){case 8:case 46:"list"==this.type?""==query(this.helpers.search_focus).val()&&(this.selected=null,w2menu.hide(this.el.id+"_menu"),query(this.el).val("").trigger("input").trigger("change")):""==query(this.helpers.multi).find("input").val()&&(w2menu.hide(this.el.id+"_menu"),this.selected.pop(),(e=w2menu.get(this.el.id+"_menu"))&&(e.options.selected=this.selected),this.refresh());break;case 9:case 16:break;case 27:w2menu.hide(this.el.id+"_menu"),this.refresh()}}keyUp(t){if("list"==this.type){let e=query(this.helpers.search_focus);""!==e.val()?query(this.el).attr("placeholder",""):query(this.el).attr("placeholder",this.tmp.pholder),13==t.keyCode&&setTimeout(()=>{e.val(""),w2menu.hide(this.el.id+"_menu"),this.refresh()},1),[38,40].includes(t.keyCode)&&!this.tmp.overlay.overlay.displayed&&this.updateOverlay(),this.refresh()}var e,i;"combo"==this.type&&this.updateOverlay(),"enum"==this.type&&(e=this.helpers.multi.find("input"),i=getComputedStyle(e.get(0)),i=w2utils.getStrWidth(e.val(),`font-family: ${i["font-family"]}; font-size: ${i["font-size"]};`),e.css({width:i+15+"px"}),this.resize(),[38,40].includes(t.keyCode))&&!this.tmp.overlay?.overlay?.displayed&&this.updateOverlay()}findItemIndex(e,i,s){let l=[];var t;return s=s||[],["list","combo","enum"].includes(this.type)&&this.options.url&&(t=w2menu.get(this.el.id+"_menu"))&&(e=t.options.items,this.options.items=e),e.forEach((e,t)=>{e.id===i&&(l=s.concat([t]),this.options.index=[t]),0==l.length&&e.items&&0{e=e.detail.color;query(this.el).val(e).trigger("input").trigger("change")}).liveUpdate(e=>{e=e.detail.color;query(this.helpers.suffix).find(":scope > div").css("background-color","#"+e)})}if(["list","combo","enum"].includes(this.type)){var t;this.el;let s=this.el;"enum"===this.type&&(t=this.helpers.multi.get(0),s=query(t).find("input").get(0)),"list"===this.type&&(t=this.selected,w2utils.isPlainObject(t)&&0{var t,i;["list","combo"].includes(this.type)?(this.selected=e.detail.item,query(s).val(""),query(this.el).val(this.selected.text).trigger("input").trigger("change"),this.focus({showMenu:!1})):(i=this.selected,(t=e.detail?.item)&&!0!==(e=this.trigger("add",{target:this.el,item:t,originalEvent:e})).isCancelled&&(i.length>=l.max&&0{e=e.detail.date;null!=e&&query(this.el).val(e).trigger("input").trigger("change")})}isStrValid(e,t){let i=!0;switch(this.type){case"int":i=!(!t||!["-",this.options.groupSymbol].includes(e))||w2utils.isInt(e.replace(this.options.numberRE,""));break;case"percent":e=e.replace(/%/g,"");case"float":i=!(!t||!["-","",this.options.decimalSymbol,this.options.groupSymbol].includes(e))||w2utils.isFloat(e.replace(this.options.numberRE,""));break;case"money":case"currency":i=!(!t||!["-",this.options.decimalSymbol,this.options.groupSymbol,this.options.currencyPrefix,this.options.currencySuffix].includes(e))||w2utils.isFloat(e.replace(this.options.moneyRE,""));break;case"bin":i=w2utils.isBin(e);break;case"color":case"hex":i=w2utils.isHex(e);break;case"alphanumeric":i=w2utils.isAlphaNumeric(e)}return i}addPrefix(){var e,t;this.options.prefix&&(t=getComputedStyle(this.el),null==this.tmp["old-padding-left"]&&(this.tmp["old-padding-left"]=t["padding-left"]),this.helpers.prefix&&query(this.helpers.prefix).remove(),query(this.el).before(`
    ${this.options.prefix}
    `),e=query(this.el).get(0).previousElementSibling,query(e).css({color:t.color,"font-family":t["font-family"],"font-size":t["font-size"],height:this.el.clientHeight+"px","padding-top":t["padding-top"],"padding-bottom":t["padding-bottom"],"padding-left":this.tmp["old-padding-left"],"padding-right":0,"margin-top":parseInt(t["margin-top"],10)+2+"px","margin-bottom":parseInt(t["margin-bottom"],10)+1+"px","margin-left":t["margin-left"],"margin-right":0,"z-index":1}),query(this.el).css("padding-left",e.clientWidth+"px !important"),this.helpers.prefix=e)}addSuffix(){if(this.options.suffix||this.options.arrow){let e,t=this;var i=getComputedStyle(this.el),s=(null==this.tmp["old-padding-right"]&&(this.tmp["old-padding-right"]=i["padding-right"]),parseInt(i["padding-right"]||0));this.options.arrow&&(this.helpers.arrow&&query(this.helpers.arrow).remove(),query(this.el).after('
     
    '),e=query(this.el).get(0).nextElementSibling,query(e).css({color:i.color,"font-family":i["font-family"],"font-size":i["font-size"],height:this.el.clientHeight+"px",padding:0,"margin-top":parseInt(i["margin-top"],10)+1+"px","margin-bottom":0,"border-left":"1px solid silver",width:"16px",transform:"translateX(-100%)"}).on("mousedown",function(e){query(e.target).hasClass("arrow-up")&&t.keyDown(e,{keyCode:38}),query(e.target).hasClass("arrow-down")&&t.keyDown(e,{keyCode:40})}),s+=e.clientWidth,query(this.el).css("padding-right",s+"px !important"),this.helpers.arrow=e),""!==this.options.suffix&&(this.helpers.suffix&&query(this.helpers.suffix).remove(),query(this.el).after(`
    ${this.options.suffix}
    `),e=query(this.el).get(0).nextElementSibling,query(e).css({color:i.color,"font-family":i["font-family"],"font-size":i["font-size"],height:this.el.clientHeight+"px","padding-top":i["padding-top"],"padding-bottom":i["padding-bottom"],"padding-left":0,"padding-right":i["padding-right"],"margin-top":parseInt(i["margin-top"],10)+2+"px","margin-bottom":parseInt(i["margin-bottom"],10)+1+"px",transform:"translateX(-100%)"}),query(this.el).css("padding-right",e.clientWidth+"px !important"),this.helpers.suffix=e)}}addSearch(){if("list"===this.type){this.helpers.search&&query(this.helpers.search).remove();let e=parseInt(query(this.el).attr("tabIndex")),t=(isNaN(e)||-1===e||(this.tmp["old-tabIndex"]=e),null!=(e=this.tmp["old-tabIndex"]?this.tmp["old-tabIndex"]:e)&&!isNaN(e)||(e=0),"");var i=` +
    + + +
    `,i=(query(this.el).attr("tabindex",-1).before(i),query(this.el).get(0).previousElementSibling),s=(this.helpers.search=i,this.helpers.search_focus=query(i).find("input").get(0),getComputedStyle(this.el));query(i).css({width:this.el.clientWidth+"px","margin-top":s["margin-top"],"margin-left":s["margin-left"],"margin-bottom":s["margin-bottom"],"margin-right":s["margin-right"]}).find("input").css({cursor:"default",width:"100%",opacity:1,padding:s.padding,margin:s.margin,border:"1px solid transparent","background-color":"transparent"}),query(i).find("input").off(".helper").on("focus.helper",e=>{query(e.target).val(""),this.tmp.pholder=query(this.el).attr("placeholder")??"",this.focus(e),e.stopPropagation()}).on("blur.helper",e=>{query(e.target).val(""),null!=this.tmp.pholder&&query(this.el).attr("placeholder",this.tmp.pholder),this.blur(e),e.stopPropagation()}).on("keydown.helper",e=>{this.keyDown(e)}).on("keyup.helper",e=>{this.keyUp(e)}),query(i).on("click",e=>{query(e.target).find("input").focus()})}}addMultiSearch(){if(["enum","file"].includes(this.type)){query(this.helpers.multi).remove();let e="";var l,r,n=getComputedStyle(this.el),a=w2utils.stripSpaces(` + margin-top: 0px; + margin-bottom: 0px; + margin-left: ${n["margin-left"]}; + margin-right: ${n["margin-right"]}; + width: ${w2utils.getSize(this.el,"width")-parseInt(n["margin-left"],10)-parseInt(n["margin-right"],10)}px; + `);null==this.tmp["min-height"]&&(l=this.tmp["min-height"]=parseInt(("none"!=n["min-height"]?n["min-height"]:0)||0),r=parseInt(n.height),this.tmp["min-height"]=Math.max(l,r)),null==this.tmp["max-height"]&&"none"!=n["max-height"]&&(this.tmp["max-height"]=parseInt(n["max-height"]));let t="",i=(null!=query(this.el).attr("id")&&(t=`id="${query(this.el).attr("id")}_search"`),parseInt(query(this.el).attr("tabIndex"))),s=(isNaN(i)||-1===i||(this.tmp["old-tabIndex"]=i),null!=(i=this.tmp["old-tabIndex"]?this.tmp["old-tabIndex"]:i)&&!isNaN(i)||(i=0),"enum"===this.type&&(e=` +
    +
    + +
    +
    `),"file"===this.type&&(e=` +
    +
    + +
    +
    + +
    +
    `),this.tmp["old-background-color"]=n["background-color"],this.tmp["old-border-color"]=n["border-color"],query(this.el).before(e).css({"border-color":"transparent","background-color":"transparent"}),query(this.el.previousElementSibling));this.helpers.multi=s,query(this.el).attr("tabindex",-1),s.on("click",e=>{this.focus(e)}),s.find("input:not(.file-input)").on("click",e=>{this.click(e)}).on("focus",e=>{this.focus(e)}).on("blur",e=>{this.blur(e)}).on("keydown",e=>{this.keyDown(e)}).on("keyup",e=>{this.keyUp(e)}),"file"===this.type&&s.find("input.file-input").off(".drag").on("click.drag",e=>{e.stopPropagation(),query(this.el).prop("readOnly")||query(this.el).prop("disabled")||this.focus(e)}).on("dragenter.drag",e=>{query(this.el).prop("readOnly")||query(this.el).prop("disabled")||s.addClass("w2ui-file-dragover")}).on("dragleave.drag",e=>{query(this.el).prop("readOnly")||query(this.el).prop("disabled")||s.removeClass("w2ui-file-dragover")}).on("drop.drag",e=>{query(this.el).prop("readOnly")||query(this.el).prop("disabled")||(s.removeClass("w2ui-file-dragover"),Array.from(e.dataTransfer.files).forEach(e=>{this.addFile(e)}),this.focus(e),e.preventDefault(),e.stopPropagation())}).on("dragover.drag",e=>{e.preventDefault(),e.stopPropagation()}).on("change.drag",e=>{void 0!==e.target.files&&Array.from(e.target.files).forEach(e=>{this.addFile(e)}),this.focus(e)}),this.refresh()}}addFile(t){var e=this.options,s=this.selected;let l={name:t.name,type:t.type,modified:t.lastModifiedDate,size:t.size,content:null,file:t},i=0,r=0,n=[],a=(Array.isArray(s)&&s.forEach(e=>{e.name==t.name&&e.size==t.size&&n.push(w2utils.lang('The file "${name}" (${size}) is already added.',{name:t.name,size:w2utils.formatSize(t.size)})),i+=e.size,r++}),0!==e.maxFileSize&&l.size>e.maxFileSize&&n.push(w2utils.lang("Maximum file size is ${size}",{size:w2utils.formatSize(e.maxFileSize)})),0!==e.maxSize&&i+l.size>e.maxSize&&n.push(w2utils.lang("Maximum total size is ${size}",{size:w2utils.formatSize(e.maxSize)})),0!==e.max&&r>=e.max&&n.push(w2utils.lang("Maximum number of files is ${count}",{count:e.max})),this.trigger("add",{target:this.el,file:l,total:r,totalSize:i,errors:n}));if(!0!==a.isCancelled)if(!0!==e.silent&&0")}),console.log("ERRORS (while adding files): ",n);else if(s.push(l),"undefined"!=typeof FileReader&&!0===e.readContent){s=new FileReader;let i=this;s.onload=function(e){var e=e.target.result,t=e.indexOf(",");l.content=e.substr(t+1),i.refresh(),query(i.el).trigger("input").trigger("change"),a.finish()},s.readAsDataURL(t)}else this.refresh(),query(this.el).trigger("input").trigger("change"),a.finish()}moveCaret2end(){setTimeout(()=>{this.el.setSelectionRange(this.el.value.length,this.el.value.length)},0)}}!function(r){function e(){var t,i;t=window,i={w2ui:w2ui,w2utils:w2utils,query:query,w2locale:w2locale,w2event:w2event,w2base:w2base,w2popup:w2popup,w2alert:w2alert,w2confirm:w2confirm,w2prompt:w2prompt,Dialog:Dialog,w2tooltip:w2tooltip,w2menu:w2menu,w2color:w2color,w2date:w2date,Tooltip:Tooltip,w2toolbar:w2toolbar,w2sidebar:w2sidebar,w2tabs:w2tabs,w2layout:w2layout,w2grid:w2grid,w2form:w2form,w2field:w2field},Object.keys(i).forEach(e=>{t[e]=i[e]})}var t=String(void 0).split("?")[1]||"";function i(t,i){var e;if(r.isPlainObject(t)){let e;return"w2form"==i&&(e=new w2form(t),0{let i=r(t).data("w2field");return i,(i=new w2field(s,l)).render(t),i})},r.fn.w2form=function(e){return i.call(this,e,"w2form")},r.fn.w2grid=function(e){return i.call(this,e,"w2grid")},r.fn.w2layout=function(e){return i.call(this,e,"w2layout")},r.fn.w2sidebar=function(e){return i.call(this,e,"w2sidebar")},r.fn.w2tabs=function(e){return i.call(this,e,"w2tabs")},r.fn.w2toolbar=function(e){return i.call(this,e,"w2toolbar")},r.fn.w2popup=function(e){0{w2utils.marker(t,i)})},r.fn.w2tag=function(i,s){return this.each((e,t)=>{null==i&&null==s?w2tooltip.hide():("object"==typeof i?s=i:(s=s??{}).html=i,w2tooltip.show(t,s))})},r.fn.w2overlay=function(i,s){return this.each((e,t)=>{null==i&&null==s?w2tooltip.hide():("object"==typeof i?s=i:s.html=i,Object.assign(s,{class:"w2ui-white",hideOn:["doc-click"]}),w2tooltip.show(t,s))})},r.fn.w2menu=function(i,s){return this.each((e,t)=>{"object"==typeof i&&(s=i),"object"==typeof i?s=i:s.items=i,w2menu.show(t,s)})},r.fn.w2color=function(i,s){return this.each((e,t)=>{t=w2color.show(t,i);"function"==typeof s&&t.select(s)})})}(window.jQuery),function(t,i){if("function"==typeof define&&define.amd)return define(()=>i);if("undefined"!=typeof exports){if("undefined"!=typeof module&&module.exports)return exports=module.exports=i;t=exports}t&&Object.keys(i).forEach(e=>{t[e]=i[e]})}(self,{w2ui:w2ui,w2utils:w2utils,query:query,w2locale:w2locale,w2event:w2event,w2base:w2base,w2popup:w2popup,w2alert:w2alert,w2confirm:w2confirm,w2prompt:w2prompt,Dialog:Dialog,w2tooltip:w2tooltip,w2menu:w2menu,w2color:w2color,w2date:w2date,Tooltip:Tooltip,w2toolbar:w2toolbar,w2sidebar:w2sidebar,w2tabs:w2tabs,w2layout:w2layout,w2grid:w2grid,w2form:w2form,w2field:w2field}); \ No newline at end of file diff --git a/src/rttester/AddLTLQueryDialog.html b/src/rttester/AddLTLQueryDialog.html deleted file mode 100644 index eb01c9e..0000000 --- a/src/rttester/AddLTLQueryDialog.html +++ /dev/null @@ -1,21 +0,0 @@ - - diff --git a/src/rttester/AddLTLQueryDialog.ts b/src/rttester/AddLTLQueryDialog.ts deleted file mode 100644 index 70f6e32..0000000 --- a/src/rttester/AddLTLQueryDialog.ts +++ /dev/null @@ -1,94 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - - -import fs = require("fs"); -import Path = require("path"); - -export function display(dir: string): void { - let hAddButton: HTMLButtonElement = document.getElementById("modalAdd"); - let hQueryName: HTMLInputElement = document.getElementById("QueryName"); - let hModalFail: HTMLLabelElement = document.getElementById("modalFail"); - - $('#modalDialog').on('shown.bs.modal', ()=> hQueryName.focus()); - hQueryName.addEventListener("input", () => { - if (hQueryName.value == "") { - hModalFail.innerText = ""; - hModalFail.style.display = "none"; - hAddButton.disabled = true; - } else { - let path = Path.join(dir, hQueryName.value); - fs.stat(path, (err: any, stats: fs.Stats) => { - if (!err) { - hModalFail.innerText = "Invalid name for LTL query."; - hAddButton.disabled = true; - hModalFail.style.display = "block"; - } else { - hModalFail.innerText = ""; - hAddButton.disabled = false; - hModalFail.style.display = "none"; - } - }); - } - }); - let create = () => { - let ltlDir = Path.join(dir, hQueryName.value); - let err = fs.mkdirSync(ltlDir); - if (err === undefined || null) { - hModalFail.innerText = "Error creating folder '" + ltlDir + "'."; - hModalFail.style.display = "block"; - return; - } - // Add empty LTL formula. - let jsonObject = { - BMCSteps: 50, - ltlFormula: "", - RequirementsToLink: [], - TracabilityLink: "verifies" - }; - let queryFileName = Path.join(ltlDir, "query.json"); - err = fs.writeFileSync(queryFileName, JSON.stringify(jsonObject, null, 4)); - if (err === undefined || null) { - hModalFail.innerText = "Error writing query file '" + queryFileName + "'."; - hModalFail.style.display = "block"; - return; - } - ($("#modalDialog")).modal("hide"); - }; - hAddButton.addEventListener("click", (event: Event) => create()); - hQueryName.addEventListener("keydown", (e) => { - // enter key - if (e.keyCode == 13 && !hAddButton.disabled) { - create(); - } - }); -} - diff --git a/src/rttester/CTAbstractions.ts b/src/rttester/CTAbstractions.ts deleted file mode 100644 index 7ec10f6..0000000 --- a/src/rttester/CTAbstractions.ts +++ /dev/null @@ -1,103 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - - -import fs = require("fs"); - -export class RangeBasedAbstraction { - lowerBound: Number; - upperBound: Number; - constructor() { - this.lowerBound = this.upperBound = 0; - } -} - -export class GradientBasedAbstraction { - gradient: Number; - timeFrame: Number; - constructor() { - this.gradient = 0; - this.timeFrame = 1000; - } -} - -export class SimulationBasedAbstraction { - fileName: string; - maxValueRange: Number; - constructor() { - this.fileName = null; - this.maxValueRange = 1; - } -} - -export class Abstraction { - selected: string; - rangeBased: RangeBasedAbstraction; - gradientBased: GradientBasedAbstraction; - simulationBased: SimulationBasedAbstraction; - constructor() { - this.selected = "none"; - this.rangeBased = new RangeBasedAbstraction(); - this.gradientBased = new GradientBasedAbstraction(); - this.rangeBased = new RangeBasedAbstraction(); - this.simulationBased = new SimulationBasedAbstraction(); - } -} - -export class Input { - name: string; - type: string; - abstraction: Abstraction; - constructor() { - this.abstraction = new Abstraction(); - } -} - -export interface Interface { - name: string; - inputs: Input[]; -} - -export interface Component { - name: string; - inputInterfaces: Interface[]; -} - -export class Abstractions { - components: Component[]; - static loadFromJSON(fileName: string): Abstractions { - let str = fs.readFileSync(fileName).toString(); - return JSON.parse(str); - } - static writeToJSON(a: Abstractions, fileName: string) { - fs.writeFileSync(fileName, JSON.stringify(a, null, 4), { encoding: "utf8" }); - } -} diff --git a/src/rttester/CTAbstractionsView.html b/src/rttester/CTAbstractionsView.html deleted file mode 100644 index 7b1b185..0000000 --- a/src/rttester/CTAbstractionsView.html +++ /dev/null @@ -1,94 +0,0 @@ - - - - - -
    -
    - -
    -
    Select Output:
    -
    -
    - - - - - -
    -
    - - diff --git a/src/rttester/CTAbstractionsView.ts b/src/rttester/CTAbstractionsView.ts deleted file mode 100644 index a35b3a5..0000000 --- a/src/rttester/CTAbstractionsView.ts +++ /dev/null @@ -1,240 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - - -import { ViewController } from "../iViewController"; -import { IntoCpsApp } from "../IntoCpsApp"; -import { Abstractions, Interface, Input, Component, Abstraction } from "../rttester/CTAbstractions"; -import { SignalMap, SignalMapEntry } from "./SignalMap"; -import Path = require("path"); -import { RTTester } from "../rttester/RTTester"; -const dialog = require("electron").remote.dialog; - - -let makeAbstractionTreeID = (function () { - let counter = 0; - return function () { return "AbstractionTreeId" + counter++; }; -})(); - -export class CTAbstractionsView extends ViewController { - - jsonFileName: string; - signalMap: SignalMap; - abstractions: Abstractions; - currentInput: Input; - - hSelectAbstractionDiv: HTMLDivElement; - hAbstractionSettings: HTMLDivElement; - - hLowerBound: HTMLInputElement; - hUpperBound: HTMLInputElement; - hGradient: HTMLInputElement; - hGradientTimeFrame: HTMLInputElement; - hSimulationFile: HTMLInputElement; - hSimulationMaxValueRange: HTMLInputElement; - hAbstractionSelection: HTMLInputElement; - - - constructor(protected viewDiv: HTMLDivElement, jsonFileName: string) { - super(viewDiv); - let self = this; - this.hSelectAbstractionDiv = document.getElementById("SelectAbstraction"); - this.hAbstractionSettings = document.getElementById("AbstractionSettings"); - this.hLowerBound = document.getElementById("lowerBound"); - this.hUpperBound = document.getElementById("upperBound"); - this.hGradient = document.getElementById("gradient"); - this.hGradientTimeFrame = document.getElementById("gradientTimeFrame"); - this.hSimulationFile = document.getElementById("simulationFile"); - this.hSimulationMaxValueRange = document.getElementById("simulationMaxValueRange"); - this.hAbstractionSelection = document.getElementById("AbstractionSelection"); - this.jsonFileName = jsonFileName; - IntoCpsApp.setTopName("Configure Abstractions"); - let signalMapFileName = Path.join(RTTester.getProjectOfFile(jsonFileName), "model", "signalmap.csv"); - SignalMap.loadFromFile(signalMapFileName, (signalMap) => { - this.signalMap = signalMap; - this.abstractions = Abstractions.loadFromJSON(jsonFileName); - this.displayAbstractions(); - // Actions for radio buttons: - let abstractionSelections = document.getElementsByName("AbstractionSelection"); - for (let i = 0; i < abstractionSelections.length; ++i) { - abstractionSelections[i].onclick = (ev: MouseEvent) => { - let selectionValue = abstractionSelections[i].value; - this.currentInput.abstraction.selected = selectionValue; - self.displaySelectedAbstraction(selectionValue); - }; - } - this.hLowerBound.onchange = (ev: Event) => { - self.currentInput.abstraction.rangeBased.lowerBound = +this.hLowerBound.value; - }; - this.hUpperBound.onchange = (ev: Event) => { - self.currentInput.abstraction.rangeBased.upperBound = +this.hUpperBound.value; - }; - this.hGradient.onchange = (ev: Event) => { - self.currentInput.abstraction.gradientBased.gradient = +this.hGradient.value; - }; - this.hGradientTimeFrame.onchange = (ev: Event) => { - self.currentInput.abstraction.gradientBased.timeFrame = +this.hGradientTimeFrame.value; - }; - this.hSimulationFile.onchange = (ev: Event) => { - self.currentInput.abstraction.simulationBased.fileName = this.hSimulationFile.value; - }; - this.hSimulationMaxValueRange.onchange = (ev: Event) => { - self.currentInput.abstraction.simulationBased.maxValueRange = +this.hSimulationMaxValueRange.value; - }; - document.getElementById("simulationFileBrowse").onclick = (ev: MouseEvent) => { - dialog.showOpenDialog({ - filters: [{ name: "Signal Log-Files (*.json)", extensions: ["json"] }] - }).then((res) => { - if(res.filePaths != undefined) { - self.currentInput.abstraction.simulationBased.fileName - = this.hSimulationFile.value - = res.filePaths[0]; - } - }).catch((error) => { - console.error(error); - return; - }); - }; - }); - } - - displaySelectedAbstraction(name: string) { - let abstractionSelections = document.getElementsByName("AbstractionSelection"); - // Hide deselected settings. - for (let i = 0; i < abstractionSelections.length; ++i) { - if (abstractionSelections[i].value != name) { - document.getElementById("AbstractionSettings_" + abstractionSelections[i].value).style.display = "none"; - } - } - // Show selected settings. - document.getElementById("AbstractionSettings_" + name).style.display = "block"; - // Show container if other than "No abstraction" has been selected - document.getElementById("AbstractionSettings").style.display = - name == "none" ? "none" : "block"; - } - - selectInput(o: Input) { - this.currentInput = o; - if (o == null) { - this.hSelectAbstractionDiv.style.display = "none"; - this.hAbstractionSettings.style.display = "none"; - } else { - if (!o.abstraction) { - o.abstraction = new Abstraction(); - o.abstraction.rangeBased.lowerBound = this.signalMap.entries[o.name].lowerBound; - o.abstraction.rangeBased.upperBound = this.signalMap.entries[o.name].upperBound; - } - this.hLowerBound.value = o.abstraction.rangeBased.lowerBound.toString(); - this.hUpperBound.value = o.abstraction.rangeBased.upperBound.toString(); - this.hGradient.value = o.abstraction.gradientBased.gradient.toString(); - this.hGradientTimeFrame.value = o.abstraction.gradientBased.timeFrame.toString(); - this.hSimulationFile.value = o.abstraction.simulationBased.fileName ? - o.abstraction.simulationBased.fileName.toString() : ""; - this.hSimulationMaxValueRange.value = o.abstraction.simulationBased.maxValueRange.toString(); - this.hSelectAbstractionDiv.style.display = "block"; - this.hAbstractionSettings.style.display = "none"; - let abstraction = o.abstraction.selected; - let h = document.getElementById("AbstractionSelection_" + abstraction); - h.checked = true; - this.hSelectAbstractionDiv.style.display = "block"; - this.displaySelectedAbstraction(abstraction); - } - } - - save() { - Abstractions.writeToJSON(this.abstractions, this.jsonFileName); - let abstractionSignalMap: SignalMap = jQuery.extend(true, {}, this.signalMap); - for (let c of this.abstractions.components) { - for (let i of c.inputInterfaces) { - for (let v of i.inputs) { - if (v.abstraction && v.abstraction.selected == "range") { - abstractionSignalMap.entries[v.name].lowerBound = +v.abstraction.rangeBased.lowerBound; - abstractionSignalMap.entries[v.name].upperBound = +v.abstraction.rangeBased.upperBound; - } - } - } - } - let abtstractionSignalMapFileName = Path.join(RTTester.getProjectOfFile(this.jsonFileName), - "model", "signalmap-with-interval-abstraction.csv"); - abstractionSignalMap.saveToFile(abtstractionSignalMapFileName, - (error) => { - if (error) console.log(error); - else { - let proj = RTTester.getProjectOfFile(abtstractionSignalMapFileName); - RTTester.queueEvent("Define-CT-Abstraction", proj); - } - }); - } - - displayAbstractions(): void { - let self = this; - - let createInputNode = (o: Input) => { - return { - id: makeAbstractionTreeID(), - text: o.name + ": " + o.type, - img: "icon-folder", - nodes: [], - input: o, - onClick: (event: any) => { self.selectInput(event.object.input); } - }; - }; - - let createInputInterfaceNode = (i: Interface) => { - return { - id: makeAbstractionTreeID(), - text: i.name, - img: "icon-page", - nodes: i.inputs.map((o: Input) => createInputNode(o)), - onClick: (event: any) => { self.selectInput(null); } - }; - }; - - let createComponentNode = (c: Component) => { - return { - id: makeAbstractionTreeID(), - text: c.name, - img: "icon-folder", - nodes: c.inputInterfaces.map((i: Interface) => createInputInterfaceNode(i)), - expanded: true, - onClick: (event: any) => { self.selectInput(null); } - }; - }; - - $("#AbstractionsTree").w2sidebar({ - name: makeAbstractionTreeID(), - menu: [], - nodes: this.abstractions.components.map((c: Component) => createComponentNode(c)) - }); - } - -} - diff --git a/src/rttester/CopyTestProcedureDialog.html b/src/rttester/CopyTestProcedureDialog.html deleted file mode 100644 index 006745e..0000000 --- a/src/rttester/CopyTestProcedureDialog.html +++ /dev/null @@ -1,21 +0,0 @@ - - diff --git a/src/rttester/CopyTestProcedureDialog.ts b/src/rttester/CopyTestProcedureDialog.ts deleted file mode 100644 index 12c7e51..0000000 --- a/src/rttester/CopyTestProcedureDialog.ts +++ /dev/null @@ -1,94 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - - -import fs = require("fs"); -import Path = require("path"); -import {RTTester} from "../rttester/RTTester"; - - -export function display(templateTP: string): void { - let hModalTitle: HTMLHeadingElement = document.getElementById("modalTitle"); - let hCopyButton: HTMLButtonElement = document.getElementById("modalCopy"); - let hTPName: HTMLInputElement = document.getElementById("TPName"); - let hModalFail: HTMLLabelElement = document.getElementById("modalFail"); - - let oldTP = RTTester.getRelativePathInProject(templateTP); - let oldTPName = oldTP.split(Path.sep)[1]; - let prjDir = RTTester.getProjectOfFile(templateTP); - hModalTitle.innerText = "Copy Test Procedure \"" + oldTPName + "\""; - - $('#modalDialog').on('shown.bs.modal', ()=> hTPName.focus()); - - hTPName.addEventListener("input", () => { - if (hTPName.value == "") { - hModalFail.innerText = ""; - hModalFail.style.display = "none"; - hCopyButton.disabled = true; - } else { - let path = Path.join(prjDir, "TestProcedures", hTPName.value); - fs.stat(path, (err: any, stats: fs.Stats) => { - if (!err) { - hModalFail.innerText = "Invalid name for Test Procedure."; - hCopyButton.disabled = true; - hModalFail.style.display = "block"; - } else { - hModalFail.innerText = ""; - hCopyButton.disabled = false; - hModalFail.style.display = "none"; - } - }); - } - }); - let copy = () => { - let newTP = Path.join("TestProcedures", hTPName.value); - let script = Path.join(RTTester.rttMBTInstallDir(), "bin", "rtt-mbt-copy-test.py"); - const spawn = require("child_process").spawn; - let args: string[] = [ - script, - oldTP, - newTP - ]; - let env: any = RTTester.genericCommandEnv(templateTP); - const p = spawn(RTTester.pythonExecutable(), args, { env: env }); - p.stdout.on("data", (d: any) => console.log(d.toString())); - p.stderr.on("data", (d: any) => console.log(d.toString())); - ($("#modalDialog")).modal("hide"); - }; - hCopyButton.addEventListener("click", (event: Event)=> copy()); - hTPName.addEventListener("keydown", (e) => { - // enter key - if (e.keyCode == 13 && !hCopyButton.disabled) { - copy(); - } - }); -} - diff --git a/src/rttester/CreateMCProject.html b/src/rttester/CreateMCProject.html deleted file mode 100644 index 0ddf15c..0000000 --- a/src/rttester/CreateMCProject.html +++ /dev/null @@ -1,30 +0,0 @@ - -
    -
    -

    Create Model Checking Project

    -
    -
    -
    -
    -
    - - -
    -
    - -
    - - - - -
    -
    -
    - -
    -
    -
    diff --git a/src/rttester/CreateMCProject.ts b/src/rttester/CreateMCProject.ts deleted file mode 100644 index d45e2ad..0000000 --- a/src/rttester/CreateMCProject.ts +++ /dev/null @@ -1,244 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - - -import { ViewController } from "../iViewController"; -import { IntoCpsApp } from "../IntoCpsApp"; -import Path = require("path"); -import fs = require("fs"); -import { RTTester } from "../rttester/RTTester"; -import { Abstractions, Interface, Input } from "./CTAbstractions"; -import { Utilities } from "../utilities"; -import { IntoCpsAppMenuHandler } from "../IntoCpsAppMenuHandler"; -import * as ModalCommand from "./GenericModalCommand"; - -const dialog = require("electron").remote.dialog; - - -export class CreateMCProjectController extends ViewController { - - menuHandler: IntoCpsAppMenuHandler; - directory: string; - hName: HTMLInputElement; - hPath: HTMLInputElement; - hBrowseButton: HTMLInputElement; - hCreateButton: HTMLButtonElement; - - constructor(protected viewDiv: HTMLDivElement, menuHandler: IntoCpsAppMenuHandler, directory: string) { - super(viewDiv); - this.menuHandler = menuHandler; - this.directory = directory; - IntoCpsApp.setTopName("RT-Tester Project"); - this.hName = document.getElementById("ProjectName"); - this.hPath = document.getElementById("XMIModelPathText"); - this.hBrowseButton = document.getElementById("browseButton"); - this.hCreateButton = document.getElementById("createButton"); - }; - - - xmiModelBrowser() { - dialog.showOpenDialog({ - filters: [{ name: "XMI-Files", extensions: ["xmi", "xml"] }] - }).then((res) => { - if(res.filePaths != undefined) { - this.hPath.value = res.filePaths[0]; - } - }).catch((error) => { - console.error(error); - return; - }); - } - - createDefaultAbstractionsPromise(c: ModalCommand.GenericModalCommand, xmiFileName: string, targetDir: string) { - return new Promise((resolve, reject) => { - let extractInterface = (onLoad: (interfaceJSON: string) => void) => { - let script: string = Path.join(RTTester.rttMBTInstallDir(), "bin", "rtt-mbt-into-extract-interface.py"); - const spawn = require("child_process").spawn; - let pythonPath = RTTester.pythonExecutable(); - let args: string[] = [ - script, - "--input", - xmiFileName - ]; - let env: any = process.env; - env["RTTDIR"] = RTTester.rttInstallDir(); - let stdout = ""; - const p = spawn(pythonPath, args, { env: env }); - p.stdout.on("data", (s: string) => { stdout += s; }); - p.stderr.on("data", c.appendLog.bind(c)); - p.on("close", (code: number) => { - if (code != 0) { - reject(); - } else { - try { - let obj = JSON.parse(stdout); - onLoad(obj); - resolve(); - } catch (e) { - c.appendLog("Problem when parsing interface description: " + e); - c.appendLog("Interface description was: " + stdout); - reject(); - } - } - }); - }; - let generateAbstractions = (interfaceJSON: any) => { - let createInputs = (inputs: any[]): Input[] => { - return inputs.reduce((oList: any[], o: any) => { - let name = o[0]; - let type = o[1]; - oList.push({ - name: name, - type: type, - }); - return oList; - }, []); - }; - let createInputInterfaces = (interfaces: any[]): Interface[] => { - return interfaces.reduce((iList: any[], i: any) => { - let name = i[0]; - let type = i[1]; - if (type == "input") { - let inputs = interfaceJSON["interfaces"][name][1]; - iList.push({ - name: name, - inputs: createInputs(inputs) - }); - } - return iList; - }, []); - }; - let createComponents = (): Abstractions => { - return { - components: Object.keys(interfaceJSON.components).map((compName: string) => { - return { - name: compName, - inputInterfaces: createInputInterfaces(interfaceJSON.components[compName]), - }; - }) - }; - }; - let abstractions = createComponents(); - Abstractions.writeToJSON(abstractions, Path.join(targetDir, "abstractions.json")); - }; - extractInterface(generateAbstractions); - }); - } - - createMCProject(c: ModalCommand.GenericModalCommand, xmiFileName: string, targetDir: string) { - return new Promise((resolve, reject) => { - let exe = RTTester.pythonExecutable(); - let script = Path.join(RTTester.rttMBTInstallDir(), "bin", "rtt-mbt-create-fmi2-project.py"); - const spawn = require("child_process").spawn; - let args: string[] = [ - script, - "--skip-rttui", - "--skip-configure", - "--skip-tests", - "--dir=" + targetDir, - "--template=MC", - xmiFileName - ]; - let env: any = process.env; - env["RTTDIR"] = RTTester.rttInstallDir(); - const p = spawn(exe, args, { env: env }); - p.stdout.on("data", c.appendLog.bind(c)); - p.stderr.on("data", c.appendLog.bind(c)); - p.on("exit", (code: number) => { - if (code != 0) { - reject(); - } else { - resolve(); - } - }); - }); - } - - createSignalMap(c: ModalCommand.GenericModalCommand, targetDir: string) { - return new Promise((resolve, reject) => { - let modelDir = Path.join(targetDir, "model"); - let exe = Path.join(RTTester.rttMBTInstallDir(), "bin", "sigmaptool"); - const spawn = require("child_process").spawn; - let args: string[] = [ - "-projectDb", "model_dump.db" - ]; - let env: any = process.env; - const p = spawn(exe, args, { cwd: modelDir }); - p.stdout.on("data", c.appendLog.bind(c)); - p.stderr.on("data", c.appendLog.bind(c)); - p.on("exit", (code: number) => { - if (code != 0) { - reject(); - } else { - Utilities.copyFile( - Path.join(modelDir, "signalmap.csv"), - Path.join(modelDir, "signalmap-with-interval-abstraction.csv"), - (error) => { - if (error) { - console.log(error); - reject(); - } else { - resolve(); - } - }); - } - }); - }); - } - - createProject(): void { - let self = this; - let xmiFileName = this.hPath.value; - let targetDir = Path.normalize(Path.join(this.directory, this.hName.value)); - let modelDetailsPath = Path.join(targetDir, "model", "model-details.html"); - let modelDetailsTitle = RTTester.getRelativePathInProject(modelDetailsPath); - - ModalCommand.load("Create Model Checking Project", - (c: ModalCommand.GenericModalCommand) => { - self.createMCProject(c, xmiFileName, targetDir).then( - () => self.createDefaultAbstractionsPromise(c, xmiFileName, targetDir).then( - () => self.createSignalMap(c, targetDir).then( - () => { - RTTester.queueEvent("Define-CT-Abstraction", targetDir); - c.displayTermination(true); - self.menuHandler.openHTMLInMainView(modelDetailsPath, modelDetailsTitle); - }, - () => c.displayTermination(false)), - () => c.displayTermination(false)), - () => c.displayTermination(false)).catch(err => console.error("Error in creating project: " + err)); - }); - } - - - - -} - diff --git a/src/rttester/CreateMCProject/AbstractionGradient.html b/src/rttester/CreateMCProject/AbstractionGradient.html deleted file mode 100644 index ee35247..0000000 --- a/src/rttester/CreateMCProject/AbstractionGradient.html +++ /dev/null @@ -1,21 +0,0 @@ - -
    - -
    -
    -
    -
    - - -
    -
    - - -
    -
    -
    -
    -
    diff --git a/src/rttester/CreateMCProject/AbstractionNone.html b/src/rttester/CreateMCProject/AbstractionNone.html deleted file mode 100644 index a418eb6..0000000 --- a/src/rttester/CreateMCProject/AbstractionNone.html +++ /dev/null @@ -1,7 +0,0 @@ - - diff --git a/src/rttester/CreateMCProject/AbstractionRange.html b/src/rttester/CreateMCProject/AbstractionRange.html deleted file mode 100644 index 981f943..0000000 --- a/src/rttester/CreateMCProject/AbstractionRange.html +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/src/rttester/CreateMCProject/AbstractionSimulation.html b/src/rttester/CreateMCProject/AbstractionSimulation.html deleted file mode 100644 index 2e2f89d..0000000 --- a/src/rttester/CreateMCProject/AbstractionSimulation.html +++ /dev/null @@ -1,24 +0,0 @@ - -
    - -
    -
    -
    -
    - -
    - - - - -
    -
    -
    -
    -
    -
    diff --git a/src/rttester/CreateMCProject/Component.html b/src/rttester/CreateMCProject/Component.html deleted file mode 100644 index d96b1dc..0000000 --- a/src/rttester/CreateMCProject/Component.html +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/src/rttester/CreateMCProject/Output.html b/src/rttester/CreateMCProject/Output.html deleted file mode 100644 index 966363d..0000000 --- a/src/rttester/CreateMCProject/Output.html +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/src/rttester/CreateTDGProject.html b/src/rttester/CreateTDGProject.html deleted file mode 100644 index 55414de..0000000 --- a/src/rttester/CreateTDGProject.html +++ /dev/null @@ -1,30 +0,0 @@ - -
    -
    -

    Create Test Data Generation Project

    -
    -
    -
    -
    -
    - - -
    -
    - -
    - - - - -
    -
    -
    - -
    -
    -
    diff --git a/src/rttester/CreateTDGProject.ts b/src/rttester/CreateTDGProject.ts deleted file mode 100644 index 92ea3fa..0000000 --- a/src/rttester/CreateTDGProject.ts +++ /dev/null @@ -1,94 +0,0 @@ -/* - * This file is part of the INTO-CPS toolchain. - * - * Copyright (c) 2017-CurrentYear, INTO-CPS Association, - * c/o Professor Peter Gorm Larsen, Department of Engineering - * Finlandsgade 22, 8200 Aarhus N. - * - * All rights reserved. - * - * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR - * THIS INTO-CPS ASSOCIATION PUBLIC LICENSE VERSION 1.0. - * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES - * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL - * VERSION 3, ACCORDING TO RECIPIENTS CHOICE. - * - * The INTO-CPS toolchain and the INTO-CPS Association Public License - * are obtained from the INTO-CPS Association, either from the above address, - * from the URLs: http://www.into-cps.org, and in the INTO-CPS toolchain distribution. - * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. - * - * This program is distributed WITHOUT ANY WARRANTY; without - * even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH IN THE - * BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF - * THE INTO-CPS ASSOCIATION. - * - * See the full INTO-CPS Association Public License conditions for more details. - * - * See the CONTRIBUTORS file for author and contributor information. - */ - - -import {ViewController} from "../iViewController"; -import {IntoCpsApp} from "../IntoCpsApp"; -import Path = require("path"); -import {RTTester} from "../rttester/RTTester"; -import * as RTesterModalCommandWindow from "./GenericModalCommand"; -import {IntoCpsAppMenuHandler} from "../IntoCpsAppMenuHandler"; - -const dialog = require("electron").remote.dialog; - -export class CreateTDGProjectController extends ViewController { - - menuHandler: IntoCpsAppMenuHandler; - directory: string; - - constructor(protected viewDiv: HTMLDivElement, menuHandler: IntoCpsAppMenuHandler, directory: string) { - super(viewDiv); - this.menuHandler = menuHandler; - this.directory = directory; - IntoCpsApp.setTopName("RT-Tester Project"); - }; - - xmiModelBrowser() { - dialog.showOpenDialog({ - filters: [{ name: "XMI-Files", extensions: ["xmi", "xml"] }] - }).then((res) => { - if(res.filePaths != undefined) { - let hText: HTMLInputElement = document.getElementById("XMIModelPathText"); - hText.value = res.filePaths[0]; - } - }).catch((error) => { - console.error(error); - return; - }); - } - - createProject(): void { - let self = this; - let xmiPath = (document.getElementById("XMIModelPathText")).value; - let projectName = (document.getElementById("ProjectName")).value; - let script = Path.join(RTTester.rttMBTInstallDir(), "bin", "rtt-mbt-create-fmi2-project.py"); - let targetDir = Path.normalize(Path.join(self.directory, projectName)); - let env: any = process.env; - let modelDetailsPath = Path.join(targetDir, "model", "model-details.html"); - let modelDetailsTitle = RTTester.getRelativePathInProject(modelDetailsPath); - env["RTTDIR"] = RTTester.rttInstallDir(); - let cmd = { - title: "Create Test Automation Project", - command: RTTester.pythonExecutable(), - arguments: [ - script, - "--dir=" + targetDir, - "--skip-rttui", - xmiPath - ], - options: { env: env }, - onSuccess: () => { self.menuHandler.openHTMLInMainView(modelDetailsPath, modelDetailsTitle) } - }; - RTesterModalCommandWindow.runCommand(cmd); - } - -} - diff --git a/src/rttester/GenericModalCommand.html b/src/rttester/GenericModalCommand.html deleted file mode 100644 index a444728..0000000 --- a/src/rttester/GenericModalCommand.html +++ /dev/null @@ -1,22 +0,0 @@ - -