diff --git a/Phraseanet-production-client/.babelrc b/Phraseanet-production-client/.babelrc
new file mode 100644
index 0000000000..a08058b18d
--- /dev/null
+++ b/Phraseanet-production-client/.babelrc
@@ -0,0 +1,19 @@
+{
+
+"ignore": [
+ "foo.js",
+ "bar/**/*.js"
+ ],
+ "presets": [
+ "es2015", "stage-0"
+ ],
+"env": {
+ "start": {
+ /* TODO: */
+ /* fill with hmr settings when there is a new release */
+ /* to play nice with babel 6*/
+ }
+ },
+/* Add plugins here**/
+"plugins": ["babel-plugin-syntax-jsx"]
+}
diff --git a/Phraseanet-production-client/.editorconfig b/Phraseanet-production-client/.editorconfig
new file mode 100644
index 0000000000..7b59292ea5
--- /dev/null
+++ b/Phraseanet-production-client/.editorconfig
@@ -0,0 +1,30 @@
+# http://editorconfig.org
+
+# A special property that should be specified at the top of the file outside of
+# any sections. Set to true to stop .editor config file search on current file
+root = true
+
+[*]
+# Indentation style
+# Possible values - tab, space
+indent_style = space
+
+# Indentation size in single-spaced characters
+# Possible values - an integer, tab
+indent_size = 4
+
+# Line ending file format
+# Possible values - lf, crlf, cr
+end_of_line = lf
+
+# File character encoding
+# Possible values - latin1, utf-8, utf-16be, utf-16le
+charset = utf-8
+
+# Denotes whether to trim whitespace at the end of lines
+# Possible values - true, false
+trim_trailing_whitespace = true
+
+# Denotes whether file should end with a newline
+# Possible values - true, false
+insert_final_newline = true
diff --git a/Phraseanet-production-client/.env b/Phraseanet-production-client/.env
new file mode 100644
index 0000000000..ffdc61ecef
--- /dev/null
+++ b/Phraseanet-production-client/.env
@@ -0,0 +1,3 @@
+NODE_PATH=./src
+NODE_ENV=development
+PORT=80
\ No newline at end of file
diff --git a/Phraseanet-production-client/.eslintignore b/Phraseanet-production-client/.eslintignore
new file mode 100644
index 0000000000..33d3d6a096
--- /dev/null
+++ b/Phraseanet-production-client/.eslintignore
@@ -0,0 +1,4 @@
+dist/*
+node_modules/*
+**/node_modules/*
+config/**
diff --git a/Phraseanet-production-client/.eslintrc b/Phraseanet-production-client/.eslintrc
new file mode 100644
index 0000000000..31bd0dcc1a
--- /dev/null
+++ b/Phraseanet-production-client/.eslintrc
@@ -0,0 +1,186 @@
+{
+ "root": true,
+ "parser": "babel-eslint",
+ "globals": {
+ "document": true,
+ "window": true,
+ "spy",
+ "mocha",
+ "stub",
+ "beforeEach",
+ "useFakeTimers": true,
+ "useFakeXMLHttpRequest": true,
+ "useFakeServer": true
+ },
+ "ecmaFeatures": {
+ "jsx": true,
+ "modules": true,
+ "es6": true
+ },
+ "env": {
+ "browser": true,
+ "es6": true,
+ "mocha": true,
+ "node": true
+
+ },
+ "rules": {
+ // /* airbnb javascript style guide rules */
+ // "strict": [2, "never"],
+ // // es6
+ // //"no-var": 2,
+ // // variables
+ //"no-shadow": 2,
+ "no-shadow-restricted-names": 2,
+ // "no-unused-vars": [2, {
+ // "vars": "all",
+ // "args": "none"
+ // }],
+ "no-undef": 2,
+ // "no-use-before-define": [2, "nofunc"],
+ // possible errors
+ "comma-dangle": 0,
+ //"no-cond-assign": [2, "always"],
+ "no-debugger": 1,
+ //"no-alert": 1,
+ "no-constant-condition": 1,
+ "no-dupe-keys": 2,
+ "no-duplicate-case": 2,
+ //"no-empty": 2,
+ "no-ex-assign": 2,
+ "no-extra-boolean-cast": 0,
+ "no-extra-semi": 2,
+ "no-func-assign": 2,
+ "no-inner-declarations": 2,
+ "no-invalid-regexp": 2,
+ "no-irregular-whitespace": 2,
+ "no-obj-calls": 2,
+ "no-sparse-arrays": 2,
+ "no-unreachable": 2,
+ "use-isnan": 2,
+ "block-scoped-var": 2,
+ // best practices
+ //"consistent-return": 2,
+ "curly": [2, "multi-line"],
+ "default-case": 2,
+ "dot-notation": [2, {
+ "allowKeywords": true
+ }],
+ "eqeqeq": 2,
+ //"guard-for-in": 2,
+ "no-caller": 2,
+ "no-eq-null": 2,
+ "no-eval": 2,
+ "no-extend-native": 2,
+ "no-extra-bind": 2,
+ "no-fallthrough": 0,
+ "no-floating-decimal": 2,
+ "no-implied-eval": 2,
+ "no-lone-blocks": 2,
+ //"no-loop-func": 2,
+ //"no-multi-str": 2,
+ "no-native-reassign": 2,
+ //"no-new": 2,
+ "no-new-func": 2,
+ // "no-new-wrappers": 2,
+ "no-octal": 2,
+ "no-octal-escape": 2,
+ // "no-param-reassign": [2, {
+ // "props": false
+ // }],
+ "no-proto": 2,
+ "no-redeclare": 2,
+ "no-return-assign": 2,
+ "no-script-url": 2,
+ "no-self-compare": 2,
+ "no-sequences": 2,
+ //"no-throw-literal": 2,
+ "no-with": 2,
+ "radix": 2,
+ // "vars-on-top": 2,
+ //"wrap-iife": [2, "any"],
+ "yoda": 2,
+ // style
+ "indent": [0, 0],
+ "brace-style": [2,
+ "1tbs", {
+ "allowSingleLine": true
+ }
+ ],
+ "quotes": [
+ 2, "single", "avoid-escape"
+ ],
+ // "camelcase": [2, {
+ // "properties": "never"
+ // }],
+ "comma-spacing": [2, {
+ "before": false,
+ "after": true
+ }],
+ "comma-style": [2, "last"],
+ "eol-last": 2,
+ "key-spacing": [2, {
+ "beforeColon": false,
+ "afterColon": true
+ }],
+ // "new-cap": [2, {
+ // "newIsCap": true
+ // }],
+ "no-multiple-empty-lines": [2, {
+ "max": 2
+ }],
+ //"no-nested-ternary": 2,
+ "no-new-object": 2,
+ "no-spaced-func": 2,
+ "no-trailing-spaces": 0,
+ //"no-extra-parens": 2,
+ "no-underscore-dangle": 0,
+ "one-var": [2, "never"],
+ "padded-blocks": 0,
+ "semi-spacing": [2, {
+ "before": false,
+ "after": true
+ }],
+ "keyword-spacing": 2,
+ "space-before-blocks": 2,
+ "space-infix-ops": 2,
+ //"spaced-comment": 2,
+
+ /* custom rules */
+ "no-console": 0,
+ "space-before-function-paren": [2, {
+ "named": "never",
+ "anonymous": "always"
+ }],
+ "func-names": 0,
+ //"consistent-this": [2, "this"],
+ "func-style": [0, "expression"],
+ //"max-nested-callbacks": [2, 3],
+ "new-parens": 2,
+ "no-array-constructor": 2,
+ "no-else-return": 0,
+ //"no-inline-comments": 2,
+ // "no-lonely-if": 2,
+ "no-mixed-spaces-and-tabs": 1,
+ "operator-assignment": 0,
+ "quote-props": [2, "as-needed"],
+ "sort-vars": [0, {
+ "ignoreCase": true
+ }],
+ "space-in-brackets": [0, "never", {
+ "arraysInArrays": false,
+ "arraysInObjects": false,
+ "singleValue": false,
+ "objectsInArrays": false,
+ "objectsInObjects": false,
+ "propertyName": false
+ }],
+ "space-in-parens": [2, "never"],
+ "space-unary-ops": [2, {
+ "words": true,
+ "nonwords": false
+ }],
+ "wrap-regex": 1
+ },
+ plugins: []
+}
diff --git a/Phraseanet-production-client/.gitignore b/Phraseanet-production-client/.gitignore
new file mode 100644
index 0000000000..7559373277
--- /dev/null
+++ b/Phraseanet-production-client/.gitignore
@@ -0,0 +1,8 @@
+*.log
+node_modules
+coverage
+npm-debug.log
+.DS_Store
+dist
+bower_components
+.idea
diff --git a/Phraseanet-production-client/.npmignore b/Phraseanet-production-client/.npmignore
new file mode 100644
index 0000000000..aa8e45f12b
--- /dev/null
+++ b/Phraseanet-production-client/.npmignore
@@ -0,0 +1 @@
+src/
\ No newline at end of file
diff --git a/Phraseanet-production-client/.travis.yml b/Phraseanet-production-client/.travis.yml
new file mode 100644
index 0000000000..c1b4054f55
--- /dev/null
+++ b/Phraseanet-production-client/.travis.yml
@@ -0,0 +1,26 @@
+language: node_js
+
+node_js:
+ - '13.13.0'
+
+# Use container-based Travis infrastructure.
+sudo: false
+
+cache:
+ directories:
+ - node_modules
+
+before_install:
+ - nvm install stable
+
+notifications:
+ email: true
+branches:
+ except:
+ - "/^v\\d+\\.\\d+\\.\\d+$/"
+
+after_script:
+ - npm run coveralls
+
+# Upload to coveralls, but don't _fail_ if coveralls is down.
+ - cat coverage/lcov.info | node_modules/.bin/coveralls || echo "Coveralls upload failed"
diff --git a/Phraseanet-production-client/CHANGELOG.md b/Phraseanet-production-client/CHANGELOG.md
new file mode 100644
index 0000000000..ecd95ea396
--- /dev/null
+++ b/Phraseanet-production-client/CHANGELOG.md
@@ -0,0 +1,5 @@
+# Changelog
+
+## 0.1.0
+
+- initial release
diff --git a/Phraseanet-production-client/LICENSE.md b/Phraseanet-production-client/LICENSE.md
new file mode 100644
index 0000000000..55cb5b0d48
--- /dev/null
+++ b/Phraseanet-production-client/LICENSE.md
@@ -0,0 +1,19 @@
+##The MIT License (MIT)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/Phraseanet-production-client/PULL_REQUEST_TEMPLATE.md b/Phraseanet-production-client/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000000..578a738748
--- /dev/null
+++ b/Phraseanet-production-client/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,15 @@
+## Changelog
+### Changed
+ - Breaking change
+
+### Fixes
+ - PHRAS-XXX: Short description of bug and fix
+ - Short description of bug and fix without issue/ticket
+
+### Adds
+ - PHRAS-XXX: Short feature description
+ - Short feature description without issue/ticket
+
+### Removes
+ - PHRAS-XXX: Short feature removal description
+ - Short feature removal description without issue/ticket
diff --git a/Phraseanet-production-client/README.md b/Phraseanet-production-client/README.md
new file mode 100644
index 0000000000..a144927b16
--- /dev/null
+++ b/Phraseanet-production-client/README.md
@@ -0,0 +1,49 @@
+# Phraseanet Production Client
+[](https://travis-ci.org/alchemy-fr/Phraseanet-production-client)
+[](https://david-dm.org/alchemy-fr/Phraseanet-production-client#info=devDependencies)
+[](https://david-dm.org/alchemy-fr/Phraseanet-production-client)
+[](https://coveralls.io/github/alchemy-fr/Phraseanet-production-client?branch=master)
+
+
+## Requirements
+
+Node `^5.0.0`.
+
+## Dev workflow
+
+ - Go to Phraseanet-production-client-folder
+ - make your modification
+ - Generate dist ```npm run dist```
+ - ```make install_asset``` to copy assets in www/assets folder
+ - If features is finished ```dist``` folder is to be commited
+
+## Available commands
+
+* `npm run production` - Build task that generate a minified script for production
+* `npm run clean` - Remove the `dist` folder and it's files
+* `npm run eslint:source` - Lint the source
+* `npm run eslint:common` - Lint the unit tests shared by Karma and Mocha
+* `npm run eslint:server` - Lint the unit tests for server
+* `npm run eslint:browser` - Lint the unit tests for browser
+* `npm run eslint:fix` - ESLint will try to fix as many issues as possible in your source files
+* `npm run clean` - Remove the coverage report and the *dist* folder
+* `npm run test` - Runs unit tests for both server and the browser
+* `npm run test:browser` - Runs the unit tests for browser / client
+* `npm run test:server` - Runs the unit tests on the server
+* `npm run watch:server` - Run all unit tests for server & watch files for changes
+* `npm run watch:browser` - Run all unit tests for browser & watch files for changes
+* `npm run karma:firefox` - Run all unit tests with Karma & Firefox
+* `npm run karma:chrome` - Run all unit tests with Karma & Chrome
+* `npm run karma:ie` - Run all unit tests with Karma & Internet Explorer
+* `npm run packages` - List installed packages
+* `npm run package:purge` - Remove all dependencies
+* `npm run package:reinstall` - Reinstall all dependencies
+* `npm run package:check` - shows a list over dependencies with a higher version number then the current one - if any
+* `npm run package:upgrade` - Automaticly upgrade all devDependencies & dependencies, and update package.json
+* `npm run package:dev` - Automaticly upgrade all devDependencies and update package.json
+* `npm run package:prod` - Automaticly upgrade all dependencies and update package.json
+* `npm run asset-server` - starts a asset server with hot module replacement (WDS) on port 8080
+
+## Credits
+
+based on [Trolly](https://github.com/Kflash/trolly) an es6 boilerplate by [KFlash](https://github.com/kflash)
diff --git a/Phraseanet-production-client/config/banner.js b/Phraseanet-production-client/config/banner.js
new file mode 100644
index 0000000000..b56cdba723
--- /dev/null
+++ b/Phraseanet-production-client/config/banner.js
@@ -0,0 +1,6 @@
+import pkg from '../package.json';
+
+export default [
+ pkg.name + '',
+ ' version ' + pkg.version
+];
\ No newline at end of file
diff --git a/Phraseanet-production-client/config/config.js b/Phraseanet-production-client/config/config.js
new file mode 100644
index 0000000000..74db9f9f0a
--- /dev/null
+++ b/Phraseanet-production-client/config/config.js
@@ -0,0 +1,15 @@
+const _root = __dirname + '/../';
+
+module.exports = {
+
+ // path helpers
+ _app: 'app',
+ minified: 'app.min.js',
+ dev: 'app.js',
+ eslintDir: _root + '.eslintrc',
+ distDir: _root + 'dist',
+ sourceDir: _root + 'src/',
+ testDir: _root + 'tests',
+ setupDir: _root + 'tests/setup/node.js',
+ karmaConf: _root + 'config/karma.conf.js'
+};
\ No newline at end of file
diff --git a/Phraseanet-production-client/config/environment.js b/Phraseanet-production-client/config/environment.js
new file mode 100644
index 0000000000..3dbe34748d
--- /dev/null
+++ b/Phraseanet-production-client/config/environment.js
@@ -0,0 +1,45 @@
+/* eslint-disable */
+import dotenv from 'dotenv';
+import path from 'path';
+import {
+ defaults
+}
+from 'lodash';
+
+dotenv.load({
+ silent: false,
+ path: path.resolve(__dirname, '../.env')
+});
+
+const {
+ ENVIRONMENT,
+ HOT_RELOAD,
+ NODE_ENV,
+ HOST,
+ PORT,
+ WEBPACK_DEV_SERVER_PORT
+} = defaults(process.env, {
+ ENVIRONMENT: 'development',
+ // localhost
+ HOST: 'localhost',
+ // port to use with the asset server
+ PORT: '8000'
+ }),
+ IS_PROD = () => {
+ return ( NODE_ENV === 'production' || ENVIRONMENT === 'prod' || ENVIRONMENT === 'production' );
+ },
+ IS_DEV = !IS_PROD,
+ ENVIRONMENT_NAME = IS_PROD ? 'production' : 'development';
+
+process.env.NODE_ENV = IS_PROD ? 'production' : 'development';
+
+export default {
+ IS_PROD,
+ IS_DEV,
+ ENVIRONMENT_NAME,
+ HOST,
+ PORT,
+ WEBPACK_DEV_SERVER_PORT,
+ HOT_RELOAD
+};
+/* eslint-enable */
\ No newline at end of file
diff --git a/Phraseanet-production-client/config/karma.conf.js b/Phraseanet-production-client/config/karma.conf.js
new file mode 100644
index 0000000000..16a5368eb3
--- /dev/null
+++ b/Phraseanet-production-client/config/karma.conf.js
@@ -0,0 +1,102 @@
+import webpackConfig from './webpack/webpack.karma.config';
+
+// Karma configuration here
+module.exports = function(config) {
+ config.set({
+ // list of files to exclude
+ exclude: [],
+ // list of files / patterns to load in the browser
+ files: [
+ './node_modules/jquery/dist/jquery.js',
+ './node_modules/babel-polyfill/dist/polyfill.js',
+ './node_modules/phantomjs-polyfill/bind-polyfill.js',
+ './test/**/*.browser.js'
+ ],
+ // frameworks to use
+ // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
+ frameworks: [
+ 'sinon-chai',
+ 'sinon',
+ 'chai',
+ 'mocha'
+ ], //use mocha and sinon-chai as framework
+
+ // preprocess matching files before serving them to the browser
+ // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
+ preprocessors: {
+ // 'src/**/*.js': ['coverage'],
+ 'test/**/*.browser.js': ['webpack', 'sourcemap']
+ },
+ // test results reporter to use
+ reporters: ['progress', 'mocha','coverage'],
+ coverageReporter: {
+ reporters: [{
+ type: 'text'
+ }, {
+ type: 'lcovonly',
+ subdir: '.'
+ }, {
+ type: 'html',
+ dir: 'coverage/'
+ }
+ ]
+ },
+ webpack: webpackConfig,
+ webpackMiddleware: {
+ noInfo: true
+ },
+ plugins: [
+ 'karma-sinon-chai',
+ 'karma-sinon',
+ 'karma-chai',
+ 'karma-webpack',
+ 'karma-mocha',
+ 'karma-mocha-reporter',
+ 'karma-phantomjs-launcher',
+ 'karma-chrome-launcher',
+ 'karma-firefox-launcher',
+ 'karma-ie-launcher',
+ 'karma-coverage',
+ 'karma-sourcemap-loader'
+ ],
+ // Start these browsers, currently available:
+ // - Chrome
+ // - ChromeCanary
+ // - Firefox
+ // - Opera (has to be installed with `npm install karma-opera-launcher`)
+ // - Safari (only Mac; has to be installed with `npm install karma-safari-launcher`)
+ // - PhantomJS
+ // - IE (only Windows; has to be installed with `npm install karma-ie-launcher`)
+ browsers: ['PhantomJS'],
+ browserDisconnectTimeout: 10000,
+ browserDisconnectTolerance: 2,
+ // concurrency level how many browser should be started simultaneously
+ concurrency: 4,
+ // If browser does not capture in given timeout [ms], kill it
+ captureTimeout: 100000,
+ browserNoActivityTimeout: 30000,
+ // enable / disable colors in the output (reporters and logs)
+ colors: true,
+ // level of logging
+ // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
+ logLevel: config.LOG_INFO,
+ // enable / disable watching file and executing tests whenever any file changes
+ autoWatch: false,
+ // Continuous Integration mode
+ // if true, Karma captures browsers, runs the tests and exits
+ singleRun: true,
+ });
+
+ if (process.env.TRAVIS) {
+
+ config.logLevel = config.LOG_DEBUG;
+ // Karma (with socket.io 1.x) buffers by 50 and 50 tests can take a long time on IEs;-)
+ config.browserNoActivityTimeout = 120000;
+
+ // Debug logging into a file, that we print out at the end of the build.
+ config.loggers.push({
+ type: 'file',
+ filename: 'logs/karma.log'
+ });
+ }
+};
\ No newline at end of file
diff --git a/Phraseanet-production-client/config/mocha.conf.js b/Phraseanet-production-client/config/mocha.conf.js
new file mode 100644
index 0000000000..210e123a36
--- /dev/null
+++ b/Phraseanet-production-client/config/mocha.conf.js
@@ -0,0 +1,15 @@
+/* eslint-disable */
+
+process.env.NODE_ENV = 'development';
+
+global.babel = require('babel-core/register');
+global.chai = require("chai");
+// global.$ = require("jquery");
+global.chaiAsPromised = require("chai-as-promised");
+global.chai.use(chaiAsPromised);
+global.expect = global.chai.expect;
+global.sinon = require('sinon');
+global.BROWSER = false;
+
+
+
diff --git a/Phraseanet-production-client/config/mocha.opts b/Phraseanet-production-client/config/mocha.opts
new file mode 100644
index 0000000000..e4aad73658
--- /dev/null
+++ b/Phraseanet-production-client/config/mocha.opts
@@ -0,0 +1,9 @@
+./test/**/*.spec.js
+
+--require ./config/mocha.conf.js
+--reporter spec
+--ui bdd
+--compilers js:babel-core/register
+--recursive
+--timeout 15000
+--bail
\ No newline at end of file
diff --git a/Phraseanet-production-client/config/webpack/webpack.development.config.js b/Phraseanet-production-client/config/webpack/webpack.development.config.js
new file mode 100644
index 0000000000..5ada9e23ea
--- /dev/null
+++ b/Phraseanet-production-client/config/webpack/webpack.development.config.js
@@ -0,0 +1,170 @@
+/**
+ * WEBPACK CONFIG
+ *
+ */
+/* eslint-disable no-var */
+require('babel-core/register');
+
+// Webpack config for development
+
+const webpack = require('webpack');
+const path = require('path');
+const pkg = require('../../package.json');
+// const banner = require('../banner');
+const WebpackNotifierPlugin = require('webpack-notifier');
+const config = require('../config');
+const ExtractTextPlugin = require('extract-text-webpack-plugin');
+
+// add loader for external stylesheets:
+var extractCSS = new ExtractTextPlugin({
+ filename: '[name].css',
+ allChunks: true
+});
+
+module.exports = {
+ // entry points
+ entry: {
+ production: config.sourceDir + 'prod/index.js',
+ lightbox: config.sourceDir + 'lightbox/index.js',
+ 'lightbox-mobile': config.sourceDir + 'lightbox-mobile/index.js',
+ permaview: config.sourceDir + 'permaview/index.js',
+ authenticate: [config.sourceDir + 'authenticate/index.js'],
+ account: [config.sourceDir + 'account/index.js'],
+ 'skin-000000': [config.sourceDir + 'skins/skin-000000.js'],
+ 'skin-959595': [config.sourceDir + 'skins/skin-959595.js'],
+ 'skin-FFFFFF': [config.sourceDir + 'skins/skin-FFFFFF.js']
+ },
+ cache: true,
+ watch: true,
+ devtool: 'inline-source-map',
+ output: {
+ path: config.distDir,
+ filename: '[name].js',
+ chunkFilename: 'lazy-[name].js',
+ libraryTarget: 'umd',
+ library: config._app,
+ publicPath: '/assets/production/'
+ },
+ module: {
+ rules: [
+ {
+ test: /\.js$/,
+ enforce: 'pre',
+ loader: 'eslint-loader',
+ exclude: /node_modules/,
+ include: path.join(__dirname, '../../src')
+ },
+ {
+ test: /\.js$/,
+ exclude: /node_modules/,
+ use: [{
+ loader: 'babel-loader',
+ options: { presets: ['es2015', 'stage-0'] },
+ }],
+ },
+ {
+ test: /\.(ttf|eot|woff|svg|png|jpg|gif)$/,
+ use: [
+ {
+ loader: 'url-loader',
+ options: {
+ limit: 10000,
+ name: '[name].[hash:6].[ext]',
+ }
+ }
+ ],
+ exclude: /node_modules/
+ },
+ {
+ test: /\.(ttf|eot|woff|svg|png|jpg|jpeg|gif)$/,
+ use: [
+ {
+ loader: 'file-loader',
+ options: {
+ name: '[name].[hash:6].[ext]'
+ }
+ }
+ ]
+ },
+ {
+ test: /\.css$/,
+ use: [
+ "style-loader",
+ "css-loader"
+ ]
+ },
+ {
+ test: /videojs-flash\.js$/,
+ loader: 'script-loader'
+ },
+ // exclude skins as inline-css in dev env
+ // {
+ // test: /\.scss$/,
+ // exclude: /src\/skins\//,
+ // loaders: ['style', 'css', 'resolve-url', 'sass?sourceMap']
+ // },
+ // only skins are extracted as external file in dev env:
+ // every css should be exported as file in dev env
+ {
+ test: /\.scss$/,
+ // exclude: /src\/(?!skins)/,
+ // include: [path.join(__dirname, '../../src'), path.join(__dirname, '../../stylesheets')],
+ use: ExtractTextPlugin.extract({
+ fallback: "style-loader",
+ use: [
+ 'css-loader',
+ 'resolve-url-loader',
+ { loader: 'sass-loader', options: { sourceMap: true } }
+ ],
+ publicPath: './'
+ })
+ },{
+ test: require.resolve('jquery-lazyload'),
+ use: "imports-loader?this=>window"
+ }, {
+ test: require.resolve('geonames-server-jquery-plugin/jquery.geonames'),
+ use: "imports-loader?this=>window"
+ }, {
+ test: require.resolve('bootstrap-multiselect'),
+ use: "imports-loader?this=>window"
+ }
+ ]
+ },
+ resolve: {
+ extensions: ['*', '.js', '.css', '.scss']
+ },
+ plugins: [
+ new WebpackNotifierPlugin({
+ alwaysNotify: true
+ }),
+ // new webpack.BannerPlugin(banner),
+ new webpack.ProvidePlugin({
+ "videojs": "video.js",
+ "window.videojs": "video.js"
+ }),
+ new webpack.DefinePlugin({
+ '__DEV__': true,
+ 'process.env.NODE_ENV': JSON.stringify('development'),
+ VERSION: JSON.stringify(pkg.version)
+ }),
+ new webpack.optimize.CommonsChunkPlugin({
+ name: 'commons',
+ chunks: ['production', 'lightbox'],
+ minChunks: 2
+ }),
+ new webpack.LoaderOptionsPlugin({
+ debug: true,
+ options: {
+ eslint: {
+ configFile: config.eslintDir
+ }
+ }
+ }),
+ extractCSS
+ // i18next
+ ],
+ externals: {
+ jquery: 'jQuery',
+ ui: 'jQuery.ui'
+ }
+};
diff --git a/Phraseanet-production-client/config/webpack/webpack.hot.assets.config.js b/Phraseanet-production-client/config/webpack/webpack.hot.assets.config.js
new file mode 100644
index 0000000000..ae0d247851
--- /dev/null
+++ b/Phraseanet-production-client/config/webpack/webpack.hot.assets.config.js
@@ -0,0 +1,37 @@
+/* eslint-disable no-var, strict */
+require('babel-core/register');
+
+const webpack = require('webpack');
+const WebpackDevServer = require('webpack-dev-server');
+const environment = require('../environment');
+const config = require('./webpack.development.config');
+
+config.devServer = {
+ hot: true
+}
+config.plugins = [
+ // Used for hot-reload
+ new webpack.HotModuleReplacementPlugin()
+];
+
+new WebpackDevServer(webpack(config), {
+ publicPath: 'http://localhost:8080/assets/',
+ // Configure hot replacement
+ // The rest is terminal configurations
+ quiet: false,
+ noInfo: true,
+ historyApiFallback: {
+ index: './templates/index.html'
+ },
+ stats: {
+ colors: true
+ }
+ // We fire up the development server and give notice in the terminal
+ // that we are starting the initial bundle
+}).listen(8080, environment.HOST, function(err, result) {
+
+ if (err) {
+ console.log(err);
+ }
+ console.log('The asset server is listening at localhost: 8080');
+});
\ No newline at end of file
diff --git a/Phraseanet-production-client/config/webpack/webpack.karma.config.js b/Phraseanet-production-client/config/webpack/webpack.karma.config.js
new file mode 100644
index 0000000000..73ad875c2b
--- /dev/null
+++ b/Phraseanet-production-client/config/webpack/webpack.karma.config.js
@@ -0,0 +1,100 @@
+// Webpack config for development
+import webpack from 'webpack';
+import path from 'path';
+import config from '../config';
+const ExtractTextPlugin = require('extract-text-webpack-plugin');
+
+// add loader for external stylesheets:
+var extractCSS = new ExtractTextPlugin({
+ filename: '[name].css',
+ allChunks: true
+});
+
+module.exports = {
+ cache: true,
+ devtool: 'inline-source-map',
+ output: {},
+ module: {
+ rules: [
+ {
+ test: /\.js$/,
+ enforce: 'post',
+ include: path.resolve('src/'),
+ use: 'istanbul-instrumenter-loader'
+ },
+ {
+ test: /\.css$/,
+ use: [
+ 'style-loader',
+ 'css-loader'
+ ]
+ },
+ {
+ test: /\.scss$/,
+ // exclude: /src\/(?!skins)/,
+ // include: [path.join(__dirname, '../../src'), path.join(__dirname, '../../stylesheets')],
+ use: ExtractTextPlugin.extract({
+ use: [
+ 'css-loader',
+ 'resolve-url-loader',
+ { loader: 'sass-loader', options: { sourceMap: true } }
+ ],
+ publicPath: './'
+ })
+ },
+ {
+ test: /\.(ttf|eot|woff|svg|png|jpg|gif)$/,
+ use: [
+ {
+ loader: 'url-loader',
+ options: {
+ limit: 10000,
+ name: '[name].[hash:6].[ext]',
+ }
+ }
+ ],
+ exclude: /node_modules/
+ },
+ {
+ test: /\.(ttf|eot|woff|svg|png|jpg|jpeg|gif)$/,
+ use: [
+ {
+ loader: 'file-loader',
+ options: {
+ name: '[name].[hash:6].[ext]'
+ }
+ }
+ ]
+ },
+ {
+ test: /\.js$/,
+ exclude: /node_modules/,
+ use: [{
+ loader: 'babel-loader',
+ options: { presets: ['es2015', 'stage-0'] },
+ }],
+ },
+ {
+ test: require.resolve('jquery-lazyload'),
+ use: "imports-loader?this=>window"
+ }
+ ]
+ },
+ resolve: {
+ extensions: ['*', '.js', '.css']
+ },
+ externals: {
+ jquery: 'jQuery',
+ ui: 'jQuery.ui'
+ },
+ plugins: [
+ new webpack.NormalModuleReplacementPlugin(/\.css$/, path.resolve('./src', './empty.js')),
+ new webpack.LoaderOptionsPlugin({
+ debug: true
+ }),
+ extractCSS
+ ],
+ devServer: {
+ hot: true
+ }
+};
diff --git a/Phraseanet-production-client/config/webpack/webpack.production.config.js b/Phraseanet-production-client/config/webpack/webpack.production.config.js
new file mode 100644
index 0000000000..800e057519
--- /dev/null
+++ b/Phraseanet-production-client/config/webpack/webpack.production.config.js
@@ -0,0 +1,131 @@
+require('babel-core/register');
+// Webpack config for creating the production bundle.
+
+const webpack = require('webpack');
+const ExtractTextPlugin = require('extract-text-webpack-plugin');
+const path = require('path');
+const WebpackNotifierPlugin = require('webpack-notifier');
+const PKG_LOCATION = require(path.join(__dirname, '../../package.json'));
+const config = require('../config');
+const webpackConfig = require('./webpack.development.config');
+// add loader for external stylesheets:
+var extractCSS = new ExtractTextPlugin({
+ filename: '[name].css',
+ allChunks: true
+});
+
+module.exports = Object.assign({}, webpackConfig, {
+
+ cache: false,
+ devtool: false,
+ watch: false,
+ module: {
+ rules: [
+ {
+ test: /\.js$/,
+ exclude: /node_modules/,
+ use: [{
+ loader: 'babel-loader',
+ options: { presets: ['es2015', 'stage-0'] },
+ }],
+ },
+ {
+ test: /\.(ttf|eot|woff|svg|png|jpg|gif)$/,
+ use: [
+ {
+ loader: 'url-loader',
+ options: {
+ limit: 10000,
+ name: '[name].[hash:6].[ext]',
+ }
+ }
+ ],
+ exclude: /node_modules/
+ },
+ {
+ test: /\.(ttf|eot|woff|svg|png|jpg|jpeg|gif)$/,
+ use: [
+ {
+ loader: 'file-loader',
+ options: {
+ name: '[name].[hash:6].[ext]'
+ }
+ }
+ ]
+ },
+ {
+ test: /\.css$/,
+ use: [
+ "style-loader",
+ "css-loader"
+ ]
+ },
+ {
+ test: /videojs-flash\.js$/,
+ loader: 'script-loader'
+ },
+ // exclude skins as inline-css in dev env
+ // {
+ // test: /\.scss$/,
+ // exclude: /src\/skins\//,
+ // loaders: ['style', 'css', 'resolve-url', 'sass']
+ // },
+ // only skins are extracted as external file in dev env:
+ {
+ test: /\.scss$/,
+ // exclude: /src\/(?!skins)/,
+ // include: [path.join(__dirname, '../../src'), path.join(__dirname, '../../stylesheets')],
+ use: ExtractTextPlugin.extract({
+ use: [
+ 'css-loader',
+ 'resolve-url-loader',
+ { loader: 'sass-loader', options: { sourceMap: true } }
+ ],
+ publicPath: './'
+ })
+ },
+ {
+ test: require.resolve('jquery-lazyload'),
+ use: "imports-loader?this=>window"
+ }, {
+ test: require.resolve('geonames-server-jquery-plugin/jquery.geonames'),
+ use: "imports-loader?this=>window"
+ }, {
+ test: require.resolve('bootstrap-multiselect'),
+ use: "imports-loader?this=>window"
+ }
+ ]
+ },
+ plugins: [
+ new webpack.ProvidePlugin({
+ $: "jquery",
+ jQuery: "jquery",
+ "videojs": "video.js",
+ "window.videojs": "video.js"
+ }),
+ // Notifier
+ new WebpackNotifierPlugin({
+ title: PKG_LOCATION.name,
+ alwaysNotify: true
+ }),
+ // optimizations
+ new webpack.NoEmitOnErrorsPlugin(),
+ new webpack.DefinePlugin({
+ '__DEV__': false,
+ 'process.env.NODE_ENV': JSON.stringify('production'),
+ VERSION: JSON.stringify(PKG_LOCATION.version)
+ }),
+ new webpack.optimize.CommonsChunkPlugin({
+ name: 'commons',
+ chunks: ['production', 'lightbox'],
+ minChunks: 2
+ }),
+ new webpack.LoaderOptionsPlugin({
+ debug: true
+ }),
+ extractCSS
+ ],
+ devServer: {
+ hot: true
+ }
+});
diff --git a/Phraseanet-production-client/config/webpack/webpack.production.minified.config.js b/Phraseanet-production-client/config/webpack/webpack.production.minified.config.js
new file mode 100644
index 0000000000..c485ef92d8
--- /dev/null
+++ b/Phraseanet-production-client/config/webpack/webpack.production.minified.config.js
@@ -0,0 +1,58 @@
+require('babel-core/register');
+
+// Webpack config for creating the minified production bundle.
+
+const webpack = require('webpack');
+const ExtractTextPlugin = require('extract-text-webpack-plugin');
+const path = require('path');
+const WebpackNotifierPlugin = require('webpack-notifier');
+const PKG_LOCATION = require(path.join(__dirname, '../../package.json'));
+const config = require('../config');
+const webpackConfig = require('./webpack.production.config')
+const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
+
+var extractCSS = new ExtractTextPlugin({
+ filename: '[name].min.css',
+ allChunks: true
+});
+
+module.exports = Object.assign({}, webpackConfig, {
+ output: {
+ path: config.distDir,
+ filename: '[name].min.js',
+ chunkFilename: 'lazy-[name].min.js',
+ libraryTarget: 'umd',
+ library: config._app,
+ publicPath: '/assets/production/'
+ },
+ plugins: [
+ new webpack.ProvidePlugin({
+ $: "jquery",
+ jQuery: "jquery",
+ "videojs": "video.js",
+ "window.videojs": "video.js"
+ }),
+ // Notifier
+ new WebpackNotifierPlugin({
+ title: PKG_LOCATION.name,
+ alwaysNotify: true
+ }),
+ // optimizations
+ new webpack.NoEmitOnErrorsPlugin(),
+ new webpack.DefinePlugin({
+ '__DEV__': false,
+ 'process.env.NODE_ENV': JSON.stringify('production'),
+ VERSION: JSON.stringify(PKG_LOCATION.version)
+ }),
+ new webpack.optimize.CommonsChunkPlugin({
+ name: 'commons',
+ chunks: ['production', 'lightbox'],
+ minChunks: 2
+ }),
+ extractCSS,
+ new OptimizeCssAssetsPlugin({
+ assetNameRegExp: /\.min\.css$/,
+ cssProcessorOptions: { discardComments: { removeAll: true }, zindex: false }
+ })
+ ]
+});
diff --git a/Phraseanet-production-client/karma.conf.js b/Phraseanet-production-client/karma.conf.js
new file mode 100644
index 0000000000..23251648a3
--- /dev/null
+++ b/Phraseanet-production-client/karma.conf.js
@@ -0,0 +1,2 @@
+require('babel-core/register');
+module.exports = require('./config/karma.conf');
\ No newline at end of file
diff --git a/Phraseanet-production-client/logs/.gitignore b/Phraseanet-production-client/logs/.gitignore
new file mode 100644
index 0000000000..c96a04f008
--- /dev/null
+++ b/Phraseanet-production-client/logs/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
\ No newline at end of file
diff --git a/Phraseanet-production-client/package-lock.json b/Phraseanet-production-client/package-lock.json
new file mode 100644
index 0000000000..f5cebe09f4
--- /dev/null
+++ b/Phraseanet-production-client/package-lock.json
@@ -0,0 +1,19053 @@
+{
+ "name": "phraseanet-production-client",
+ "version": "0.34.272-d",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "@babel/runtime": {
+ "version": "7.4.5",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.4.5.tgz",
+ "integrity": "sha512-TuI4qpWZP6lGOGIuGWtp9sPluqYICmbk8T/1vpSysqJxRPkudh/ofFWyqdcMsDf2s7KvDL4/YHgKyvcS3g9CJQ==",
+ "requires": {
+ "regenerator-runtime": "^0.13.2"
+ },
+ "dependencies": {
+ "regenerator-runtime": {
+ "version": "0.13.2",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz",
+ "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA=="
+ }
+ }
+ },
+ "@mapbox/geojson-area": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/@mapbox/geojson-area/-/geojson-area-0.2.2.tgz",
+ "integrity": "sha1-GNeBSqNr8j+7zDefjiaiKSfevxA=",
+ "requires": {
+ "wgs84": "0.0.0"
+ }
+ },
+ "@mapbox/geojson-rewind": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/@mapbox/geojson-rewind/-/geojson-rewind-0.5.0.tgz",
+ "integrity": "sha512-73l/qJQgj/T/zO1JXVfuVvvKDgikD/7D/rHAD28S9BG1OTstgmftrmqfCx4U+zQAmtsB6HcDA3a7ymdnJZAQgg==",
+ "requires": {
+ "concat-stream": "~2.0.0",
+ "minimist": "^1.2.5"
+ },
+ "dependencies": {
+ "concat-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz",
+ "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==",
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^3.0.2",
+ "typedarray": "^0.0.6"
+ }
+ },
+ "minimist": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
+ },
+ "readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ }
+ }
+ },
+ "@mapbox/geojson-types": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@mapbox/geojson-types/-/geojson-types-1.0.2.tgz",
+ "integrity": "sha512-e9EBqHHv3EORHrSfbR9DqecPNn+AmuAoQxV6aL8Xu30bJMJR1o8PZLZzpk1Wq7/NfCbuhmakHTPYRhoqLsXRnw=="
+ },
+ "@mapbox/gl-matrix": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/@mapbox/gl-matrix/-/gl-matrix-0.0.1.tgz",
+ "integrity": "sha1-5RJqq01kw2uBx6l9CuDd3eV3PSs="
+ },
+ "@mapbox/jsonlint-lines-primitives": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz",
+ "integrity": "sha1-zlblOfg1UrWNENZy6k1vya3HsjQ="
+ },
+ "@mapbox/mapbox-gl-language": {
+ "version": "0.9.2",
+ "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-language/-/mapbox-gl-language-0.9.2.tgz",
+ "integrity": "sha1-0Cb3GRDwkTlZ58BbCRH4zv4KbJ4="
+ },
+ "@mapbox/mapbox-gl-supported": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-1.4.0.tgz",
+ "integrity": "sha512-ZD0Io4XK+/vU/4zpANjOtdWfVszAgnaMPsGR6LKsWh4kLIEv9qoobTVmJPPuwuM+ZI2b3BlZ6DYw1XHVmv6YTA=="
+ },
+ "@mapbox/point-geometry": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz",
+ "integrity": "sha1-ioP5M1x4YO/6Lu7KJUMyqgru2PI="
+ },
+ "@mapbox/shelf-pack": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/@mapbox/shelf-pack/-/shelf-pack-3.2.0.tgz",
+ "integrity": "sha512-dyQxe6ukILV6qaEvxoKCIwhblgRjYp1ZGlClo4xvfbmxzFO5LYu7Tnrg2AZrRgN7VsSragsGcNjzUe9kCdKHYQ=="
+ },
+ "@mapbox/tiny-sdf": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-1.1.0.tgz",
+ "integrity": "sha512-dnhyk8X2BkDRWImgHILYAGgo+kuciNYX30CUKj/Qd5eNjh54OWM/mdOS/PWsPeN+3abtN+QDGYM4G220ynVJKA=="
+ },
+ "@mapbox/unitbezier": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-0.0.0.tgz",
+ "integrity": "sha1-FWUb1VOme4WB+zmIEMmK2Go0Uk4="
+ },
+ "@mapbox/vector-tile": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/@mapbox/vector-tile/-/vector-tile-1.3.1.tgz",
+ "integrity": "sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw==",
+ "requires": {
+ "@mapbox/point-geometry": "~0.1.0"
+ }
+ },
+ "@mapbox/whoots-js": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz",
+ "integrity": "sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q=="
+ },
+ "@turf/along": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/along/-/along-5.1.5.tgz",
+ "integrity": "sha1-YdbmplhKzdq1asVYTge/jL5fi+s=",
+ "requires": {
+ "@turf/bearing": "^5.1.5",
+ "@turf/destination": "^5.1.5",
+ "@turf/distance": "^5.1.5",
+ "@turf/helpers": "^5.1.5"
+ }
+ },
+ "@turf/area": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/area/-/area-5.1.5.tgz",
+ "integrity": "sha1-79iZv9Jgzb0VQbKjwVX4pdLu+h0=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/meta": "^5.1.5"
+ }
+ },
+ "@turf/bbox": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/bbox/-/bbox-5.1.5.tgz",
+ "integrity": "sha1-MFHfUUrUxQ9KT5uKLRX9i2hA7aM=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/meta": "^5.1.5"
+ }
+ },
+ "@turf/bbox-clip": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/bbox-clip/-/bbox-clip-5.1.5.tgz",
+ "integrity": "sha1-M2S1Mo3/nzz0HZ4C7a/zdNFQzIQ=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5",
+ "lineclip": "^1.1.5"
+ }
+ },
+ "@turf/bbox-polygon": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/bbox-polygon/-/bbox-polygon-5.1.5.tgz",
+ "integrity": "sha1-auuk7VHYXSluD3w4uIwznwHu4CQ=",
+ "requires": {
+ "@turf/helpers": "^5.1.5"
+ }
+ },
+ "@turf/bearing": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/bearing/-/bearing-5.1.5.tgz",
+ "integrity": "sha1-egt5ATbE70eX8CRjBdRcvi0ns/c=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5"
+ }
+ },
+ "@turf/bezier-spline": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/bezier-spline/-/bezier-spline-5.1.5.tgz",
+ "integrity": "sha1-WaJ7ul17l+8Vqz/VpA+9I4cEm8o=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5"
+ }
+ },
+ "@turf/boolean-clockwise": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/boolean-clockwise/-/boolean-clockwise-5.1.5.tgz",
+ "integrity": "sha1-MwK32sYsXikaB4nimvcoM4f6nes=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5"
+ }
+ },
+ "@turf/boolean-contains": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/boolean-contains/-/boolean-contains-5.1.5.tgz",
+ "integrity": "sha1-WW1jruY2961T7pn5/yTJaZSg7xQ=",
+ "requires": {
+ "@turf/bbox": "^5.1.5",
+ "@turf/boolean-point-in-polygon": "^5.1.5",
+ "@turf/boolean-point-on-line": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5"
+ }
+ },
+ "@turf/boolean-crosses": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/boolean-crosses/-/boolean-crosses-5.1.5.tgz",
+ "integrity": "sha1-Ab+uollvFk3kpNMlCU3HwlXHFdY=",
+ "requires": {
+ "@turf/boolean-point-in-polygon": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5",
+ "@turf/line-intersect": "^5.1.5",
+ "@turf/polygon-to-line": "^5.1.5"
+ }
+ },
+ "@turf/boolean-disjoint": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/@turf/boolean-disjoint/-/boolean-disjoint-5.1.6.tgz",
+ "integrity": "sha512-KHvUS6SBNYHBCLIJEJrg04pF5Oy+Fqn8V5G9U+9pti5vI9tyX7Ln2g7RSB7iJ1Cxsz8QAi6OukhXjEF2/8ZpGg==",
+ "requires": {
+ "@turf/boolean-point-in-polygon": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/line-intersect": "^5.1.5",
+ "@turf/meta": "^5.1.5",
+ "@turf/polygon-to-line": "^5.1.5"
+ }
+ },
+ "@turf/boolean-equal": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/boolean-equal/-/boolean-equal-5.1.5.tgz",
+ "integrity": "sha1-Kfj21gu4RQff12WzIlTbjnLJOKQ=",
+ "requires": {
+ "@turf/clean-coords": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5",
+ "geojson-equality": "0.1.6"
+ }
+ },
+ "@turf/boolean-overlap": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/boolean-overlap/-/boolean-overlap-5.1.5.tgz",
+ "integrity": "sha1-DU5kxSx3CijpPZ7834qLg3OsznU=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5",
+ "@turf/line-intersect": "^5.1.5",
+ "@turf/line-overlap": "^5.1.5",
+ "@turf/meta": "^5.1.5",
+ "geojson-equality": "0.1.6"
+ }
+ },
+ "@turf/boolean-parallel": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/boolean-parallel/-/boolean-parallel-5.1.5.tgz",
+ "integrity": "sha1-c5NYR16ltlx+GCejw+DopofTqF0=",
+ "requires": {
+ "@turf/clean-coords": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/line-segment": "^5.1.5",
+ "@turf/rhumb-bearing": "^5.1.5"
+ }
+ },
+ "@turf/boolean-point-in-polygon": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/boolean-point-in-polygon/-/boolean-point-in-polygon-5.1.5.tgz",
+ "integrity": "sha1-8BzBlNHgMKVIv9qYHLpDz9YpQbc=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5"
+ }
+ },
+ "@turf/boolean-point-on-line": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/boolean-point-on-line/-/boolean-point-on-line-5.1.5.tgz",
+ "integrity": "sha1-9jPF/4Aq0ku48Vja269v9KAj3Xs=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5"
+ }
+ },
+ "@turf/boolean-within": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/boolean-within/-/boolean-within-5.1.5.tgz",
+ "integrity": "sha1-RxBdVtB1Kp0Pv81Dw2pfkUnchpc=",
+ "requires": {
+ "@turf/bbox": "^5.1.5",
+ "@turf/boolean-point-in-polygon": "^5.1.5",
+ "@turf/boolean-point-on-line": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5"
+ }
+ },
+ "@turf/buffer": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/buffer/-/buffer-5.1.5.tgz",
+ "integrity": "sha1-hByWJ8+5dLEirE4alW8EZrwCMcQ=",
+ "requires": {
+ "@turf/bbox": "^5.1.5",
+ "@turf/center": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/meta": "^5.1.5",
+ "@turf/projection": "^5.1.5",
+ "d3-geo": "1.7.1",
+ "turf-jsts": "*"
+ }
+ },
+ "@turf/center": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/center/-/center-5.1.5.tgz",
+ "integrity": "sha1-RKss2VT2PA03dX9xWKmcPvURS4A=",
+ "requires": {
+ "@turf/bbox": "^5.1.5",
+ "@turf/helpers": "^5.1.5"
+ }
+ },
+ "@turf/center-mean": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/center-mean/-/center-mean-5.1.5.tgz",
+ "integrity": "sha1-jI6YdTkeXwnw5uePXWYbiLIQigo=",
+ "requires": {
+ "@turf/bbox": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/meta": "^5.1.5"
+ }
+ },
+ "@turf/center-median": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/center-median/-/center-median-5.1.5.tgz",
+ "integrity": "sha1-u0Yb/noqSGAdikcnaFcYcjoUqHI=",
+ "requires": {
+ "@turf/center-mean": "^5.1.5",
+ "@turf/centroid": "^5.1.5",
+ "@turf/distance": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/meta": "^5.1.5"
+ }
+ },
+ "@turf/center-of-mass": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/center-of-mass/-/center-of-mass-5.1.5.tgz",
+ "integrity": "sha1-TTvXnYhJjbq4Mk1PafAyL2Uguco=",
+ "requires": {
+ "@turf/centroid": "^5.1.5",
+ "@turf/convex": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5",
+ "@turf/meta": "^5.1.5"
+ }
+ },
+ "@turf/centroid": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/centroid/-/centroid-5.1.5.tgz",
+ "integrity": "sha1-d4radCFjNQIa2P0OemWoNJ1Tx2k=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/meta": "^5.1.5"
+ }
+ },
+ "@turf/circle": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/circle/-/circle-5.1.5.tgz",
+ "integrity": "sha1-mxV3g1UIq1L7HBCypQZcuiuHtqU=",
+ "requires": {
+ "@turf/destination": "^5.1.5",
+ "@turf/helpers": "^5.1.5"
+ }
+ },
+ "@turf/clean-coords": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/clean-coords/-/clean-coords-5.1.5.tgz",
+ "integrity": "sha1-EoAKmKeMmkUqcuxChJPEOs8q2h8=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5"
+ }
+ },
+ "@turf/clone": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/clone/-/clone-5.1.5.tgz",
+ "integrity": "sha1-JT6NNUdxgZduM636tQoPAqfw42c=",
+ "requires": {
+ "@turf/helpers": "^5.1.5"
+ }
+ },
+ "@turf/clusters": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/clusters/-/clusters-5.1.5.tgz",
+ "integrity": "sha1-ZzpeXxsZycq6vFfJCO6t1oIiTdQ=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/meta": "^5.1.5"
+ }
+ },
+ "@turf/clusters-dbscan": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/clusters-dbscan/-/clusters-dbscan-5.1.5.tgz",
+ "integrity": "sha1-V4H7TmVsdHoLjpk333MYHAMJ4m8=",
+ "requires": {
+ "@turf/clone": "^5.1.5",
+ "@turf/distance": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5",
+ "@turf/meta": "^5.1.5",
+ "density-clustering": "1.3.0"
+ }
+ },
+ "@turf/clusters-kmeans": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/clusters-kmeans/-/clusters-kmeans-5.1.5.tgz",
+ "integrity": "sha1-/W3+qLEzuovcI3CsPKzuFYejAvE=",
+ "requires": {
+ "@turf/clone": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5",
+ "@turf/meta": "^5.1.5",
+ "skmeans": "0.9.7"
+ }
+ },
+ "@turf/collect": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/collect/-/collect-5.1.5.tgz",
+ "integrity": "sha1-/pjJqMIY7PJP/DPXApUXt8GbKj4=",
+ "requires": {
+ "@turf/bbox": "^5.1.5",
+ "@turf/boolean-point-in-polygon": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "rbush": "^2.0.1"
+ }
+ },
+ "@turf/combine": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/combine/-/combine-5.1.5.tgz",
+ "integrity": "sha1-uxS976VVBDVxlfwaEkzX1TqMiQU=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/meta": "^5.1.5"
+ }
+ },
+ "@turf/concave": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/concave/-/concave-5.1.5.tgz",
+ "integrity": "sha1-I7uqw4fQNLlldKG9cNBZI3qdIRA=",
+ "requires": {
+ "@turf/clone": "^5.1.5",
+ "@turf/distance": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5",
+ "@turf/meta": "^5.1.5",
+ "@turf/tin": "^5.1.5",
+ "topojson-client": "3.x",
+ "topojson-server": "3.x"
+ }
+ },
+ "@turf/convex": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/convex/-/convex-5.1.5.tgz",
+ "integrity": "sha1-Dfk3fdACIWzpghsH9wXgN9rj4B0=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/meta": "^5.1.5",
+ "concaveman": "*"
+ }
+ },
+ "@turf/destination": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/destination/-/destination-5.1.5.tgz",
+ "integrity": "sha1-7TU4G9zoO73cvQei4rzivd/7zCY=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5"
+ }
+ },
+ "@turf/difference": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/difference/-/difference-5.1.5.tgz",
+ "integrity": "sha1-ok1pCnvKgD8QkKnuO52Qb8Q3H0I=",
+ "requires": {
+ "@turf/area": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5",
+ "@turf/meta": "^5.1.5",
+ "turf-jsts": "*"
+ }
+ },
+ "@turf/dissolve": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/dissolve/-/dissolve-5.1.5.tgz",
+ "integrity": "sha1-LPEzqQIdIWODHD16lY1lB/nYGTg=",
+ "requires": {
+ "@turf/boolean-overlap": "^5.1.5",
+ "@turf/clone": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5",
+ "@turf/line-intersect": "^5.1.5",
+ "@turf/meta": "^5.1.5",
+ "@turf/union": "^5.1.5",
+ "geojson-rbush": "2.1.0",
+ "get-closest": "*"
+ }
+ },
+ "@turf/distance": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/distance/-/distance-5.1.5.tgz",
+ "integrity": "sha1-Oc8YIEu/h1h9cH5gmmARiQkVZAk=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5"
+ }
+ },
+ "@turf/ellipse": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/ellipse/-/ellipse-5.1.5.tgz",
+ "integrity": "sha1-1XyrhTmFkgzeYCKKeNgEWAJcVL4=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5",
+ "@turf/rhumb-destination": "^5.1.5",
+ "@turf/transform-rotate": "^5.1.5"
+ }
+ },
+ "@turf/envelope": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/envelope/-/envelope-5.1.5.tgz",
+ "integrity": "sha1-UBMwnFP91D369LWIplw/7X28EIo=",
+ "requires": {
+ "@turf/bbox": "^5.1.5",
+ "@turf/bbox-polygon": "^5.1.5",
+ "@turf/helpers": "^5.1.5"
+ }
+ },
+ "@turf/explode": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/explode/-/explode-5.1.5.tgz",
+ "integrity": "sha1-sSsvd0AEobSPYrqVsgocZVo94Rg=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/meta": "^5.1.5"
+ }
+ },
+ "@turf/flatten": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/flatten/-/flatten-5.1.5.tgz",
+ "integrity": "sha1-2iknBnEz7WFpsLnWB7khVoiqE1g=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/meta": "^5.1.5"
+ }
+ },
+ "@turf/flip": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/flip/-/flip-5.1.5.tgz",
+ "integrity": "sha1-Q29kOnIvDKU7n85jjkaT2zYIpoo=",
+ "requires": {
+ "@turf/clone": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/meta": "^5.1.5"
+ }
+ },
+ "@turf/great-circle": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/great-circle/-/great-circle-5.1.5.tgz",
+ "integrity": "sha1-3r+2cc5HVQnLY3MBwV/PzPo1mpM=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5"
+ }
+ },
+ "@turf/helpers": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/helpers/-/helpers-5.1.5.tgz",
+ "integrity": "sha1-FTQFInq5M9AEpbuWQantmZ/L4M8="
+ },
+ "@turf/hex-grid": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/hex-grid/-/hex-grid-5.1.5.tgz",
+ "integrity": "sha1-m3ul/s9QUfHoWJL3E/zlxVBQKmo=",
+ "requires": {
+ "@turf/distance": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/intersect": "^5.1.5",
+ "@turf/invariant": "^5.1.5"
+ }
+ },
+ "@turf/interpolate": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/interpolate/-/interpolate-5.1.5.tgz",
+ "integrity": "sha1-DxLwq3VtbdEK+ykMpuh3ve8BPqo=",
+ "requires": {
+ "@turf/bbox": "^5.1.5",
+ "@turf/centroid": "^5.1.5",
+ "@turf/clone": "^5.1.5",
+ "@turf/distance": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/hex-grid": "^5.1.5",
+ "@turf/invariant": "^5.1.5",
+ "@turf/meta": "^5.1.5",
+ "@turf/point-grid": "^5.1.5",
+ "@turf/square-grid": "^5.1.5",
+ "@turf/triangle-grid": "^5.1.5"
+ }
+ },
+ "@turf/intersect": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/@turf/intersect/-/intersect-5.1.6.tgz",
+ "integrity": "sha512-KXyNv/GXdoGAOy03qZF53rgtXC2tNhF/4jLwTKiVRrBQH6kcEpipGStdJ+QkYIlarQPa8f7I9UlVAB19et4MfQ==",
+ "requires": {
+ "@turf/clean-coords": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5",
+ "@turf/truncate": "^5.1.5",
+ "turf-jsts": "*"
+ }
+ },
+ "@turf/invariant": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/invariant/-/invariant-5.1.5.tgz",
+ "integrity": "sha1-9Z9P76CSJLFdzhZR+QPIaNV6JOE=",
+ "requires": {
+ "@turf/helpers": "^5.1.5"
+ }
+ },
+ "@turf/isobands": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/isobands/-/isobands-5.1.5.tgz",
+ "integrity": "sha1-a0TO9YTVUaMTBBh68jtKFYLj8I0=",
+ "requires": {
+ "@turf/area": "^5.1.5",
+ "@turf/bbox": "^5.1.5",
+ "@turf/boolean-point-in-polygon": "^5.1.5",
+ "@turf/explode": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5",
+ "@turf/meta": "^5.1.5"
+ }
+ },
+ "@turf/isolines": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/isolines/-/isolines-5.1.5.tgz",
+ "integrity": "sha1-irTn9Cuz38VGFOW/FVln9+VdLeE=",
+ "requires": {
+ "@turf/bbox": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5",
+ "@turf/meta": "^5.1.5"
+ }
+ },
+ "@turf/kinks": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/kinks/-/kinks-5.1.5.tgz",
+ "integrity": "sha1-irtpYdm7AQchO63fLCwmQNAlaYA=",
+ "requires": {
+ "@turf/helpers": "^5.1.5"
+ }
+ },
+ "@turf/length": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/length/-/length-5.1.5.tgz",
+ "integrity": "sha1-86X4ZMK5lqi7RxeUU1ofrxLuvvs=",
+ "requires": {
+ "@turf/distance": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/meta": "^5.1.5"
+ }
+ },
+ "@turf/line-arc": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/line-arc/-/line-arc-5.1.5.tgz",
+ "integrity": "sha1-AHinRHg1oSrkFKIR+aZNEYYVDhU=",
+ "requires": {
+ "@turf/circle": "^5.1.5",
+ "@turf/destination": "^5.1.5",
+ "@turf/helpers": "^5.1.5"
+ }
+ },
+ "@turf/line-chunk": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/line-chunk/-/line-chunk-5.1.5.tgz",
+ "integrity": "sha1-kQqFwFwG2dD5w4l3oF4IGNUIXEI=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/length": "^5.1.5",
+ "@turf/line-slice-along": "^5.1.5",
+ "@turf/meta": "^5.1.5"
+ }
+ },
+ "@turf/line-intersect": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/line-intersect/-/line-intersect-5.1.5.tgz",
+ "integrity": "sha1-DikHGuQDKV5JFyO8SfXPrI0R3fM=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5",
+ "@turf/line-segment": "^5.1.5",
+ "@turf/meta": "^5.1.5",
+ "geojson-rbush": "2.1.0"
+ }
+ },
+ "@turf/line-offset": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/line-offset/-/line-offset-5.1.5.tgz",
+ "integrity": "sha1-KrWy8In4yRPiMdmUN4553KkLWh4=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5",
+ "@turf/meta": "^5.1.5"
+ }
+ },
+ "@turf/line-overlap": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/line-overlap/-/line-overlap-5.1.5.tgz",
+ "integrity": "sha1-lDxvh6A4bcQ9+sEdKz/5wRLNP2A=",
+ "requires": {
+ "@turf/boolean-point-on-line": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5",
+ "@turf/line-segment": "^5.1.5",
+ "@turf/meta": "^5.1.5",
+ "@turf/nearest-point-on-line": "^5.1.5",
+ "geojson-rbush": "2.1.0"
+ }
+ },
+ "@turf/line-segment": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/line-segment/-/line-segment-5.1.5.tgz",
+ "integrity": "sha1-Mgeq7lRqskw9jcPMY/kcdwuAE+U=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5",
+ "@turf/meta": "^5.1.5"
+ }
+ },
+ "@turf/line-slice": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/line-slice/-/line-slice-5.1.5.tgz",
+ "integrity": "sha1-Hs/OFGKjeFeXVM7fRGTN4mgp8rU=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5",
+ "@turf/nearest-point-on-line": "^5.1.5"
+ }
+ },
+ "@turf/line-slice-along": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/line-slice-along/-/line-slice-along-5.1.5.tgz",
+ "integrity": "sha1-7drQoh70efKWihG9LdcomiEy6aU=",
+ "requires": {
+ "@turf/bearing": "^5.1.5",
+ "@turf/destination": "^5.1.5",
+ "@turf/distance": "^5.1.5",
+ "@turf/helpers": "^5.1.5"
+ }
+ },
+ "@turf/line-split": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/line-split/-/line-split-5.1.5.tgz",
+ "integrity": "sha1-Wy30w3YZty73JbUWPPmSbVVArLc=",
+ "requires": {
+ "@turf/bbox": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5",
+ "@turf/line-intersect": "^5.1.5",
+ "@turf/line-segment": "^5.1.5",
+ "@turf/meta": "^5.1.5",
+ "@turf/nearest-point-on-line": "^5.1.5",
+ "@turf/square": "^5.1.5",
+ "@turf/truncate": "^5.1.5",
+ "geojson-rbush": "2.1.0"
+ }
+ },
+ "@turf/line-to-polygon": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/line-to-polygon/-/line-to-polygon-5.1.5.tgz",
+ "integrity": "sha1-ITz0Gmj4Ikd4ujnTGH3sPouBhlo=",
+ "requires": {
+ "@turf/bbox": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5"
+ }
+ },
+ "@turf/mask": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/mask/-/mask-5.1.5.tgz",
+ "integrity": "sha1-mrD+8aJyyY/j70kvn/thggayQtU=",
+ "requires": {
+ "@turf/bbox": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/meta": "^5.1.5",
+ "@turf/union": "^5.1.5",
+ "rbush": "^2.0.1"
+ }
+ },
+ "@turf/meta": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/@turf/meta/-/meta-5.1.6.tgz",
+ "integrity": "sha1-wgqGPt7Qhp+yhUje6Ik0G8y0akY=",
+ "requires": {
+ "@turf/helpers": "^5.1.5"
+ }
+ },
+ "@turf/midpoint": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/midpoint/-/midpoint-5.1.5.tgz",
+ "integrity": "sha1-4mH2srDqgSTM7/VSomLdRlydBfA=",
+ "requires": {
+ "@turf/bearing": "^5.1.5",
+ "@turf/destination": "^5.1.5",
+ "@turf/distance": "^5.1.5",
+ "@turf/helpers": "^5.1.5"
+ }
+ },
+ "@turf/nearest-point": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/nearest-point/-/nearest-point-5.1.5.tgz",
+ "integrity": "sha1-EgUN5Bw5hEMiTHl43g9iE5ANNPs=",
+ "requires": {
+ "@turf/clone": "^5.1.5",
+ "@turf/distance": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/meta": "^5.1.5"
+ }
+ },
+ "@turf/nearest-point-on-line": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/nearest-point-on-line/-/nearest-point-on-line-5.1.5.tgz",
+ "integrity": "sha1-VgauKX8VlHUkvqUaKp71HsG/nDY=",
+ "requires": {
+ "@turf/bearing": "^5.1.5",
+ "@turf/destination": "^5.1.5",
+ "@turf/distance": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5",
+ "@turf/line-intersect": "^5.1.5",
+ "@turf/meta": "^5.1.5"
+ }
+ },
+ "@turf/nearest-point-to-line": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/@turf/nearest-point-to-line/-/nearest-point-to-line-5.1.6.tgz",
+ "integrity": "sha512-ZSvDIEiHhifn/vNwLXZI/E8xmEz5yBPqfUR7BVHRZrB1cP7jLhKZvkbidjG//uW8Fr1Ulc+PFOXczLspIcx/lw==",
+ "requires": {
+ "@turf/helpers": "6.x",
+ "@turf/invariant": "6.x",
+ "@turf/meta": "6.x",
+ "@turf/point-to-line-distance": "^5.1.5",
+ "object-assign": "*"
+ },
+ "dependencies": {
+ "@turf/helpers": {
+ "version": "6.1.4",
+ "resolved": "https://registry.npmjs.org/@turf/helpers/-/helpers-6.1.4.tgz",
+ "integrity": "sha512-vJvrdOZy1ngC7r3MDA7zIGSoIgyrkWcGnNIEaqn/APmw+bVLF2gAW7HIsdTxd12s5wQMqEpqIQrmrbRRZ0xC7g=="
+ },
+ "@turf/invariant": {
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/@turf/invariant/-/invariant-6.1.2.tgz",
+ "integrity": "sha512-WU08Ph8j0J2jVGlQCKChXoCtI50BB3yEH21V++V0T4cR1T27HKCxkehV2sYMwTierfMBgjwSwDIsxnR4/2mWXg==",
+ "requires": {
+ "@turf/helpers": "6.x"
+ }
+ },
+ "@turf/meta": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/@turf/meta/-/meta-6.0.2.tgz",
+ "integrity": "sha512-VA7HJkx7qF1l3+GNGkDVn2oXy4+QoLP6LktXAaZKjuT1JI0YESat7quUkbCMy4zP9lAUuvS4YMslLyTtr919FA==",
+ "requires": {
+ "@turf/helpers": "6.x"
+ }
+ }
+ }
+ },
+ "@turf/planepoint": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/planepoint/-/planepoint-5.1.5.tgz",
+ "integrity": "sha1-GLvfAG91ne9eQsagBsn53oGyt/8=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5"
+ }
+ },
+ "@turf/point-grid": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/point-grid/-/point-grid-5.1.5.tgz",
+ "integrity": "sha1-MFFBJI9Quv42zn5mukuX56sjaIc=",
+ "requires": {
+ "@turf/boolean-within": "^5.1.5",
+ "@turf/distance": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5"
+ }
+ },
+ "@turf/point-on-feature": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/point-on-feature/-/point-on-feature-5.1.5.tgz",
+ "integrity": "sha1-MMfwMkMCd8ZBjZbSieRba/shP+c=",
+ "requires": {
+ "@turf/boolean-point-in-polygon": "^5.1.5",
+ "@turf/center": "^5.1.5",
+ "@turf/explode": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/nearest-point": "^5.1.5"
+ }
+ },
+ "@turf/point-to-line-distance": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/@turf/point-to-line-distance/-/point-to-line-distance-5.1.6.tgz",
+ "integrity": "sha512-PE3hiTeeDEi4ZLPtI8XAzFYW9nHo1EVsZGm/4ZVV8jo39d3X1oLVHxY3e1PkCmWwRapXy4QLqvnTQ7nU4wspNw==",
+ "requires": {
+ "@turf/bearing": "6.x",
+ "@turf/distance": "6.x",
+ "@turf/helpers": "6.x",
+ "@turf/invariant": "6.x",
+ "@turf/meta": "6.x",
+ "@turf/projection": "6.x",
+ "@turf/rhumb-bearing": "6.x",
+ "@turf/rhumb-distance": "6.x"
+ },
+ "dependencies": {
+ "@turf/bearing": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/@turf/bearing/-/bearing-6.0.1.tgz",
+ "integrity": "sha512-mXY1NozqV9EFfBTbUItujwfqfQF0G/Xe2fzvnZle90ekPEUfhi4Dgf5JswJTd96J9LiT8kcd6Jonp5khnx0wIg==",
+ "requires": {
+ "@turf/helpers": "6.x",
+ "@turf/invariant": "6.x"
+ }
+ },
+ "@turf/clone": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/@turf/clone/-/clone-6.0.2.tgz",
+ "integrity": "sha512-UVpYPnW3wRj3bPncR6Z2PRbowBk+nEdVWgGewPxrKKLfvswtVtG9n/OIyvbU3E3ZOadBVxTH2uAMEMOz4800FA==",
+ "requires": {
+ "@turf/helpers": "6.x"
+ }
+ },
+ "@turf/distance": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/@turf/distance/-/distance-6.0.1.tgz",
+ "integrity": "sha512-q7t7rWIWfkg7MP1Vt4uLjSEhe5rPfCO2JjpKmk7JC+QZKEQkuvHEqy3ejW1iC7Kw5ZcZNR3qdMGGz+6HnVwqvg==",
+ "requires": {
+ "@turf/helpers": "6.x",
+ "@turf/invariant": "6.x"
+ }
+ },
+ "@turf/helpers": {
+ "version": "6.1.4",
+ "resolved": "https://registry.npmjs.org/@turf/helpers/-/helpers-6.1.4.tgz",
+ "integrity": "sha512-vJvrdOZy1ngC7r3MDA7zIGSoIgyrkWcGnNIEaqn/APmw+bVLF2gAW7HIsdTxd12s5wQMqEpqIQrmrbRRZ0xC7g=="
+ },
+ "@turf/invariant": {
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/@turf/invariant/-/invariant-6.1.2.tgz",
+ "integrity": "sha512-WU08Ph8j0J2jVGlQCKChXoCtI50BB3yEH21V++V0T4cR1T27HKCxkehV2sYMwTierfMBgjwSwDIsxnR4/2mWXg==",
+ "requires": {
+ "@turf/helpers": "6.x"
+ }
+ },
+ "@turf/meta": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/@turf/meta/-/meta-6.0.2.tgz",
+ "integrity": "sha512-VA7HJkx7qF1l3+GNGkDVn2oXy4+QoLP6LktXAaZKjuT1JI0YESat7quUkbCMy4zP9lAUuvS4YMslLyTtr919FA==",
+ "requires": {
+ "@turf/helpers": "6.x"
+ }
+ },
+ "@turf/projection": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/@turf/projection/-/projection-6.0.1.tgz",
+ "integrity": "sha512-Y3RvGT6I53MjYKLG69e9sMk45wJXcLbrEO1t6P3WQQQGqA2gYhhMJyV41vE2Z2llrJpvs2dDx/tIeQzGd0HHMQ==",
+ "requires": {
+ "@turf/clone": "6.x",
+ "@turf/helpers": "6.x",
+ "@turf/meta": "6.x"
+ }
+ },
+ "@turf/rhumb-bearing": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/@turf/rhumb-bearing/-/rhumb-bearing-6.0.1.tgz",
+ "integrity": "sha512-MVBra8OVfjM4+/N0B3o6cBIYg9p/uRKzA9uk05RfrzasEbUL1vdD23LkTooVL74Yw4UxL8BQD9hS5Re2COJFDA==",
+ "requires": {
+ "@turf/helpers": "6.x",
+ "@turf/invariant": "6.x"
+ }
+ },
+ "@turf/rhumb-distance": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/@turf/rhumb-distance/-/rhumb-distance-6.0.1.tgz",
+ "integrity": "sha512-3G45DQtQByzzfHFPcCyJdUZFwsd45zfZ7sAb1ddF7mhEj4G70+T2G3GKjInymqDNrbyh2gbG6wQiZSToC8Uf9g==",
+ "requires": {
+ "@turf/helpers": "6.x",
+ "@turf/invariant": "6.x"
+ }
+ }
+ }
+ },
+ "@turf/points-within-polygon": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/points-within-polygon/-/points-within-polygon-5.1.5.tgz",
+ "integrity": "sha1-K4VaXfOq2lfC7oIKB1SrlJKKIzc=",
+ "requires": {
+ "@turf/boolean-point-in-polygon": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/meta": "^5.1.5"
+ }
+ },
+ "@turf/polygon-tangents": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/polygon-tangents/-/polygon-tangents-5.1.5.tgz",
+ "integrity": "sha1-K/AJkUcwJbF44lDcfLmuVAm71lI=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5"
+ }
+ },
+ "@turf/polygon-to-line": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/polygon-to-line/-/polygon-to-line-5.1.5.tgz",
+ "integrity": "sha1-I7tEjYTcTGUZmaxhGjbZHFklA2o=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5"
+ }
+ },
+ "@turf/polygonize": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/polygonize/-/polygonize-5.1.5.tgz",
+ "integrity": "sha1-BJP6EYefOdELmtAs5qI+lC0IqjI=",
+ "requires": {
+ "@turf/boolean-point-in-polygon": "^5.1.5",
+ "@turf/envelope": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5",
+ "@turf/meta": "^5.1.5"
+ }
+ },
+ "@turf/projection": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/projection/-/projection-5.1.5.tgz",
+ "integrity": "sha1-JFF+7rLzaBa6n3EueubWo2jt91c=",
+ "requires": {
+ "@turf/clone": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/meta": "^5.1.5"
+ }
+ },
+ "@turf/random": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/random/-/random-5.1.5.tgz",
+ "integrity": "sha1-sy78k0Vgroulfo67UfJBw5+6Lns=",
+ "requires": {
+ "@turf/helpers": "^5.1.5"
+ }
+ },
+ "@turf/rewind": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/rewind/-/rewind-5.1.5.tgz",
+ "integrity": "sha1-nqPbSmi3PB/R3RH1djGxQ8/vock=",
+ "requires": {
+ "@turf/boolean-clockwise": "^5.1.5",
+ "@turf/clone": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5",
+ "@turf/meta": "^5.1.5"
+ }
+ },
+ "@turf/rhumb-bearing": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/rhumb-bearing/-/rhumb-bearing-5.1.5.tgz",
+ "integrity": "sha1-rPalAkJ+uMSeGM2mrg7/qwxd3NI=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5"
+ }
+ },
+ "@turf/rhumb-destination": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/rhumb-destination/-/rhumb-destination-5.1.5.tgz",
+ "integrity": "sha1-sbKuuSFUfyrAwamUtqEw+SRjx0I=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5"
+ }
+ },
+ "@turf/rhumb-distance": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/rhumb-distance/-/rhumb-distance-5.1.5.tgz",
+ "integrity": "sha1-GAaFdiX0IlOE2tQT5p85U4/192U=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5"
+ }
+ },
+ "@turf/sample": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/sample/-/sample-5.1.5.tgz",
+ "integrity": "sha1-6ctEikeJzFbuPeLdZ4HiNDQ1tBE=",
+ "requires": {
+ "@turf/helpers": "^5.1.5"
+ }
+ },
+ "@turf/sector": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/sector/-/sector-5.1.5.tgz",
+ "integrity": "sha1-rCu5TBPt1gNPb9wrZwCBNdIPXgc=",
+ "requires": {
+ "@turf/circle": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5",
+ "@turf/line-arc": "^5.1.5",
+ "@turf/meta": "^5.1.5"
+ }
+ },
+ "@turf/shortest-path": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/shortest-path/-/shortest-path-5.1.5.tgz",
+ "integrity": "sha1-hUroCW9rw+EwD6ynfz6PZ9j5Nas=",
+ "requires": {
+ "@turf/bbox": "^5.1.5",
+ "@turf/bbox-polygon": "^5.1.5",
+ "@turf/boolean-point-in-polygon": "^5.1.5",
+ "@turf/clean-coords": "^5.1.5",
+ "@turf/distance": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5",
+ "@turf/meta": "^5.1.5",
+ "@turf/transform-scale": "^5.1.5"
+ }
+ },
+ "@turf/simplify": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/simplify/-/simplify-5.1.5.tgz",
+ "integrity": "sha1-Csjyei60IYGD7dmZjDJ1q+QIuSY=",
+ "requires": {
+ "@turf/clean-coords": "^5.1.5",
+ "@turf/clone": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/meta": "^5.1.5"
+ }
+ },
+ "@turf/square": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/square/-/square-5.1.5.tgz",
+ "integrity": "sha1-qnsh5gM8ySUsOlvW89iNq9b+0YA=",
+ "requires": {
+ "@turf/distance": "^5.1.5",
+ "@turf/helpers": "^5.1.5"
+ }
+ },
+ "@turf/square-grid": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/square-grid/-/square-grid-5.1.5.tgz",
+ "integrity": "sha1-G9X3uesU8LYLwjH+/nNR0aMvGlE=",
+ "requires": {
+ "@turf/boolean-contains": "^5.1.5",
+ "@turf/boolean-overlap": "^5.1.5",
+ "@turf/distance": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/intersect": "^5.1.5",
+ "@turf/invariant": "^5.1.5"
+ }
+ },
+ "@turf/standard-deviational-ellipse": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/standard-deviational-ellipse/-/standard-deviational-ellipse-5.1.5.tgz",
+ "integrity": "sha1-hc0oO14ayljyG9ZkEuQUtW2FIyQ=",
+ "requires": {
+ "@turf/center-mean": "^5.1.5",
+ "@turf/ellipse": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5",
+ "@turf/meta": "^5.1.5",
+ "@turf/points-within-polygon": "^5.1.5"
+ }
+ },
+ "@turf/tag": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/tag/-/tag-5.1.5.tgz",
+ "integrity": "sha1-0e4aUIjs/UoUEQGcmCOczypJfSA=",
+ "requires": {
+ "@turf/boolean-point-in-polygon": "^5.1.5",
+ "@turf/clone": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/meta": "^5.1.5"
+ }
+ },
+ "@turf/tesselate": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/tesselate/-/tesselate-5.1.5.tgz",
+ "integrity": "sha1-MqWU6cIaAEIKn5DSxD3z4RZgYc0=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "earcut": "^2.0.0"
+ }
+ },
+ "@turf/tin": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/tin/-/tin-5.1.5.tgz",
+ "integrity": "sha1-KCI+r8X76a6azKgc3P6l0UJMkX0=",
+ "requires": {
+ "@turf/helpers": "^5.1.5"
+ }
+ },
+ "@turf/transform-rotate": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/transform-rotate/-/transform-rotate-5.1.5.tgz",
+ "integrity": "sha1-0Jbt2eMA/jFQadVNjkWMQJIh7fs=",
+ "requires": {
+ "@turf/centroid": "^5.1.5",
+ "@turf/clone": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5",
+ "@turf/meta": "^5.1.5",
+ "@turf/rhumb-bearing": "^5.1.5",
+ "@turf/rhumb-destination": "^5.1.5",
+ "@turf/rhumb-distance": "^5.1.5"
+ }
+ },
+ "@turf/transform-scale": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/transform-scale/-/transform-scale-5.1.5.tgz",
+ "integrity": "sha1-cP064BhWz3uunxWtVhzf6PiQAbk=",
+ "requires": {
+ "@turf/bbox": "^5.1.5",
+ "@turf/center": "^5.1.5",
+ "@turf/centroid": "^5.1.5",
+ "@turf/clone": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5",
+ "@turf/meta": "^5.1.5",
+ "@turf/rhumb-bearing": "^5.1.5",
+ "@turf/rhumb-destination": "^5.1.5",
+ "@turf/rhumb-distance": "^5.1.5"
+ }
+ },
+ "@turf/transform-translate": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/transform-translate/-/transform-translate-5.1.5.tgz",
+ "integrity": "sha1-Uwolf7Hccmja3Ks05nkB6yo97GM=",
+ "requires": {
+ "@turf/clone": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5",
+ "@turf/meta": "^5.1.5",
+ "@turf/rhumb-destination": "^5.1.5"
+ }
+ },
+ "@turf/triangle-grid": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/triangle-grid/-/triangle-grid-5.1.5.tgz",
+ "integrity": "sha1-ezZ2IQhVTBTyjK/zxIsc/ILI3IE=",
+ "requires": {
+ "@turf/distance": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/intersect": "^5.1.5",
+ "@turf/invariant": "^5.1.5"
+ }
+ },
+ "@turf/truncate": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/truncate/-/truncate-5.1.5.tgz",
+ "integrity": "sha1-nu37Oxi6gfLJjT6tCUMcyhiErYk=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/meta": "^5.1.5"
+ }
+ },
+ "@turf/turf": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/@turf/turf/-/turf-5.1.6.tgz",
+ "integrity": "sha1-wxIlkoh+0jS3VGi4qMRb+Ib7+PY=",
+ "requires": {
+ "@turf/along": "5.1.x",
+ "@turf/area": "5.1.x",
+ "@turf/bbox": "5.1.x",
+ "@turf/bbox-clip": "5.1.x",
+ "@turf/bbox-polygon": "5.1.x",
+ "@turf/bearing": "5.1.x",
+ "@turf/bezier-spline": "5.1.x",
+ "@turf/boolean-clockwise": "5.1.x",
+ "@turf/boolean-contains": "5.1.x",
+ "@turf/boolean-crosses": "5.1.x",
+ "@turf/boolean-disjoint": "5.1.x",
+ "@turf/boolean-equal": "5.1.x",
+ "@turf/boolean-overlap": "5.1.x",
+ "@turf/boolean-parallel": "5.1.x",
+ "@turf/boolean-point-in-polygon": "5.1.x",
+ "@turf/boolean-point-on-line": "5.1.x",
+ "@turf/boolean-within": "5.1.x",
+ "@turf/buffer": "5.1.x",
+ "@turf/center": "5.1.x",
+ "@turf/center-mean": "5.1.x",
+ "@turf/center-median": "5.1.x",
+ "@turf/center-of-mass": "5.1.x",
+ "@turf/centroid": "5.1.x",
+ "@turf/circle": "5.1.x",
+ "@turf/clean-coords": "5.1.x",
+ "@turf/clone": "5.1.x",
+ "@turf/clusters": "5.1.x",
+ "@turf/clusters-dbscan": "5.1.x",
+ "@turf/clusters-kmeans": "5.1.x",
+ "@turf/collect": "5.1.x",
+ "@turf/combine": "5.1.x",
+ "@turf/concave": "5.1.x",
+ "@turf/convex": "5.1.x",
+ "@turf/destination": "5.1.x",
+ "@turf/difference": "5.1.x",
+ "@turf/dissolve": "5.1.x",
+ "@turf/distance": "5.1.x",
+ "@turf/ellipse": "5.1.x",
+ "@turf/envelope": "5.1.x",
+ "@turf/explode": "5.1.x",
+ "@turf/flatten": "5.1.x",
+ "@turf/flip": "5.1.x",
+ "@turf/great-circle": "5.1.x",
+ "@turf/helpers": "5.1.x",
+ "@turf/hex-grid": "5.1.x",
+ "@turf/interpolate": "5.1.x",
+ "@turf/intersect": "5.1.x",
+ "@turf/invariant": "5.1.x",
+ "@turf/isobands": "5.1.x",
+ "@turf/isolines": "5.1.x",
+ "@turf/kinks": "5.1.x",
+ "@turf/length": "5.1.x",
+ "@turf/line-arc": "5.1.x",
+ "@turf/line-chunk": "5.1.x",
+ "@turf/line-intersect": "5.1.x",
+ "@turf/line-offset": "5.1.x",
+ "@turf/line-overlap": "5.1.x",
+ "@turf/line-segment": "5.1.x",
+ "@turf/line-slice": "5.1.x",
+ "@turf/line-slice-along": "5.1.x",
+ "@turf/line-split": "5.1.x",
+ "@turf/line-to-polygon": "5.1.x",
+ "@turf/mask": "5.1.x",
+ "@turf/meta": "5.1.x",
+ "@turf/midpoint": "5.1.x",
+ "@turf/nearest-point": "5.1.x",
+ "@turf/nearest-point-on-line": "5.1.x",
+ "@turf/nearest-point-to-line": "5.1.x",
+ "@turf/planepoint": "5.1.x",
+ "@turf/point-grid": "5.1.x",
+ "@turf/point-on-feature": "5.1.x",
+ "@turf/point-to-line-distance": "5.1.x",
+ "@turf/points-within-polygon": "5.1.x",
+ "@turf/polygon-tangents": "5.1.x",
+ "@turf/polygon-to-line": "5.1.x",
+ "@turf/polygonize": "5.1.x",
+ "@turf/projection": "5.1.x",
+ "@turf/random": "5.1.x",
+ "@turf/rewind": "5.1.x",
+ "@turf/rhumb-bearing": "5.1.x",
+ "@turf/rhumb-destination": "5.1.x",
+ "@turf/rhumb-distance": "5.1.x",
+ "@turf/sample": "5.1.x",
+ "@turf/sector": "5.1.x",
+ "@turf/shortest-path": "5.1.x",
+ "@turf/simplify": "5.1.x",
+ "@turf/square": "5.1.x",
+ "@turf/square-grid": "5.1.x",
+ "@turf/standard-deviational-ellipse": "5.1.x",
+ "@turf/tag": "5.1.x",
+ "@turf/tesselate": "5.1.x",
+ "@turf/tin": "5.1.x",
+ "@turf/transform-rotate": "5.1.x",
+ "@turf/transform-scale": "5.1.x",
+ "@turf/transform-translate": "5.1.x",
+ "@turf/triangle-grid": "5.1.x",
+ "@turf/truncate": "5.1.x",
+ "@turf/union": "5.1.x",
+ "@turf/unkink-polygon": "5.1.x",
+ "@turf/voronoi": "5.1.x"
+ }
+ },
+ "@turf/union": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/union/-/union-5.1.5.tgz",
+ "integrity": "sha1-UyhbYJQEf8WNlqrA6pCGXsNNRUs=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "turf-jsts": "*"
+ }
+ },
+ "@turf/unkink-polygon": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/unkink-polygon/-/unkink-polygon-5.1.5.tgz",
+ "integrity": "sha1-ewGEfFD7V0riV54Z5Ey6hSbSE8M=",
+ "requires": {
+ "@turf/area": "^5.1.5",
+ "@turf/boolean-point-in-polygon": "^5.1.5",
+ "@turf/helpers": "^5.1.5",
+ "@turf/meta": "^5.1.5",
+ "rbush": "^2.0.1"
+ }
+ },
+ "@turf/voronoi": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/@turf/voronoi/-/voronoi-5.1.5.tgz",
+ "integrity": "sha1-6FbpQG3MLyXWbdyJhYTifC6/ymY=",
+ "requires": {
+ "@turf/helpers": "^5.1.5",
+ "@turf/invariant": "^5.1.5",
+ "d3-voronoi": "1.1.2"
+ }
+ },
+ "@videojs/http-streaming": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/@videojs/http-streaming/-/http-streaming-1.9.3.tgz",
+ "integrity": "sha512-gNdqyvhxTU67optzxiywHXi/z2+Ju0b6hNth0V7BsL7YAH+R1StIKmmp6SsfFZQfrNW5ykYFoR95M/AT5cg9Ug==",
+ "requires": {
+ "aes-decrypter": "3.0.0",
+ "global": "^4.3.0",
+ "m3u8-parser": "4.3.0",
+ "mpd-parser": "0.7.0",
+ "mux.js": "5.1.1",
+ "url-toolkit": "^2.1.3",
+ "video.js": "^6.8.0 || ^7.0.0"
+ }
+ },
+ "JSV": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/JSV/-/JSV-4.0.2.tgz",
+ "integrity": "sha1-0Hf2glVx+CEy+d/67Vh7QCn+/1c="
+ },
+ "abbrev": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz",
+ "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=",
+ "dev": true
+ },
+ "accepts": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz",
+ "integrity": "sha1-w8p0NJOGSMPg2cHjKN1otiLChMo=",
+ "dev": true,
+ "requires": {
+ "mime-types": "~2.1.11",
+ "negotiator": "0.6.1"
+ }
+ },
+ "acorn": {
+ "version": "5.7.4",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz",
+ "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg=="
+ },
+ "acorn-dynamic-import": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz",
+ "integrity": "sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ=",
+ "dev": true,
+ "requires": {
+ "acorn": "^4.0.3"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "4.0.13",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz",
+ "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=",
+ "dev": true
+ }
+ }
+ },
+ "acorn-jsx": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz",
+ "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=",
+ "requires": {
+ "acorn": "^3.0.4"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
+ "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo="
+ }
+ }
+ },
+ "acorn-object-spread": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/acorn-object-spread/-/acorn-object-spread-1.0.0.tgz",
+ "integrity": "sha1-SOrQ9KjrFplaF6Dbn/xqyq2kumg=",
+ "requires": {
+ "acorn": "^3.1.0"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
+ "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo="
+ }
+ }
+ },
+ "adjust-sourcemap-loader": {
+ "version": "1.2.0",
+ "resolved": "http://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-1.2.0.tgz",
+ "integrity": "sha512-958oaHHVEXMvsY7v7cC5gEkNIcoaAVIhZ4mBReYVZJOTP9IgKmzLjIOhTtzpLMu+qriXvLsVjJ155EeInp45IQ==",
+ "dev": true,
+ "requires": {
+ "assert": "^1.3.0",
+ "camelcase": "^1.2.1",
+ "loader-utils": "^1.1.0",
+ "lodash.assign": "^4.0.1",
+ "lodash.defaults": "^3.1.2",
+ "object-path": "^0.9.2",
+ "regex-parser": "^2.2.9"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
+ "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=",
+ "dev": true
+ },
+ "lodash.defaults": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-3.1.2.tgz",
+ "integrity": "sha1-xzCLGNv4vJNy1wGnNJPGEZK9Liw=",
+ "dev": true,
+ "requires": {
+ "lodash.assign": "^3.0.0",
+ "lodash.restparam": "^3.0.0"
+ },
+ "dependencies": {
+ "lodash.assign": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-3.2.0.tgz",
+ "integrity": "sha1-POnwI0tLIiPilrj6CsH+6OvKZPo=",
+ "dev": true,
+ "requires": {
+ "lodash._baseassign": "^3.0.0",
+ "lodash._createassigner": "^3.0.0",
+ "lodash.keys": "^3.0.0"
+ }
+ }
+ }
+ },
+ "object-path": {
+ "version": "0.9.2",
+ "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.9.2.tgz",
+ "integrity": "sha1-D9mnT8X60a45aLWGvaXGMr1sBaU=",
+ "dev": true
+ }
+ }
+ },
+ "aes-decrypter": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/aes-decrypter/-/aes-decrypter-3.0.0.tgz",
+ "integrity": "sha1-eEihwUW5/b9Xrj4rWxvHzwZEqPs=",
+ "requires": {
+ "commander": "^2.9.0",
+ "global": "^4.3.2",
+ "pkcs7": "^1.0.2"
+ }
+ },
+ "after": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
+ "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=",
+ "dev": true
+ },
+ "ajv": {
+ "version": "5.5.2",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
+ "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
+ "requires": {
+ "co": "^4.6.0",
+ "fast-deep-equal": "^1.0.0",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.3.0"
+ }
+ },
+ "ajv-keywords": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz",
+ "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=",
+ "dev": true
+ },
+ "align-text": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
+ "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2",
+ "longest": "^1.0.1",
+ "repeat-string": "^1.5.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "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="
+ },
+ "ansi-align": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz",
+ "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=",
+ "dev": true,
+ "requires": {
+ "string-width": "^2.0.0"
+ }
+ },
+ "ansi-escapes": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz",
+ "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw=="
+ },
+ "ansi-html": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz",
+ "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=",
+ "dev": true
+ },
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
+ },
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
+ },
+ "ansicolors": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.2.1.tgz",
+ "integrity": "sha1-vgiVmQl7dKXJxKhKDNvNtivYeu8="
+ },
+ "anymatch": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz",
+ "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==",
+ "dev": true,
+ "requires": {
+ "micromatch": "^2.1.5",
+ "normalize-path": "^2.0.0"
+ }
+ },
+ "aproba": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
+ "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
+ "dev": true
+ },
+ "are-we-there-yet": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
+ "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
+ "dev": true,
+ "requires": {
+ "delegates": "^1.0.0",
+ "readable-stream": "^2.0.6"
+ }
+ },
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ },
+ "dependencies": {
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
+ }
+ }
+ },
+ "aria-query": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-0.7.1.tgz",
+ "integrity": "sha1-Jsu1r/ZBRLCoJb4YRuCxbPoAsR4=",
+ "dev": true,
+ "requires": {
+ "ast-types-flow": "0.0.7",
+ "commander": "^2.11.0"
+ }
+ },
+ "arr-diff": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
+ "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
+ "requires": {
+ "arr-flatten": "^1.0.1"
+ }
+ },
+ "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-union": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+ "dev": true
+ },
+ "array-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="
+ },
+ "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-includes": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz",
+ "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.2",
+ "es-abstract": "^1.7.0"
+ }
+ },
+ "array-slice": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz",
+ "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=",
+ "dev": true
+ },
+ "array-union": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
+ "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
+ "dev": true,
+ "requires": {
+ "array-uniq": "^1.0.1"
+ }
+ },
+ "array-uniq": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+ "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
+ "dev": true
+ },
+ "array-unique": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
+ "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM="
+ },
+ "arraybuffer.slice": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz",
+ "integrity": "sha1-8zshWfBTKj8xB6JywMz70a0peco=",
+ "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": "4.10.1",
+ "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
+ "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.0.0",
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0"
+ }
+ },
+ "assert": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz",
+ "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=",
+ "dev": true,
+ "requires": {
+ "util": "0.10.3"
+ }
+ },
+ "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=",
+ "dev": true
+ },
+ "ast-types-flow": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz",
+ "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=",
+ "dev": true
+ },
+ "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"
+ }
+ },
+ "async-each": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
+ "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=",
+ "dev": true
+ },
+ "async-foreach": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz",
+ "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=",
+ "dev": true
+ },
+ "asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
+ },
+ "atob": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
+ "dev": true
+ },
+ "autoprefixer": {
+ "version": "6.7.7",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz",
+ "integrity": "sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ=",
+ "dev": true,
+ "requires": {
+ "browserslist": "^1.7.6",
+ "caniuse-db": "^1.0.30000634",
+ "normalize-range": "^0.1.2",
+ "num2fraction": "^1.2.2",
+ "postcss": "^5.2.16",
+ "postcss-value-parser": "^3.2.3"
+ }
+ },
+ "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.8.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
+ "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ=="
+ },
+ "axios": {
+ "version": "0.19.2",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
+ "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==",
+ "requires": {
+ "follow-redirects": "1.5.10"
+ },
+ "dependencies": {
+ "follow-redirects": {
+ "version": "1.5.10",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
+ "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
+ "requires": {
+ "debug": "=3.1.0"
+ }
+ }
+ }
+ },
+ "axobject-query": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-0.1.0.tgz",
+ "integrity": "sha1-YvWdvFnJ+SQnWco0mWDnov48NsA=",
+ "dev": true,
+ "requires": {
+ "ast-types-flow": "0.0.7"
+ }
+ },
+ "babel-cli": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-cli/-/babel-cli-6.26.0.tgz",
+ "integrity": "sha1-UCq1SHTX24itALiHoGODzgPQAvE=",
+ "dev": true,
+ "requires": {
+ "babel-core": "^6.26.0",
+ "babel-polyfill": "^6.26.0",
+ "babel-register": "^6.26.0",
+ "babel-runtime": "^6.26.0",
+ "chokidar": "^1.6.1",
+ "commander": "^2.11.0",
+ "convert-source-map": "^1.5.0",
+ "fs-readdir-recursive": "^1.0.0",
+ "glob": "^7.1.2",
+ "lodash": "^4.17.4",
+ "output-file-sync": "^1.1.2",
+ "path-is-absolute": "^1.0.1",
+ "slash": "^1.0.0",
+ "source-map": "^0.5.6",
+ "v8flags": "^2.1.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
+ }
+ }
+ },
+ "babel-code-frame": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
+ "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.1.3",
+ "esutils": "^2.0.2",
+ "js-tokens": "^3.0.2"
+ },
+ "dependencies": {
+ "js-tokens": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
+ "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
+ "dev": true
+ }
+ }
+ },
+ "babel-core": {
+ "version": "6.26.3",
+ "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz",
+ "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==",
+ "dev": true,
+ "requires": {
+ "babel-code-frame": "^6.26.0",
+ "babel-generator": "^6.26.0",
+ "babel-helpers": "^6.24.1",
+ "babel-messages": "^6.23.0",
+ "babel-register": "^6.26.0",
+ "babel-runtime": "^6.26.0",
+ "babel-template": "^6.26.0",
+ "babel-traverse": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "babylon": "^6.18.0",
+ "convert-source-map": "^1.5.1",
+ "debug": "^2.6.9",
+ "json5": "^0.5.1",
+ "lodash": "^4.17.4",
+ "minimatch": "^3.0.4",
+ "path-is-absolute": "^1.0.1",
+ "private": "^0.1.8",
+ "slash": "^1.0.0",
+ "source-map": "^0.5.7"
+ },
+ "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"
+ }
+ },
+ "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-eslint": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-7.2.3.tgz",
+ "integrity": "sha1-sv4tgBJkcPXBlELcdXJTqJdxCCc=",
+ "dev": true,
+ "requires": {
+ "babel-code-frame": "^6.22.0",
+ "babel-traverse": "^6.23.1",
+ "babel-types": "^6.23.0",
+ "babylon": "^6.17.0"
+ }
+ },
+ "babel-generator": {
+ "version": "6.26.1",
+ "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz",
+ "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==",
+ "dev": true,
+ "requires": {
+ "babel-messages": "^6.23.0",
+ "babel-runtime": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "detect-indent": "^4.0.0",
+ "jsesc": "^1.3.0",
+ "lodash": "^4.17.4",
+ "source-map": "^0.5.7",
+ "trim-right": "^1.0.1"
+ },
+ "dependencies": {
+ "detect-indent": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz",
+ "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=",
+ "dev": true,
+ "requires": {
+ "repeating": "^2.0.0"
+ }
+ },
+ "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-bindify-decorators": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz",
+ "integrity": "sha1-FMGeXxQte0fxmlJDHlKxzLxAozA=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-helper-builder-binary-assignment-operator-visitor": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz",
+ "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=",
+ "dev": true,
+ "requires": {
+ "babel-helper-explode-assignable-expression": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-helper-call-delegate": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz",
+ "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=",
+ "dev": true,
+ "requires": {
+ "babel-helper-hoist-variables": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-helper-define-map": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz",
+ "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=",
+ "dev": true,
+ "requires": {
+ "babel-helper-function-name": "^6.24.1",
+ "babel-runtime": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "lodash": "^4.17.4"
+ }
+ },
+ "babel-helper-explode-assignable-expression": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz",
+ "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-helper-explode-class": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz",
+ "integrity": "sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes=",
+ "dev": true,
+ "requires": {
+ "babel-helper-bindify-decorators": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-helper-function-name": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz",
+ "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=",
+ "dev": true,
+ "requires": {
+ "babel-helper-get-function-arity": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-helper-get-function-arity": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz",
+ "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-helper-hoist-variables": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz",
+ "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-helper-optimise-call-expression": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz",
+ "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-helper-regex": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz",
+ "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "lodash": "^4.17.4"
+ }
+ },
+ "babel-helper-remap-async-to-generator": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz",
+ "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=",
+ "dev": true,
+ "requires": {
+ "babel-helper-function-name": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-helper-replace-supers": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz",
+ "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=",
+ "dev": true,
+ "requires": {
+ "babel-helper-optimise-call-expression": "^6.24.1",
+ "babel-messages": "^6.23.0",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-helpers": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz",
+ "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1"
+ }
+ },
+ "babel-loader": {
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-7.1.4.tgz",
+ "integrity": "sha512-/hbyEvPzBJuGpk9o80R0ZyTej6heEOr59GoEUtn8qFKbnx4cJm9FWES6J/iv644sYgrtVw9JJQkjaLW/bqb5gw==",
+ "dev": true,
+ "requires": {
+ "find-cache-dir": "^1.0.0",
+ "loader-utils": "^1.0.2",
+ "mkdirp": "^0.5.1"
+ }
+ },
+ "babel-messages": {
+ "version": "6.23.0",
+ "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz",
+ "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-check-es2015-constants": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz",
+ "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-syntax-async-functions": {
+ "version": "6.13.0",
+ "resolved": "http://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz",
+ "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=",
+ "dev": true
+ },
+ "babel-plugin-syntax-async-generators": {
+ "version": "6.13.0",
+ "resolved": "http://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz",
+ "integrity": "sha1-a8lj67FuzLrmuStZbrfzXDQqi5o=",
+ "dev": true
+ },
+ "babel-plugin-syntax-class-constructor-call": {
+ "version": "6.18.0",
+ "resolved": "http://registry.npmjs.org/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz",
+ "integrity": "sha1-nLnTn+Q8hgC+yBRkVt3L1OGnZBY=",
+ "dev": true
+ },
+ "babel-plugin-syntax-class-properties": {
+ "version": "6.13.0",
+ "resolved": "http://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz",
+ "integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=",
+ "dev": true
+ },
+ "babel-plugin-syntax-decorators": {
+ "version": "6.13.0",
+ "resolved": "http://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz",
+ "integrity": "sha1-MSVjtNvePMgGzuPkFszurd0RrAs=",
+ "dev": true
+ },
+ "babel-plugin-syntax-do-expressions": {
+ "version": "6.13.0",
+ "resolved": "http://registry.npmjs.org/babel-plugin-syntax-do-expressions/-/babel-plugin-syntax-do-expressions-6.13.0.tgz",
+ "integrity": "sha1-V0d1YTmqJtOQ0JQQsDdEugfkeW0=",
+ "dev": true
+ },
+ "babel-plugin-syntax-dynamic-import": {
+ "version": "6.18.0",
+ "resolved": "http://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz",
+ "integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=",
+ "dev": true
+ },
+ "babel-plugin-syntax-exponentiation-operator": {
+ "version": "6.13.0",
+ "resolved": "http://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz",
+ "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=",
+ "dev": true
+ },
+ "babel-plugin-syntax-export-extensions": {
+ "version": "6.13.0",
+ "resolved": "http://registry.npmjs.org/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz",
+ "integrity": "sha1-cKFITw+QiaToStRLrDU8lbmxJyE=",
+ "dev": true
+ },
+ "babel-plugin-syntax-function-bind": {
+ "version": "6.13.0",
+ "resolved": "http://registry.npmjs.org/babel-plugin-syntax-function-bind/-/babel-plugin-syntax-function-bind-6.13.0.tgz",
+ "integrity": "sha1-SMSV8Xe98xqYHnMvVa3AvdJgH0Y=",
+ "dev": true
+ },
+ "babel-plugin-syntax-jsx": {
+ "version": "6.18.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",
+ "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=",
+ "dev": true
+ },
+ "babel-plugin-syntax-object-rest-spread": {
+ "version": "6.13.0",
+ "resolved": "http://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
+ "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=",
+ "dev": true
+ },
+ "babel-plugin-syntax-trailing-function-commas": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz",
+ "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=",
+ "dev": true
+ },
+ "babel-plugin-transform-async-generator-functions": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz",
+ "integrity": "sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds=",
+ "dev": true,
+ "requires": {
+ "babel-helper-remap-async-to-generator": "^6.24.1",
+ "babel-plugin-syntax-async-generators": "^6.5.0",
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-async-to-generator": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz",
+ "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=",
+ "dev": true,
+ "requires": {
+ "babel-helper-remap-async-to-generator": "^6.24.1",
+ "babel-plugin-syntax-async-functions": "^6.8.0",
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-class-constructor-call": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-constructor-call/-/babel-plugin-transform-class-constructor-call-6.24.1.tgz",
+ "integrity": "sha1-gNwoVQWsBn3LjWxl4vbxGrd2Xvk=",
+ "dev": true,
+ "requires": {
+ "babel-plugin-syntax-class-constructor-call": "^6.18.0",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-class-properties": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz",
+ "integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=",
+ "dev": true,
+ "requires": {
+ "babel-helper-function-name": "^6.24.1",
+ "babel-plugin-syntax-class-properties": "^6.8.0",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-decorators": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz",
+ "integrity": "sha1-eIAT2PjGtSIr33s0Q5Df13Vp4k0=",
+ "dev": true,
+ "requires": {
+ "babel-helper-explode-class": "^6.24.1",
+ "babel-plugin-syntax-decorators": "^6.13.0",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-do-expressions": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-do-expressions/-/babel-plugin-transform-do-expressions-6.22.0.tgz",
+ "integrity": "sha1-KMyvkoEtlJws0SgfaQyP3EaK6bs=",
+ "dev": true,
+ "requires": {
+ "babel-plugin-syntax-do-expressions": "^6.8.0",
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-es2015-arrow-functions": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz",
+ "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-es2015-block-scoped-functions": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz",
+ "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-es2015-block-scoping": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz",
+ "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.26.0",
+ "babel-template": "^6.26.0",
+ "babel-traverse": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "lodash": "^4.17.4"
+ }
+ },
+ "babel-plugin-transform-es2015-classes": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz",
+ "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=",
+ "dev": true,
+ "requires": {
+ "babel-helper-define-map": "^6.24.1",
+ "babel-helper-function-name": "^6.24.1",
+ "babel-helper-optimise-call-expression": "^6.24.1",
+ "babel-helper-replace-supers": "^6.24.1",
+ "babel-messages": "^6.23.0",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-es2015-computed-properties": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz",
+ "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-es2015-destructuring": {
+ "version": "6.23.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz",
+ "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-es2015-duplicate-keys": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz",
+ "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-es2015-for-of": {
+ "version": "6.23.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz",
+ "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-es2015-function-name": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz",
+ "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=",
+ "dev": true,
+ "requires": {
+ "babel-helper-function-name": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-es2015-literals": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz",
+ "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-es2015-modules-amd": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz",
+ "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=",
+ "dev": true,
+ "requires": {
+ "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-es2015-modules-commonjs": {
+ "version": "6.26.2",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz",
+ "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==",
+ "dev": true,
+ "requires": {
+ "babel-plugin-transform-strict-mode": "^6.24.1",
+ "babel-runtime": "^6.26.0",
+ "babel-template": "^6.26.0",
+ "babel-types": "^6.26.0"
+ }
+ },
+ "babel-plugin-transform-es2015-modules-systemjs": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz",
+ "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=",
+ "dev": true,
+ "requires": {
+ "babel-helper-hoist-variables": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-es2015-modules-umd": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz",
+ "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=",
+ "dev": true,
+ "requires": {
+ "babel-plugin-transform-es2015-modules-amd": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-es2015-object-super": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz",
+ "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=",
+ "dev": true,
+ "requires": {
+ "babel-helper-replace-supers": "^6.24.1",
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-es2015-parameters": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz",
+ "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=",
+ "dev": true,
+ "requires": {
+ "babel-helper-call-delegate": "^6.24.1",
+ "babel-helper-get-function-arity": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-es2015-shorthand-properties": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz",
+ "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-es2015-spread": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz",
+ "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-es2015-sticky-regex": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz",
+ "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=",
+ "dev": true,
+ "requires": {
+ "babel-helper-regex": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-es2015-template-literals": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz",
+ "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-es2015-typeof-symbol": {
+ "version": "6.23.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz",
+ "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-es2015-unicode-regex": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz",
+ "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=",
+ "dev": true,
+ "requires": {
+ "babel-helper-regex": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "regexpu-core": "^2.0.0"
+ }
+ },
+ "babel-plugin-transform-exponentiation-operator": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz",
+ "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=",
+ "dev": true,
+ "requires": {
+ "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1",
+ "babel-plugin-syntax-exponentiation-operator": "^6.8.0",
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-export-extensions": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-6.22.0.tgz",
+ "integrity": "sha1-U3OLR+deghhYnuqUbLvTkQm75lM=",
+ "dev": true,
+ "requires": {
+ "babel-plugin-syntax-export-extensions": "^6.8.0",
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-function-bind": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-function-bind/-/babel-plugin-transform-function-bind-6.22.0.tgz",
+ "integrity": "sha1-xvuOlqwpajELjPjqQBRiQH3fapc=",
+ "dev": true,
+ "requires": {
+ "babel-plugin-syntax-function-bind": "^6.8.0",
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-object-rest-spread": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz",
+ "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=",
+ "dev": true,
+ "requires": {
+ "babel-plugin-syntax-object-rest-spread": "^6.8.0",
+ "babel-runtime": "^6.26.0"
+ }
+ },
+ "babel-plugin-transform-regenerator": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz",
+ "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=",
+ "dev": true,
+ "requires": {
+ "regenerator-transform": "^0.10.0"
+ }
+ },
+ "babel-plugin-transform-strict-mode": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz",
+ "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-polyfill": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz",
+ "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.26.0",
+ "core-js": "^2.5.0",
+ "regenerator-runtime": "^0.10.5"
+ },
+ "dependencies": {
+ "regenerator-runtime": {
+ "version": "0.10.5",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz",
+ "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=",
+ "dev": true
+ }
+ }
+ },
+ "babel-preset-es2015": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz",
+ "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=",
+ "dev": true,
+ "requires": {
+ "babel-plugin-check-es2015-constants": "^6.22.0",
+ "babel-plugin-transform-es2015-arrow-functions": "^6.22.0",
+ "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0",
+ "babel-plugin-transform-es2015-block-scoping": "^6.24.1",
+ "babel-plugin-transform-es2015-classes": "^6.24.1",
+ "babel-plugin-transform-es2015-computed-properties": "^6.24.1",
+ "babel-plugin-transform-es2015-destructuring": "^6.22.0",
+ "babel-plugin-transform-es2015-duplicate-keys": "^6.24.1",
+ "babel-plugin-transform-es2015-for-of": "^6.22.0",
+ "babel-plugin-transform-es2015-function-name": "^6.24.1",
+ "babel-plugin-transform-es2015-literals": "^6.22.0",
+ "babel-plugin-transform-es2015-modules-amd": "^6.24.1",
+ "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1",
+ "babel-plugin-transform-es2015-modules-systemjs": "^6.24.1",
+ "babel-plugin-transform-es2015-modules-umd": "^6.24.1",
+ "babel-plugin-transform-es2015-object-super": "^6.24.1",
+ "babel-plugin-transform-es2015-parameters": "^6.24.1",
+ "babel-plugin-transform-es2015-shorthand-properties": "^6.24.1",
+ "babel-plugin-transform-es2015-spread": "^6.22.0",
+ "babel-plugin-transform-es2015-sticky-regex": "^6.24.1",
+ "babel-plugin-transform-es2015-template-literals": "^6.22.0",
+ "babel-plugin-transform-es2015-typeof-symbol": "^6.22.0",
+ "babel-plugin-transform-es2015-unicode-regex": "^6.24.1",
+ "babel-plugin-transform-regenerator": "^6.24.1"
+ }
+ },
+ "babel-preset-stage-0": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-preset-stage-0/-/babel-preset-stage-0-6.24.1.tgz",
+ "integrity": "sha1-VkLRUEL5E4TX5a+LyIsduVsDnmo=",
+ "dev": true,
+ "requires": {
+ "babel-plugin-transform-do-expressions": "^6.22.0",
+ "babel-plugin-transform-function-bind": "^6.22.0",
+ "babel-preset-stage-1": "^6.24.1"
+ }
+ },
+ "babel-preset-stage-1": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-preset-stage-1/-/babel-preset-stage-1-6.24.1.tgz",
+ "integrity": "sha1-dpLNfc1oSZB+auSgqFWJz7niv7A=",
+ "dev": true,
+ "requires": {
+ "babel-plugin-transform-class-constructor-call": "^6.24.1",
+ "babel-plugin-transform-export-extensions": "^6.22.0",
+ "babel-preset-stage-2": "^6.24.1"
+ }
+ },
+ "babel-preset-stage-2": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz",
+ "integrity": "sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE=",
+ "dev": true,
+ "requires": {
+ "babel-plugin-syntax-dynamic-import": "^6.18.0",
+ "babel-plugin-transform-class-properties": "^6.24.1",
+ "babel-plugin-transform-decorators": "^6.24.1",
+ "babel-preset-stage-3": "^6.24.1"
+ }
+ },
+ "babel-preset-stage-3": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz",
+ "integrity": "sha1-g2raCp56f6N8sTj7kyb4eTSkg5U=",
+ "dev": true,
+ "requires": {
+ "babel-plugin-syntax-trailing-function-commas": "^6.22.0",
+ "babel-plugin-transform-async-generator-functions": "^6.24.1",
+ "babel-plugin-transform-async-to-generator": "^6.24.1",
+ "babel-plugin-transform-exponentiation-operator": "^6.24.1",
+ "babel-plugin-transform-object-rest-spread": "^6.22.0"
+ }
+ },
+ "babel-register": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz",
+ "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=",
+ "dev": true,
+ "requires": {
+ "babel-core": "^6.26.0",
+ "babel-runtime": "^6.26.0",
+ "core-js": "^2.5.0",
+ "home-or-tmp": "^2.0.0",
+ "lodash": "^4.17.4",
+ "mkdirp": "^0.5.1",
+ "source-map-support": "^0.4.15"
+ }
+ },
+ "babel-runtime": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
+ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
+ "requires": {
+ "core-js": "^2.4.0",
+ "regenerator-runtime": "^0.11.0"
+ }
+ },
+ "babel-template": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz",
+ "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.26.0",
+ "babel-traverse": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "babylon": "^6.18.0",
+ "lodash": "^4.17.4"
+ }
+ },
+ "babel-traverse": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz",
+ "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=",
+ "dev": true,
+ "requires": {
+ "babel-code-frame": "^6.26.0",
+ "babel-messages": "^6.23.0",
+ "babel-runtime": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "babylon": "^6.18.0",
+ "debug": "^2.6.8",
+ "globals": "^9.18.0",
+ "invariant": "^2.2.2",
+ "lodash": "^4.17.4"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ }
+ }
+ },
+ "babel-types": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
+ "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.26.0",
+ "esutils": "^2.0.2",
+ "lodash": "^4.17.4",
+ "to-fast-properties": "^1.0.3"
+ }
+ },
+ "babylon": {
+ "version": "6.18.0",
+ "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
+ "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ=="
+ },
+ "backbone": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/backbone/-/backbone-1.3.3.tgz",
+ "integrity": "sha1-TMgOp8sWMaxHSInOQPL4vGg7KZk=",
+ "requires": {
+ "underscore": ">=1.8.3"
+ }
+ },
+ "backo2": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
+ "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=",
+ "dev": true
+ },
+ "balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+ },
+ "base": {
+ "version": "0.11.2",
+ "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+ "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+ "dev": true,
+ "requires": {
+ "cache-base": "^1.0.1",
+ "class-utils": "^0.3.5",
+ "component-emitter": "^1.2.1",
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.1",
+ "mixin-deep": "^1.2.0",
+ "pascalcase": "^0.1.1"
+ },
+ "dependencies": {
+ "component-emitter": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+ "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
+ "dev": true
+ },
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+ "dev": true
+ }
+ }
+ },
+ "base64-arraybuffer": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz",
+ "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=",
+ "dev": true
+ },
+ "base64-js": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz",
+ "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==",
+ "dev": true
+ },
+ "base64id": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz",
+ "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=",
+ "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"
+ }
+ },
+ "better-assert": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz",
+ "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=",
+ "dev": true,
+ "requires": {
+ "callsite": "1.0.0"
+ }
+ },
+ "big.js": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz",
+ "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==",
+ "dev": true
+ },
+ "binary-extensions": {
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz",
+ "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=",
+ "dev": true
+ },
+ "bindings": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
+ "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
+ "optional": true,
+ "requires": {
+ "file-uri-to-path": "1.0.0"
+ }
+ },
+ "bl": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
+ "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==",
+ "optional": true,
+ "requires": {
+ "readable-stream": "^2.3.5",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "blob": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz",
+ "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=",
+ "dev": true
+ },
+ "block-stream": {
+ "version": "0.0.9",
+ "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
+ "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
+ "dev": true,
+ "requires": {
+ "inherits": "~2.0.0"
+ }
+ },
+ "bluebird": {
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.2.tgz",
+ "integrity": "sha512-dhHTWMI7kMx5whMQntl7Vr9C6BvV10lFXDAasnqnrMYhXVCzzk6IO9Fo2L75jXHT07WrOngL1WDXOp+yYS91Yg==",
+ "dev": true
+ },
+ "blueimp-canvas-to-blob": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/blueimp-canvas-to-blob/-/blueimp-canvas-to-blob-3.5.0.tgz",
+ "integrity": "sha1-VnmsMvaig1gh8MOtZhcZ/4WpI2s=",
+ "optional": true
+ },
+ "blueimp-file-upload": {
+ "version": "9.15.0",
+ "resolved": "https://registry.npmjs.org/blueimp-file-upload/-/blueimp-file-upload-9.15.0.tgz",
+ "integrity": "sha1-0kK0saLyqbunlZLmUNlvH9E3p80=",
+ "requires": {
+ "blueimp-canvas-to-blob": "3.5.0",
+ "blueimp-load-image": "2.9.0",
+ "blueimp-tmpl": "3.6.0"
+ },
+ "dependencies": {
+ "blueimp-load-image": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/blueimp-load-image/-/blueimp-load-image-2.9.0.tgz",
+ "integrity": "sha1-MH+kTD66gaT/CnEXzUI4laAmgy0=",
+ "optional": true
+ }
+ }
+ },
+ "blueimp-load-image": {
+ "version": "2.19.0",
+ "resolved": "https://registry.npmjs.org/blueimp-load-image/-/blueimp-load-image-2.19.0.tgz",
+ "integrity": "sha512-lc5fORHdmkGTGFW8vsr1D7pNWJA+BT0eqlhx8RpEw35VULUvEZB6tJACJXEreqbWIFJc3/jlTsGvOpf9N62WLQ=="
+ },
+ "blueimp-tmpl": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/blueimp-tmpl/-/blueimp-tmpl-3.6.0.tgz",
+ "integrity": "sha1-pJEJddBC4rwDunfw5i0E8VSKUkw=",
+ "optional": true
+ },
+ "bn.js": {
+ "version": "4.11.8",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+ "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+ "dev": true
+ },
+ "body-parser": {
+ "version": "1.18.3",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz",
+ "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=",
+ "dev": true,
+ "requires": {
+ "bytes": "3.0.0",
+ "content-type": "~1.0.4",
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "http-errors": "~1.6.3",
+ "iconv-lite": "0.4.23",
+ "on-finished": "~2.3.0",
+ "qs": "6.5.2",
+ "raw-body": "2.3.3",
+ "type-is": "~1.6.16"
+ },
+ "dependencies": {
+ "bytes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+ "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
+ "dev": true
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "iconv-lite": {
+ "version": "0.4.23",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz",
+ "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==",
+ "dev": true,
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
+ }
+ }
+ },
+ "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"
+ }
+ },
+ "boom": {
+ "version": "2.10.1",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
+ "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
+ "dev": true,
+ "requires": {
+ "hoek": "2.x.x"
+ }
+ },
+ "bootstrap-multiselect": {
+ "version": "0.9.13-1",
+ "resolved": "https://registry.npmjs.org/bootstrap-multiselect/-/bootstrap-multiselect-0.9.13-1.tgz",
+ "integrity": "sha1-LFfO4mCxjX8BpO3Z1l8l3wQl/So="
+ },
+ "bootstrap-sass": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/bootstrap-sass/-/bootstrap-sass-2.3.2.tgz",
+ "integrity": "sha1-qHu8hgYK1mLVZvyOgMlMBdiMuvk="
+ },
+ "boxen": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz",
+ "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==",
+ "dev": true,
+ "requires": {
+ "ansi-align": "^2.0.0",
+ "camelcase": "^4.0.0",
+ "chalk": "^2.0.1",
+ "cli-boxes": "^1.0.0",
+ "string-width": "^2.0.0",
+ "term-size": "^1.2.0",
+ "widest-line": "^2.0.0"
+ },
+ "dependencies": {
+ "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==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.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": "1.8.5",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
+ "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
+ "requires": {
+ "expand-range": "^1.8.1",
+ "preserve": "^0.2.0",
+ "repeat-element": "^1.1.2"
+ }
+ },
+ "brfs": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/brfs/-/brfs-1.6.1.tgz",
+ "integrity": "sha512-OfZpABRQQf+Xsmju8XE9bDjs+uU4vLREGolP7bDgcpsI17QREyZ4Bl+2KLxxx1kCgA0fAIhKQBaBYh+PEcCqYQ==",
+ "requires": {
+ "quote-stream": "^1.0.1",
+ "resolve": "^1.1.5",
+ "static-module": "^2.2.0",
+ "through2": "^2.0.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.0",
+ "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz",
+ "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=",
+ "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-package-json": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/browserify-package-json/-/browserify-package-json-1.0.1.tgz",
+ "integrity": "sha1-mN3oqlxWH9bT/km7qhArdLOW/eo="
+ },
+ "browserify-rsa": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
+ "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.1.0",
+ "randombytes": "^2.0.1"
+ }
+ },
+ "browserify-sign": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz",
+ "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.1.1",
+ "browserify-rsa": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "create-hmac": "^1.1.2",
+ "elliptic": "^6.0.0",
+ "inherits": "^2.0.1",
+ "parse-asn1": "^5.0.0"
+ }
+ },
+ "browserify-zlib": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz",
+ "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=",
+ "optional": true,
+ "requires": {
+ "pako": "~0.2.0"
+ }
+ },
+ "browserslist": {
+ "version": "1.7.7",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz",
+ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=",
+ "dev": true,
+ "requires": {
+ "caniuse-db": "^1.0.30000639",
+ "electron-to-chromium": "^1.2.7"
+ }
+ },
+ "buble": {
+ "version": "0.15.2",
+ "resolved": "https://registry.npmjs.org/buble/-/buble-0.15.2.tgz",
+ "integrity": "sha1-VH/EdIP45egXbYKqXrzLGDsC1hM=",
+ "requires": {
+ "acorn": "^3.3.0",
+ "acorn-jsx": "^3.0.1",
+ "acorn-object-spread": "^1.0.0",
+ "chalk": "^1.1.3",
+ "magic-string": "^0.14.0",
+ "minimist": "^1.2.0",
+ "os-homedir": "^1.0.1"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
+ "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo="
+ },
+ "magic-string": {
+ "version": "0.14.0",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.14.0.tgz",
+ "integrity": "sha1-VyJK7xcByu7Sc7F6OalW5ysXJGI=",
+ "requires": {
+ "vlq": "^0.2.1"
+ }
+ },
+ "minimist": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
+ }
+ }
+ },
+ "bubleify": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/bubleify/-/bubleify-0.7.0.tgz",
+ "integrity": "sha1-0I6mQv/Qhf+HEciEP1cHLw1euPY=",
+ "requires": {
+ "buble": "^0.15.1",
+ "object-assign": "^4.0.1"
+ }
+ },
+ "buffer": {
+ "version": "4.9.1",
+ "resolved": "http://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
+ "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
+ "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==",
+ "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=="
+ },
+ "buffer-equal": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz",
+ "integrity": "sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs="
+ },
+ "buffer-fill": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz",
+ "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw="
+ },
+ "buffer-from": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
+ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
+ },
+ "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
+ },
+ "builtin-modules": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
+ "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8="
+ },
+ "builtin-status-codes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
+ "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=",
+ "dev": true
+ },
+ "bytes": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.5.0.tgz",
+ "integrity": "sha1-TJQj6i0lLCcMQbK97+/5u2tiwGo=",
+ "optional": true
+ },
+ "cache-base": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+ "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+ "dev": true,
+ "requires": {
+ "collection-visit": "^1.0.0",
+ "component-emitter": "^1.2.1",
+ "get-value": "^2.0.6",
+ "has-value": "^1.0.0",
+ "isobject": "^3.0.1",
+ "set-value": "^2.0.0",
+ "to-object-path": "^0.3.0",
+ "union-value": "^1.0.0",
+ "unset-value": "^1.0.0"
+ },
+ "dependencies": {
+ "component-emitter": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+ "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
+ "dev": true
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ }
+ }
+ },
+ "call-matcher": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/call-matcher/-/call-matcher-1.1.0.tgz",
+ "integrity": "sha512-IoQLeNwwf9KTNbtSA7aEBb1yfDbdnzwjCetjkC8io5oGeOmK2CBNdg0xr+tadRYKO0p7uQyZzvon0kXlZbvGrw==",
+ "requires": {
+ "core-js": "^2.0.0",
+ "deep-equal": "^1.0.0",
+ "espurify": "^1.6.0",
+ "estraverse": "^4.0.0"
+ }
+ },
+ "caller-path": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz",
+ "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=",
+ "dev": true,
+ "requires": {
+ "callsites": "^0.2.0"
+ }
+ },
+ "callsite": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
+ "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=",
+ "dev": true
+ },
+ "callsites": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz",
+ "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=",
+ "dev": true
+ },
+ "camelcase": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+ "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0="
+ },
+ "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": "1.6.1",
+ "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-1.6.1.tgz",
+ "integrity": "sha1-tTTnxzTE+B7F++isoq0kNUuWLGw=",
+ "dev": true,
+ "requires": {
+ "browserslist": "^1.3.6",
+ "caniuse-db": "^1.0.30000529",
+ "lodash.memoize": "^4.1.2",
+ "lodash.uniq": "^4.5.0"
+ }
+ },
+ "caniuse-db": {
+ "version": "1.0.30000884",
+ "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000884.tgz",
+ "integrity": "sha512-jVcZPhqrsyohOBAoYpf87mfKIL80XtQH9B1XQ3Ac8nMUKGld+QuFtc+ZaXKAUlE9o8vYLlUAooihB30VRPu0rA==",
+ "dev": true
+ },
+ "capture-stack-trace": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz",
+ "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==",
+ "dev": true
+ },
+ "cardinal": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-0.4.4.tgz",
+ "integrity": "sha1-ylu2iltRG5D+k7ms6km97lwyv+I=",
+ "requires": {
+ "ansicolors": "~0.2.1",
+ "redeyed": "~0.4.0"
+ }
+ },
+ "caseless": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
+ },
+ "center-align": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
+ "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
+ "dev": true,
+ "requires": {
+ "align-text": "^0.1.3",
+ "lazy-cache": "^1.0.3"
+ }
+ },
+ "chai": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/chai/-/chai-3.5.0.tgz",
+ "integrity": "sha1-TQJjewZ/6Vi9v906QOxW/vc3Mkc=",
+ "dev": true,
+ "requires": {
+ "assertion-error": "^1.0.1",
+ "deep-eql": "^0.1.3",
+ "type-detect": "^1.0.0"
+ }
+ },
+ "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"
+ }
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "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"
+ }
+ },
+ "chardet": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz",
+ "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I="
+ },
+ "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": "1.7.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz",
+ "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=",
+ "dev": true,
+ "requires": {
+ "anymatch": "^1.3.0",
+ "async-each": "^1.0.0",
+ "fsevents": "^1.0.0",
+ "glob-parent": "^2.0.0",
+ "inherits": "^2.0.1",
+ "is-binary-path": "^1.0.0",
+ "is-glob": "^2.0.0",
+ "path-is-absolute": "^1.0.0",
+ "readdirp": "^2.0.0"
+ }
+ },
+ "chownr": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz",
+ "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=",
+ "optional": true
+ },
+ "ci-info": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.4.0.tgz",
+ "integrity": "sha512-Oqmw2pVfCl8sCL+1QgMywPfdxPJPkC51y4usw0iiE2S9qnEOAqXy8bwl1CpMpnoU39g4iKJTz6QZj+28FvOnjQ=="
+ },
+ "cint": {
+ "version": "8.2.1",
+ "resolved": "https://registry.npmjs.org/cint/-/cint-8.2.1.tgz",
+ "integrity": "sha1-cDhrG0jidz0NYxZqVa/5TvRFahI=",
+ "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-json": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
+ "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==",
+ "dev": true
+ },
+ "clap": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/clap/-/clap-1.2.3.tgz",
+ "integrity": "sha512-4CoL/A3hf90V3VIEjeuhSvlGFEHKzOz+Wfc2IVZc+FaUgU0ZQafJTP49fvnULipOPcAfqhyI2duwQyns6xqjYA==",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.1.3"
+ }
+ },
+ "class-utils": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+ "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+ "dev": true,
+ "requires": {
+ "arr-union": "^3.1.0",
+ "define-property": "^0.2.5",
+ "isobject": "^3.0.0",
+ "static-extend": "^0.1.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ }
+ }
+ },
+ "cli-boxes": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz",
+ "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=",
+ "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-table": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz",
+ "integrity": "sha1-9TsFJmqLGguTSz0IIebi3FkUriM=",
+ "dev": true,
+ "requires": {
+ "colors": "1.0.3"
+ },
+ "dependencies": {
+ "colors": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
+ "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=",
+ "dev": true
+ }
+ }
+ },
+ "cli-width": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
+ "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk="
+ },
+ "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"
+ },
+ "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"
+ }
+ },
+ "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"
+ }
+ }
+ }
+ },
+ "clone": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
+ "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=",
+ "dev": true
+ },
+ "clone-deep": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-2.0.2.tgz",
+ "integrity": "sha512-SZegPTKjCgpQH63E+eN6mVEEPdQBOUzjyJm5Pora4lrwWRFS8I0QAxV/KD6vV/i0WuijHZWQC1fMsPEdxfdVCQ==",
+ "dev": true,
+ "requires": {
+ "for-own": "^1.0.0",
+ "is-plain-object": "^2.0.4",
+ "kind-of": "^6.0.0",
+ "shallow-clone": "^1.0.0"
+ },
+ "dependencies": {
+ "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"
+ }
+ },
+ "kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true
+ }
+ }
+ },
+ "cmd-shim": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-2.0.2.tgz",
+ "integrity": "sha1-b8vamUg6j9FdfTChlspp1oii79s=",
+ "optional": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "mkdirp": "~0.5.0"
+ }
+ },
+ "co": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+ "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
+ },
+ "coa": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/coa/-/coa-1.0.4.tgz",
+ "integrity": "sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0=",
+ "dev": true,
+ "requires": {
+ "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=",
+ "dev": true
+ },
+ "collection-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+ "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+ "dev": true,
+ "requires": {
+ "map-visit": "^1.0.0",
+ "object-visit": "^1.0.0"
+ }
+ },
+ "color": {
+ "version": "0.11.4",
+ "resolved": "https://registry.npmjs.org/color/-/color-0.11.4.tgz",
+ "integrity": "sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q=",
+ "dev": true,
+ "requires": {
+ "clone": "^1.0.2",
+ "color-convert": "^1.3.0",
+ "color-string": "^0.3.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": "0.3.0",
+ "resolved": "https://registry.npmjs.org/color-string/-/color-string-0.3.0.tgz",
+ "integrity": "sha1-J9RvtnAlxcL6JZk7+/V55HhBuZE=",
+ "dev": true,
+ "requires": {
+ "color-name": "^1.0.0"
+ }
+ },
+ "colormin": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/colormin/-/colormin-1.1.2.tgz",
+ "integrity": "sha1-6i90IKcrlogaOKrlnsEkpvcpgTM=",
+ "dev": true,
+ "requires": {
+ "color": "^0.11.0",
+ "css-color-names": "0.0.4",
+ "has": "^1.0.1"
+ }
+ },
+ "colors": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
+ "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=",
+ "dev": true
+ },
+ "combine-lists": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/combine-lists/-/combine-lists-1.0.1.tgz",
+ "integrity": "sha1-RYwH4J4NkA/Ci3Cj/sLazR0st/Y=",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.5.0"
+ }
+ },
+ "combined-stream": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz",
+ "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
+ "requires": {
+ "delayed-stream": "~1.0.0"
+ }
+ },
+ "commander": {
+ "version": "2.17.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
+ "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg=="
+ },
+ "commondir": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
+ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
+ "dev": true
+ },
+ "component-bind": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
+ "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=",
+ "dev": true
+ },
+ "component-emitter": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.1.2.tgz",
+ "integrity": "sha1-KWWU8nU9qmOZbSrwjRWpURbJrsM=",
+ "dev": true
+ },
+ "component-inherit": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz",
+ "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=",
+ "dev": true
+ },
+ "compressible": {
+ "version": "2.0.17",
+ "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.17.tgz",
+ "integrity": "sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw==",
+ "dev": true,
+ "requires": {
+ "mime-db": ">= 1.40.0 < 2"
+ },
+ "dependencies": {
+ "mime-db": {
+ "version": "1.40.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
+ "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==",
+ "dev": true
+ }
+ }
+ },
+ "compression": {
+ "version": "1.7.4",
+ "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz",
+ "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==",
+ "dev": true,
+ "requires": {
+ "accepts": "~1.3.5",
+ "bytes": "3.0.0",
+ "compressible": "~2.0.16",
+ "debug": "2.6.9",
+ "on-headers": "~1.0.2",
+ "safe-buffer": "5.1.2",
+ "vary": "~1.1.2"
+ },
+ "dependencies": {
+ "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"
+ }
+ },
+ "bytes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+ "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
+ "dev": true
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "mime-db": {
+ "version": "1.40.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
+ "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==",
+ "dev": true
+ },
+ "mime-types": {
+ "version": "2.1.24",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz",
+ "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==",
+ "dev": true,
+ "requires": {
+ "mime-db": "1.40.0"
+ }
+ },
+ "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
+ }
+ }
+ },
+ "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"
+ }
+ },
+ "concaveman": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/concaveman/-/concaveman-1.1.1.tgz",
+ "integrity": "sha1-bCSCWAslI874L8K+wAoEFebmgWI=",
+ "requires": {
+ "monotone-convex-hull-2d": "^1.0.1",
+ "point-in-polygon": "^1.0.1",
+ "rbush": "^2.0.1",
+ "robust-orientation": "^1.1.3",
+ "tinyqueue": "^1.1.0"
+ }
+ },
+ "configstore": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz",
+ "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==",
+ "dev": true,
+ "requires": {
+ "dot-prop": "^4.1.0",
+ "graceful-fs": "^4.1.2",
+ "make-dir": "^1.0.0",
+ "unique-string": "^1.0.0",
+ "write-file-atomic": "^2.0.0",
+ "xdg-basedir": "^3.0.0"
+ }
+ },
+ "connect": {
+ "version": "3.6.6",
+ "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz",
+ "integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.9",
+ "finalhandler": "1.1.0",
+ "parseurl": "~1.3.2",
+ "utils-merge": "1.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"
+ }
+ }
+ }
+ },
+ "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.1.0",
+ "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz",
+ "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=",
+ "dev": true,
+ "requires": {
+ "date-now": "^0.1.4"
+ }
+ },
+ "console-control-strings": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
+ "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
+ "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
+ },
+ "contains-path": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz",
+ "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=",
+ "dev": true
+ },
+ "content-disposition": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
+ "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=",
+ "dev": true
+ },
+ "content-type": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
+ "dev": true
+ },
+ "convert-source-map": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz",
+ "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==",
+ "requires": {
+ "safe-buffer": "~5.1.1"
+ }
+ },
+ "cookie": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
+ "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=",
+ "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-descriptor": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+ "dev": true
+ },
+ "core-js": {
+ "version": "2.5.7",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz",
+ "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw=="
+ },
+ "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="
+ },
+ "corslite": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/corslite/-/corslite-0.0.6.tgz",
+ "integrity": "sha1-YilU4UwzhSEjxMaPo97/qeLRyJY="
+ },
+ "cosmiconfig": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.2.2.tgz",
+ "integrity": "sha512-GiNXLwAFPYHy25XmTPpafYvn3CLAkJ8FLsscq78MQd1Kh0OU6Yzhn4eV2MVF4G9WEQZoWEGltatdR+ntGPMl5A==",
+ "dev": true,
+ "requires": {
+ "is-directory": "^0.3.1",
+ "js-yaml": "^3.4.3",
+ "minimist": "^1.2.0",
+ "object-assign": "^4.1.0",
+ "os-homedir": "^1.0.1",
+ "parse-json": "^2.2.0",
+ "require-from-string": "^1.1.0"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+ "dev": true
+ },
+ "require-from-string": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz",
+ "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=",
+ "dev": true
+ }
+ }
+ },
+ "coveralls": {
+ "version": "2.13.3",
+ "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-2.13.3.tgz",
+ "integrity": "sha512-iiAmn+l1XqRwNLXhW8Rs5qHZRFMYp9ZIPjEOVRpC/c4so6Y/f4/lFi0FfR5B9cCqgyhkJ5cZmbvcVRfP8MHchw==",
+ "dev": true,
+ "requires": {
+ "js-yaml": "3.6.1",
+ "lcov-parse": "0.0.10",
+ "log-driver": "1.2.5",
+ "minimist": "1.2.0",
+ "request": "2.79.0"
+ },
+ "dependencies": {
+ "assert-plus": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
+ "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
+ "dev": true
+ },
+ "aws-sign2": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
+ "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=",
+ "dev": true
+ },
+ "caseless": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz",
+ "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=",
+ "dev": true
+ },
+ "esprima": {
+ "version": "2.7.3",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
+ "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
+ "dev": true
+ },
+ "form-data": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz",
+ "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=",
+ "dev": true,
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.5",
+ "mime-types": "^2.1.12"
+ }
+ },
+ "har-validator": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz",
+ "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.1.1",
+ "commander": "^2.9.0",
+ "is-my-json-valid": "^2.12.4",
+ "pinkie-promise": "^2.0.0"
+ }
+ },
+ "http-signature": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
+ "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^0.2.0",
+ "jsprim": "^1.2.2",
+ "sshpk": "^1.7.0"
+ }
+ },
+ "js-yaml": {
+ "version": "3.6.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.6.1.tgz",
+ "integrity": "sha1-bl/mfYsgXOTSL60Ft3geja3MSzA=",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^2.6.0"
+ }
+ },
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "dev": true
+ },
+ "oauth-sign": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
+ "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
+ "dev": true
+ },
+ "punycode": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+ "dev": true
+ },
+ "qs": {
+ "version": "6.3.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz",
+ "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=",
+ "dev": true
+ },
+ "request": {
+ "version": "2.79.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz",
+ "integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=",
+ "dev": true,
+ "requires": {
+ "aws-sign2": "~0.6.0",
+ "aws4": "^1.2.1",
+ "caseless": "~0.11.0",
+ "combined-stream": "~1.0.5",
+ "extend": "~3.0.0",
+ "forever-agent": "~0.6.1",
+ "form-data": "~2.1.1",
+ "har-validator": "~2.0.6",
+ "hawk": "~3.1.3",
+ "http-signature": "~1.1.0",
+ "is-typedarray": "~1.0.0",
+ "isstream": "~0.1.2",
+ "json-stringify-safe": "~5.0.1",
+ "mime-types": "~2.1.7",
+ "oauth-sign": "~0.8.1",
+ "qs": "~6.3.0",
+ "stringstream": "~0.0.4",
+ "tough-cookie": "~2.3.0",
+ "tunnel-agent": "~0.4.1",
+ "uuid": "^3.0.0"
+ }
+ },
+ "tough-cookie": {
+ "version": "2.3.4",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz",
+ "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==",
+ "dev": true,
+ "requires": {
+ "punycode": "^1.4.1"
+ }
+ },
+ "tunnel-agent": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz",
+ "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=",
+ "dev": true
+ }
+ }
+ },
+ "create-ecdh": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz",
+ "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.1.0",
+ "elliptic": "^6.0.0"
+ }
+ },
+ "create-error-class": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz",
+ "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=",
+ "dev": true,
+ "requires": {
+ "capture-stack-trace": "^1.0.0"
+ }
+ },
+ "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": "3.0.1",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz",
+ "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^4.0.1",
+ "which": "^1.2.9"
+ }
+ },
+ "cryptiles": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
+ "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
+ "dev": true,
+ "requires": {
+ "boom": "2.x.x"
+ }
+ },
+ "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": "1.0.0",
+ "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz",
+ "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=",
+ "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"
+ }
+ },
+ "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-loader": {
+ "version": "0.28.11",
+ "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-0.28.11.tgz",
+ "integrity": "sha512-wovHgjAx8ZIMGSL8pTys7edA1ClmzxHeY6n/d97gg5odgsxEgKjULPR0viqyC+FWMCL9sfqoC/QCUBo62tLvPg==",
+ "dev": true,
+ "requires": {
+ "babel-code-frame": "^6.26.0",
+ "css-selector-tokenizer": "^0.7.0",
+ "cssnano": "^3.10.0",
+ "icss-utils": "^2.1.0",
+ "loader-utils": "^1.0.2",
+ "lodash.camelcase": "^4.3.0",
+ "object-assign": "^4.1.1",
+ "postcss": "^5.0.6",
+ "postcss-modules-extract-imports": "^1.2.0",
+ "postcss-modules-local-by-default": "^1.2.0",
+ "postcss-modules-scope": "^1.1.0",
+ "postcss-modules-values": "^1.3.0",
+ "postcss-value-parser": "^3.3.0",
+ "source-list-map": "^2.0.0"
+ }
+ },
+ "css-selector-tokenizer": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz",
+ "integrity": "sha1-5piEdK6MlTR3v15+/s/OzNnPTIY=",
+ "dev": true,
+ "requires": {
+ "cssesc": "^0.1.0",
+ "fastparse": "^1.1.1",
+ "regexpu-core": "^1.0.0"
+ },
+ "dependencies": {
+ "regexpu-core": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz",
+ "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=",
+ "dev": true,
+ "requires": {
+ "regenerate": "^1.2.1",
+ "regjsgen": "^0.2.0",
+ "regjsparser": "^0.1.4"
+ }
+ }
+ }
+ },
+ "csscolorparser": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz",
+ "integrity": "sha1-s085HupNqPPpgjHizNjfnAQfFxs="
+ },
+ "cssesc": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz",
+ "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=",
+ "dev": true
+ },
+ "cssnano": {
+ "version": "3.10.0",
+ "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz",
+ "integrity": "sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg=",
+ "dev": true,
+ "requires": {
+ "autoprefixer": "^6.3.1",
+ "decamelize": "^1.1.2",
+ "defined": "^1.0.0",
+ "has": "^1.0.1",
+ "object-assign": "^4.0.1",
+ "postcss": "^5.0.14",
+ "postcss-calc": "^5.2.0",
+ "postcss-colormin": "^2.1.8",
+ "postcss-convert-values": "^2.3.4",
+ "postcss-discard-comments": "^2.0.4",
+ "postcss-discard-duplicates": "^2.0.1",
+ "postcss-discard-empty": "^2.0.1",
+ "postcss-discard-overridden": "^0.1.1",
+ "postcss-discard-unused": "^2.2.1",
+ "postcss-filter-plugins": "^2.0.0",
+ "postcss-merge-idents": "^2.1.5",
+ "postcss-merge-longhand": "^2.0.1",
+ "postcss-merge-rules": "^2.0.3",
+ "postcss-minify-font-values": "^1.0.2",
+ "postcss-minify-gradients": "^1.0.1",
+ "postcss-minify-params": "^1.0.4",
+ "postcss-minify-selectors": "^2.0.4",
+ "postcss-normalize-charset": "^1.1.0",
+ "postcss-normalize-url": "^3.0.7",
+ "postcss-ordered-values": "^2.1.0",
+ "postcss-reduce-idents": "^2.2.2",
+ "postcss-reduce-initial": "^1.0.0",
+ "postcss-reduce-transforms": "^1.0.3",
+ "postcss-svgo": "^2.1.1",
+ "postcss-unique-selectors": "^2.0.2",
+ "postcss-value-parser": "^3.2.3",
+ "postcss-zindex": "^2.0.1"
+ }
+ },
+ "csso": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/csso/-/csso-2.3.2.tgz",
+ "integrity": "sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U=",
+ "dev": true,
+ "requires": {
+ "clap": "^1.0.9",
+ "source-map": "^0.5.3"
+ },
+ "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
+ }
+ }
+ },
+ "currently-unhandled": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
+ "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
+ "requires": {
+ "array-find-index": "^1.0.1"
+ }
+ },
+ "custom-event": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz",
+ "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=",
+ "dev": true
+ },
+ "d": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz",
+ "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=",
+ "dev": true,
+ "requires": {
+ "es5-ext": "^0.10.9"
+ }
+ },
+ "d3-array": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz",
+ "integrity": "sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw=="
+ },
+ "d3-geo": {
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.7.1.tgz",
+ "integrity": "sha512-O4AempWAr+P5qbk2bC2FuN/sDW4z+dN2wDf9QV3bxQt4M5HfOEeXLgJ/UKQW0+o1Dj8BE+L5kiDbdWUMjsmQpw==",
+ "requires": {
+ "d3-array": "1"
+ }
+ },
+ "d3-voronoi": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/d3-voronoi/-/d3-voronoi-1.1.2.tgz",
+ "integrity": "sha1-Fodmfo8TotFYyAwUgMWinLDYlzw="
+ },
+ "damerau-levenshtein": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.4.tgz",
+ "integrity": "sha1-AxkcQyy27qFou3fzpV/9zLiXhRQ=",
+ "dev": true
+ },
+ "dashdash": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+ "requires": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "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
+ },
+ "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"
+ }
+ },
+ "death": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz",
+ "integrity": "sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg=",
+ "optional": true
+ },
+ "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"
+ }
+ },
+ "decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+ "dev": true
+ },
+ "decode-uri-component": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
+ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
+ "dev": true
+ },
+ "deep-eql": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz",
+ "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=",
+ "dev": true,
+ "requires": {
+ "type-detect": "0.1.1"
+ },
+ "dependencies": {
+ "type-detect": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz",
+ "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=",
+ "dev": true
+ }
+ }
+ },
+ "deep-equal": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz",
+ "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU="
+ },
+ "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
+ },
+ "deep-is": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ="
+ },
+ "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==",
+ "requires": {
+ "object-keys": "^1.0.12"
+ }
+ },
+ "define-property": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.2",
+ "isobject": "^3.0.1"
+ },
+ "dependencies": {
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true
+ }
+ }
+ },
+ "defined": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
+ "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=",
+ "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="
+ },
+ "delegates": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
+ "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
+ "dev": true
+ },
+ "density-clustering": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/density-clustering/-/density-clustering-1.3.0.tgz",
+ "integrity": "sha1-3J9ZyPCrl+FiSsZJMP0xlIF9ysU="
+ },
+ "depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+ "dev": true
+ },
+ "des.js": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz",
+ "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=",
+ "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-indent": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz",
+ "integrity": "sha1-OHHMCmoALow+Wzz38zYmRnXwa50=",
+ "optional": true
+ },
+ "detect-node": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz",
+ "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==",
+ "dev": true
+ },
+ "di": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz",
+ "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=",
+ "dev": true
+ },
+ "diff": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz",
+ "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=",
+ "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"
+ }
+ },
+ "dns-equal": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
+ "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=",
+ "dev": true
+ },
+ "dns-packet": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz",
+ "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==",
+ "dev": true,
+ "requires": {
+ "ip": "^1.1.0",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "dns-txt": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz",
+ "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=",
+ "dev": true,
+ "requires": {
+ "buffer-indexof": "^1.0.0"
+ }
+ },
+ "doctrine": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+ "dev": true,
+ "requires": {
+ "esutils": "^2.0.2"
+ }
+ },
+ "dom-serialize": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz",
+ "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=",
+ "dev": true,
+ "requires": {
+ "custom-event": "~1.0.0",
+ "ent": "~2.2.0",
+ "extend": "^3.0.0",
+ "void-elements": "^2.0.0"
+ }
+ },
+ "dom-walk": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz",
+ "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg="
+ },
+ "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
+ },
+ "dot-prop": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz",
+ "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==",
+ "dev": true,
+ "requires": {
+ "is-obj": "^1.0.0"
+ }
+ },
+ "dotenv": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-4.0.0.tgz",
+ "integrity": "sha1-hk7xN5rO1Vzm+V3r7NzhefegzR0=",
+ "dev": true
+ },
+ "duplexer": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
+ "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
+ "dev": true
+ },
+ "duplexer2": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
+ "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=",
+ "requires": {
+ "readable-stream": "^2.0.2"
+ }
+ },
+ "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.6.0",
+ "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.0.tgz",
+ "integrity": "sha512-fO3Di4tBKJpYTFHAxTU00BcfWMY9w24r/x21a6rZRbsD/ToUgGxsMbiGRmB7uVAXeGKXD9MwiLZa5E97EVgIRQ==",
+ "optional": true,
+ "requires": {
+ "end-of-stream": "^1.0.0",
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.0",
+ "stream-shift": "^1.0.0"
+ }
+ },
+ "earcut": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.1.3.tgz",
+ "integrity": "sha512-AxdCdWUk1zzK/NuZ7e1ljj6IGC+VAdC3Qb7QQDsXpfNrc5IM8tL9nNXUmEGE6jRHTfZ10zhzRhtDmWVsR5pd3A=="
+ },
+ "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"
+ }
+ },
+ "ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
+ "dev": true
+ },
+ "electron-to-chromium": {
+ "version": "1.3.62",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.62.tgz",
+ "integrity": "sha512-x09ndL/Gjnuk3unlAyoGyUg3wbs4w/bXurgL7wL913vXHAOWmMhrLf1VNGRaMLngmadd5Q8gsV9BFuIr6rP+Xg==",
+ "dev": true
+ },
+ "elliptic": {
+ "version": "6.4.1",
+ "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz",
+ "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.4.0",
+ "brorand": "^1.0.1",
+ "hash.js": "^1.0.0",
+ "hmac-drbg": "^1.0.0",
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0",
+ "minimalistic-crypto-utils": "^1.0.0"
+ }
+ },
+ "emoji-regex": {
+ "version": "6.5.1",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.5.1.tgz",
+ "integrity": "sha512-PAHp6TxrCy7MGMFidro8uikr+zlJJKJ/Q6mm2ExZ7HwkyR9lSVFfE3kt36qcwa24BQL7y0G9axycGjK1A/0uNQ==",
+ "dev": true
+ },
+ "emojis-list": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz",
+ "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=",
+ "dev": true
+ },
+ "encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
+ "dev": true
+ },
+ "end-of-stream": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
+ "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
+ "optional": true,
+ "requires": {
+ "once": "^1.4.0"
+ }
+ },
+ "engine.io": {
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-1.8.3.tgz",
+ "integrity": "sha1-jef5eJXSDTm4X4ju7nd7K9QrE9Q=",
+ "dev": true,
+ "requires": {
+ "accepts": "1.3.3",
+ "base64id": "1.0.0",
+ "cookie": "0.3.1",
+ "debug": "2.3.3",
+ "engine.io-parser": "1.3.2",
+ "ws": "1.1.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
+ "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=",
+ "dev": true,
+ "requires": {
+ "ms": "0.7.2"
+ }
+ },
+ "ms": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
+ "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=",
+ "dev": true
+ }
+ }
+ },
+ "engine.io-client": {
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-1.8.3.tgz",
+ "integrity": "sha1-F5jtk0USRkU9TG9jXXogH+lA1as=",
+ "dev": true,
+ "requires": {
+ "component-emitter": "1.2.1",
+ "component-inherit": "0.0.3",
+ "debug": "2.3.3",
+ "engine.io-parser": "1.3.2",
+ "has-cors": "1.1.0",
+ "indexof": "0.0.1",
+ "parsejson": "0.0.3",
+ "parseqs": "0.0.5",
+ "parseuri": "0.0.5",
+ "ws": "1.1.2",
+ "xmlhttprequest-ssl": "1.5.3",
+ "yeast": "0.1.2"
+ },
+ "dependencies": {
+ "component-emitter": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+ "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
+ "dev": true
+ },
+ "debug": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
+ "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=",
+ "dev": true,
+ "requires": {
+ "ms": "0.7.2"
+ }
+ },
+ "ms": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
+ "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=",
+ "dev": true
+ }
+ }
+ },
+ "engine.io-parser": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-1.3.2.tgz",
+ "integrity": "sha1-k3sHnwAH0Ik+xW1GyyILjLQ1Igo=",
+ "dev": true,
+ "requires": {
+ "after": "0.8.2",
+ "arraybuffer.slice": "0.0.6",
+ "base64-arraybuffer": "0.1.5",
+ "blob": "0.0.4",
+ "has-binary": "0.1.7",
+ "wtf-8": "1.0.0"
+ }
+ },
+ "enhanced-resolve": {
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz",
+ "integrity": "sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "memory-fs": "^0.4.0",
+ "object-assign": "^4.0.1",
+ "tapable": "^0.2.7"
+ }
+ },
+ "ent": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz",
+ "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=",
+ "dev": true
+ },
+ "errno": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
+ "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==",
+ "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.12.0",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz",
+ "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==",
+ "requires": {
+ "es-to-primitive": "^1.1.1",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.1",
+ "is-callable": "^1.1.3",
+ "is-regex": "^1.0.4"
+ }
+ },
+ "es-to-primitive": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz",
+ "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=",
+ "requires": {
+ "is-callable": "^1.1.1",
+ "is-date-object": "^1.0.1",
+ "is-symbol": "^1.0.1"
+ }
+ },
+ "es5-ext": {
+ "version": "0.10.46",
+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.46.tgz",
+ "integrity": "sha512-24XxRvJXNFwEMpJb3nOkiRJKRoupmjYmOPVlI65Qy2SrtxwOTB+g6ODjBKOtwEHbYrhWRty9xxOWLNdClT2djw==",
+ "dev": true,
+ "requires": {
+ "es6-iterator": "~2.0.3",
+ "es6-symbol": "~3.1.1",
+ "next-tick": "1"
+ }
+ },
+ "es5-shim": {
+ "version": "4.5.13",
+ "resolved": "https://registry.npmjs.org/es5-shim/-/es5-shim-4.5.13.tgz",
+ "integrity": "sha512-xi6hh6gsvDE0MaW4Vp1lgNEBpVcCXRWfPXj5egDvtgLz4L9MEvNwYEMdJH+JJinWkwa8c3c3o5HduV7dB/e1Hw=="
+ },
+ "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-map": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz",
+ "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=",
+ "dev": true,
+ "requires": {
+ "d": "1",
+ "es5-ext": "~0.10.14",
+ "es6-iterator": "~2.0.1",
+ "es6-set": "~0.1.5",
+ "es6-symbol": "~3.1.1",
+ "event-emitter": "~0.3.5"
+ }
+ },
+ "es6-promise": {
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz",
+ "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ=="
+ },
+ "es6-set": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz",
+ "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=",
+ "dev": true,
+ "requires": {
+ "d": "1",
+ "es5-ext": "~0.10.14",
+ "es6-iterator": "~2.0.1",
+ "es6-symbol": "3.1.1",
+ "event-emitter": "~0.3.5"
+ }
+ },
+ "es6-symbol": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
+ "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=",
+ "dev": true,
+ "requires": {
+ "d": "1",
+ "es5-ext": "~0.10.14"
+ }
+ },
+ "es6-weak-map": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz",
+ "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=",
+ "dev": true,
+ "requires": {
+ "d": "1",
+ "es5-ext": "^0.10.14",
+ "es6-iterator": "^2.0.1",
+ "es6-symbol": "^3.1.1"
+ }
+ },
+ "escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
+ "dev": true
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
+ },
+ "escodegen": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.1.tgz",
+ "integrity": "sha512-6hTjO1NAWkHnDk3OqQ4YrCuwwmGHL9S3nPlzBOUG/R44rda3wLNrfvQ5fkSGjyhHFKM7ALPKcKGrwvCLe0lC7Q==",
+ "requires": {
+ "esprima": "^3.1.3",
+ "estraverse": "^4.2.0",
+ "esutils": "^2.0.2",
+ "optionator": "^0.8.1",
+ "source-map": "~0.6.1"
+ },
+ "dependencies": {
+ "esprima": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz",
+ "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM="
+ }
+ }
+ },
+ "escope": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz",
+ "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=",
+ "dev": true,
+ "requires": {
+ "es6-map": "^0.1.3",
+ "es6-weak-map": "^2.0.1",
+ "esrecurse": "^4.1.0",
+ "estraverse": "^4.1.1"
+ }
+ },
+ "eslint": {
+ "version": "4.18.2",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.18.2.tgz",
+ "integrity": "sha512-qy4i3wODqKMYfz9LUI8N2qYDkHkoieTbiHpMrYUI/WbjhXJQr7lI4VngixTgaG+yHX+NBCv7nW4hA0ShbvaNKw==",
+ "dev": true,
+ "requires": {
+ "ajv": "^5.3.0",
+ "babel-code-frame": "^6.22.0",
+ "chalk": "^2.1.0",
+ "concat-stream": "^1.6.0",
+ "cross-spawn": "^5.1.0",
+ "debug": "^3.1.0",
+ "doctrine": "^2.1.0",
+ "eslint-scope": "^3.7.1",
+ "eslint-visitor-keys": "^1.0.0",
+ "espree": "^3.5.2",
+ "esquery": "^1.0.0",
+ "esutils": "^2.0.2",
+ "file-entry-cache": "^2.0.0",
+ "functional-red-black-tree": "^1.0.1",
+ "glob": "^7.1.2",
+ "globals": "^11.0.1",
+ "ignore": "^3.3.3",
+ "imurmurhash": "^0.1.4",
+ "inquirer": "^3.0.6",
+ "is-resolvable": "^1.0.0",
+ "js-yaml": "^3.9.1",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.3.0",
+ "lodash": "^4.17.4",
+ "minimatch": "^3.0.2",
+ "mkdirp": "^0.5.1",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.8.2",
+ "path-is-inside": "^1.0.2",
+ "pluralize": "^7.0.0",
+ "progress": "^2.0.0",
+ "require-uncached": "^1.0.3",
+ "semver": "^5.3.0",
+ "strip-ansi": "^4.0.0",
+ "strip-json-comments": "~2.0.1",
+ "table": "4.0.2",
+ "text-table": "~0.2.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ },
+ "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==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "cross-spawn": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
+ "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^4.0.1",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ }
+ },
+ "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
+ },
+ "progress": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "eslint-config-airbnb": {
+ "version": "15.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-15.1.0.tgz",
+ "integrity": "sha512-m0q9fiMBzDAIbirlGnpJNWToIhdhJmXXnMG+IFflYzzod9231ZhtmGKegKg8E9T8F1YuVaDSU1FnCm5b9iXVhQ==",
+ "dev": true,
+ "requires": {
+ "eslint-config-airbnb-base": "^11.3.0"
+ }
+ },
+ "eslint-config-airbnb-base": {
+ "version": "11.3.2",
+ "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-11.3.2.tgz",
+ "integrity": "sha512-/fhjt/VqzBA2SRsx7ErDtv6Ayf+XLw9LIOqmpBuHFCVwyJo2EtzGWMB9fYRFBoWWQLxmNmCpenNiH0RxyeS41w==",
+ "dev": true,
+ "requires": {
+ "eslint-restricted-globals": "^0.1.1"
+ }
+ },
+ "eslint-import-resolver-node": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz",
+ "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==",
+ "dev": true,
+ "requires": {
+ "debug": "^2.6.9",
+ "resolve": "^1.5.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ }
+ }
+ },
+ "eslint-loader": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-1.9.0.tgz",
+ "integrity": "sha512-40aN976qSNPyb9ejTqjEthZITpls1SVKtwguahmH1dzGCwQU/vySE+xX33VZmD8csU0ahVNCtFlsPgKqRBiqgg==",
+ "dev": true,
+ "requires": {
+ "loader-fs-cache": "^1.0.0",
+ "loader-utils": "^1.0.2",
+ "object-assign": "^4.0.1",
+ "object-hash": "^1.1.4",
+ "rimraf": "^2.6.1"
+ }
+ },
+ "eslint-module-utils": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz",
+ "integrity": "sha1-snA2LNiLGkitMIl2zn+lTphBF0Y=",
+ "dev": true,
+ "requires": {
+ "debug": "^2.6.8",
+ "pkg-dir": "^1.0.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "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"
+ }
+ },
+ "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"
+ }
+ },
+ "pkg-dir": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz",
+ "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=",
+ "dev": true,
+ "requires": {
+ "find-up": "^1.0.0"
+ }
+ }
+ }
+ },
+ "eslint-plugin-import": {
+ "version": "2.12.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.12.0.tgz",
+ "integrity": "sha1-2tMXgSktZmSyUxf9BJ0uKy8CIF0=",
+ "dev": true,
+ "requires": {
+ "contains-path": "^0.1.0",
+ "debug": "^2.6.8",
+ "doctrine": "1.5.0",
+ "eslint-import-resolver-node": "^0.3.1",
+ "eslint-module-utils": "^2.2.0",
+ "has": "^1.0.1",
+ "lodash": "^4.17.4",
+ "minimatch": "^3.0.3",
+ "read-pkg-up": "^2.0.0",
+ "resolve": "^1.6.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "doctrine": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
+ "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=",
+ "dev": true,
+ "requires": {
+ "esutils": "^2.0.2",
+ "isarray": "^1.0.0"
+ }
+ }
+ }
+ },
+ "eslint-plugin-jsx-a11y": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-5.1.1.tgz",
+ "integrity": "sha512-5I9SpoP7gT4wBFOtXT8/tXNPYohHBVfyVfO17vkbC7r9kEIxYJF12D3pKqhk8+xnk12rfxKClS3WCFpVckFTPQ==",
+ "dev": true,
+ "requires": {
+ "aria-query": "^0.7.0",
+ "array-includes": "^3.0.3",
+ "ast-types-flow": "0.0.7",
+ "axobject-query": "^0.1.0",
+ "damerau-levenshtein": "^1.0.0",
+ "emoji-regex": "^6.1.0",
+ "jsx-ast-utils": "^1.4.0"
+ }
+ },
+ "eslint-plugin-react": {
+ "version": "7.9.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.9.1.tgz",
+ "integrity": "sha512-uvq+2ZkiqzjwF+pMZ8xqIC3pChV4KviPvvPIyQOvKWnjtvyW3iGfHIRqVumw05L3itby0QGmA4VdBA9m1OdMmg==",
+ "dev": true,
+ "requires": {
+ "doctrine": "^2.1.0",
+ "has": "^1.0.2",
+ "jsx-ast-utils": "^2.0.1",
+ "prop-types": "^15.6.1"
+ },
+ "dependencies": {
+ "jsx-ast-utils": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz",
+ "integrity": "sha1-6AGxs5mF4g//yHtA43SAgOLcrH8=",
+ "dev": true,
+ "requires": {
+ "array-includes": "^3.0.3"
+ }
+ }
+ }
+ },
+ "eslint-restricted-globals": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz",
+ "integrity": "sha1-NfDVy8ZMLj7WLpO0saevBbp+1Nc=",
+ "dev": true
+ },
+ "eslint-scope": {
+ "version": "3.7.3",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz",
+ "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==",
+ "dev": true,
+ "requires": {
+ "esrecurse": "^4.1.0",
+ "estraverse": "^4.1.1"
+ }
+ },
+ "eslint-visitor-keys": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz",
+ "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==",
+ "dev": true
+ },
+ "espree": {
+ "version": "3.5.4",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz",
+ "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==",
+ "dev": true,
+ "requires": {
+ "acorn": "^5.5.0",
+ "acorn-jsx": "^3.0.0"
+ }
+ },
+ "esprima": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz",
+ "integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0="
+ },
+ "espurify": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/espurify/-/espurify-1.8.1.tgz",
+ "integrity": "sha512-ZDko6eY/o+D/gHCWyHTU85mKDgYcS4FJj7S+YD6WIInm7GQ6AnOjmcL4+buFV/JOztVLELi/7MmuGU5NHta0Mg==",
+ "requires": {
+ "core-js": "^2.0.0"
+ }
+ },
+ "esquery": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz",
+ "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==",
+ "dev": true,
+ "requires": {
+ "estraverse": "^4.0.0"
+ }
+ },
+ "esrecurse": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
+ "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
+ "dev": true,
+ "requires": {
+ "estraverse": "^4.1.0"
+ }
+ },
+ "estraverse": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
+ "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM="
+ },
+ "esutils": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
+ "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs="
+ },
+ "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"
+ },
+ "dependencies": {
+ "split": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
+ "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
+ "dev": true,
+ "requires": {
+ "through": "2"
+ }
+ }
+ }
+ },
+ "eventemitter3": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz",
+ "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==",
+ "dev": true
+ },
+ "events": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
+ "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ="
+ },
+ "eventsource": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-0.1.6.tgz",
+ "integrity": "sha1-Cs7ehJ7X3RzMMsgRuxG5RNTykjI=",
+ "dev": true,
+ "requires": {
+ "original": ">=0.0.5"
+ }
+ },
+ "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": "0.7.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
+ "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^5.0.1",
+ "get-stream": "^3.0.0",
+ "is-stream": "^1.1.0",
+ "npm-run-path": "^2.0.0",
+ "p-finally": "^1.0.0",
+ "signal-exit": "^3.0.0",
+ "strip-eof": "^1.0.0"
+ },
+ "dependencies": {
+ "cross-spawn": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
+ "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^4.0.1",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ }
+ }
+ }
+ },
+ "expand-braces": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/expand-braces/-/expand-braces-0.1.2.tgz",
+ "integrity": "sha1-SIsdHSRRyz06axks/AMPRMWFX+o=",
+ "dev": true,
+ "requires": {
+ "array-slice": "^0.2.3",
+ "array-unique": "^0.2.1",
+ "braces": "^0.1.2"
+ },
+ "dependencies": {
+ "braces": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-0.1.5.tgz",
+ "integrity": "sha1-wIVxEIUpHYt1/ddOqw+FlygHEeY=",
+ "dev": true,
+ "requires": {
+ "expand-range": "^0.1.0"
+ }
+ },
+ "expand-range": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-0.1.1.tgz",
+ "integrity": "sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ=",
+ "dev": true,
+ "requires": {
+ "is-number": "^0.1.1",
+ "repeat-string": "^0.2.2"
+ }
+ },
+ "is-number": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-0.1.1.tgz",
+ "integrity": "sha1-aaevEWlj1HIG7JvZtIoUIW8eOAY=",
+ "dev": true
+ },
+ "repeat-string": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-0.2.2.tgz",
+ "integrity": "sha1-x6jTI2BoNiBZp+RlH8aITosftK4=",
+ "dev": true
+ }
+ }
+ },
+ "expand-brackets": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
+ "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
+ "requires": {
+ "is-posix-bracket": "^0.1.0"
+ }
+ },
+ "expand-range": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz",
+ "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=",
+ "requires": {
+ "fill-range": "^2.1.0"
+ }
+ },
+ "express": {
+ "version": "4.16.4",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz",
+ "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==",
+ "dev": true,
+ "requires": {
+ "accepts": "~1.3.5",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.18.3",
+ "content-disposition": "0.5.2",
+ "content-type": "~1.0.4",
+ "cookie": "0.3.1",
+ "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.1",
+ "fresh": "0.5.2",
+ "merge-descriptors": "1.0.1",
+ "methods": "~1.1.2",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.2",
+ "path-to-regexp": "0.1.7",
+ "proxy-addr": "~2.0.4",
+ "qs": "6.5.2",
+ "range-parser": "~1.2.0",
+ "safe-buffer": "5.1.2",
+ "send": "0.16.2",
+ "serve-static": "1.13.2",
+ "setprototypeof": "1.1.0",
+ "statuses": "~1.4.0",
+ "type-is": "~1.6.16",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
+ },
+ "dependencies": {
+ "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"
+ }
+ },
+ "array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
+ "dev": true
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "finalhandler": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
+ "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.2",
+ "statuses": "~1.4.0",
+ "unpipe": "~1.0.0"
+ }
+ },
+ "mime-db": {
+ "version": "1.40.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
+ "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==",
+ "dev": true
+ },
+ "mime-types": {
+ "version": "2.1.24",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz",
+ "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==",
+ "dev": true,
+ "requires": {
+ "mime-db": "1.40.0"
+ }
+ },
+ "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
+ },
+ "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
+ },
+ "statuses": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
+ "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==",
+ "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": "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"
+ }
+ },
+ "external-editor": {
+ "version": "2.2.0",
+ "resolved": "http://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz",
+ "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==",
+ "requires": {
+ "chardet": "^0.4.0",
+ "iconv-lite": "^0.4.17",
+ "tmp": "^0.0.33"
+ }
+ },
+ "extglob": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
+ "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
+ "requires": {
+ "is-extglob": "^1.0.0"
+ }
+ },
+ "extract-text-webpack-plugin": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.2.tgz",
+ "integrity": "sha512-bt/LZ4m5Rqt/Crl2HiKuAl/oqg0psx1tsTLkvWbJen1CtD+fftkZhMaQ9HOtY2gWsl2Wq+sABmMVi9z3DhKWQQ==",
+ "dev": true,
+ "requires": {
+ "async": "^2.4.1",
+ "loader-utils": "^1.1.0",
+ "schema-utils": "^0.3.0",
+ "webpack-sources": "^1.0.1"
+ }
+ },
+ "extract-zip": {
+ "version": "1.6.7",
+ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz",
+ "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=",
+ "dev": true,
+ "requires": {
+ "concat-stream": "1.6.2",
+ "debug": "2.6.9",
+ "mkdirp": "0.5.1",
+ "yauzl": "2.4.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"
+ }
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+ "dev": true,
+ "requires": {
+ "minimist": "0.0.8"
+ }
+ }
+ }
+ },
+ "extsprintf": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
+ },
+ "falafel": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/falafel/-/falafel-2.1.0.tgz",
+ "integrity": "sha1-lrsXdh2rqU9G0AFzizzt86Z/4Gw=",
+ "requires": {
+ "acorn": "^5.0.0",
+ "foreach": "^2.0.5",
+ "isarray": "0.0.1",
+ "object-keys": "^1.0.6"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
+ }
+ }
+ },
+ "fast-deep-equal": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
+ "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ="
+ },
+ "fast-diff": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.1.2.tgz",
+ "integrity": "sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==",
+ "dev": true
+ },
+ "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": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
+ },
+ "fastparse": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.1.tgz",
+ "integrity": "sha1-0eJkOzipTXWDtHkGDmxK/8lAcfg=",
+ "dev": true
+ },
+ "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=",
+ "dev": true,
+ "requires": {
+ "pend": "~1.2.0"
+ }
+ },
+ "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-entry-cache": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz",
+ "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=",
+ "dev": true,
+ "requires": {
+ "flat-cache": "^1.2.1",
+ "object-assign": "^4.0.1"
+ }
+ },
+ "file-loader": {
+ "version": "0.11.2",
+ "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-0.11.2.tgz",
+ "integrity": "sha512-N+uhF3mswIFeziHQjGScJ/yHXYt3DiLBeC+9vWW+WjUBiClMSOlV1YrXQi+7KM2aA3Rn4Bybgv+uXFQbfkzpvg==",
+ "dev": true,
+ "requires": {
+ "loader-utils": "^1.0.2"
+ }
+ },
+ "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
+ },
+ "filename-regex": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",
+ "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY="
+ },
+ "fill-range": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz",
+ "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==",
+ "requires": {
+ "is-number": "^2.1.0",
+ "isobject": "^2.0.0",
+ "randomatic": "^3.0.0",
+ "repeat-element": "^1.1.2",
+ "repeat-string": "^1.5.2"
+ }
+ },
+ "finalhandler": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz",
+ "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.1",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.2",
+ "statuses": "~1.3.1",
+ "unpipe": "~1.0.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "statuses": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
+ "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=",
+ "dev": true
+ }
+ }
+ },
+ "find-cache-dir": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz",
+ "integrity": "sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=",
+ "dev": true,
+ "requires": {
+ "commondir": "^1.0.1",
+ "make-dir": "^1.0.0",
+ "pkg-dir": "^2.0.0"
+ }
+ },
+ "find-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+ "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+ "dev": true,
+ "requires": {
+ "locate-path": "^2.0.0"
+ }
+ },
+ "flat-cache": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz",
+ "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==",
+ "dev": true,
+ "requires": {
+ "circular-json": "^0.3.1",
+ "graceful-fs": "^4.1.2",
+ "rimraf": "~2.6.2",
+ "write": "^0.2.1"
+ }
+ },
+ "flatten": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz",
+ "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=",
+ "dev": true
+ },
+ "flow-remove-types": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/flow-remove-types/-/flow-remove-types-1.2.3.tgz",
+ "integrity": "sha512-ypq/U3V+t9atYiOuSJd40tekCra03EHKoRsiK/wXGrsZimuum0kdwVY7Yv0HTaoXgHW1WiayomYd+Q3kkvPl9Q==",
+ "requires": {
+ "babylon": "^6.15.0",
+ "vlq": "^0.2.1"
+ }
+ },
+ "follow-redirects": {
+ "version": "1.5.7",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.7.tgz",
+ "integrity": "sha512-NONJVIFiX7Z8k2WxfqBjtwqMifx7X42ORLFrOZ2LTKGj71G3C0kfdyTqGqr8fx5zSX6Foo/D95dgGWbPUiwnew==",
+ "dev": true,
+ "requires": {
+ "debug": "^3.1.0"
+ }
+ },
+ "for-each": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
+ "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
+ "requires": {
+ "is-callable": "^1.1.3"
+ }
+ },
+ "for-in": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+ "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA="
+ },
+ "for-own": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz",
+ "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=",
+ "requires": {
+ "for-in": "^1.0.1"
+ }
+ },
+ "foreach": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
+ "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k="
+ },
+ "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.2",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz",
+ "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "1.0.6",
+ "mime-types": "^2.1.12"
+ }
+ },
+ "formatio": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/formatio/-/formatio-1.2.0.tgz",
+ "integrity": "sha1-87IWfZBoxGmKjVH092CjmlTYGOs=",
+ "dev": true,
+ "requires": {
+ "samsam": "1.x"
+ }
+ },
+ "forwarded": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+ "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
+ "dev": true
+ },
+ "fragment-cache": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+ "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+ "dev": true,
+ "requires": {
+ "map-cache": "^0.2.2"
+ }
+ },
+ "fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
+ "dev": true
+ },
+ "from": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
+ "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=",
+ "dev": true
+ },
+ "fs-access": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz",
+ "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=",
+ "dev": true,
+ "requires": {
+ "null-check": "^1.0.0"
+ }
+ },
+ "fs-constants": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
+ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
+ "optional": true
+ },
+ "fs-extra": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz",
+ "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^2.1.0",
+ "klaw": "^1.0.0"
+ }
+ },
+ "fs-readdir-recursive": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz",
+ "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==",
+ "dev": true
+ },
+ "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"
+ }
+ },
+ "fstream": {
+ "version": "1.0.12",
+ "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
+ "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "inherits": "~2.0.0",
+ "mkdirp": ">=0.5 0",
+ "rimraf": "2"
+ }
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+ },
+ "functional-red-black-tree": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+ "dev": true
+ },
+ "gauge": {
+ "version": "2.7.4",
+ "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
+ "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
+ "dev": true,
+ "requires": {
+ "aproba": "^1.0.3",
+ "console-control-strings": "^1.0.0",
+ "has-unicode": "^2.0.0",
+ "object-assign": "^4.1.0",
+ "signal-exit": "^3.0.0",
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1",
+ "wide-align": "^1.1.0"
+ },
+ "dependencies": {
+ "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"
+ }
+ },
+ "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"
+ }
+ }
+ }
+ },
+ "gaze": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz",
+ "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==",
+ "dev": true,
+ "requires": {
+ "globule": "^1.0.0"
+ }
+ },
+ "generate-function": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz",
+ "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==",
+ "dev": true,
+ "requires": {
+ "is-property": "^1.0.2"
+ }
+ },
+ "generate-object-property": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz",
+ "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=",
+ "dev": true,
+ "requires": {
+ "is-property": "^1.0.0"
+ }
+ },
+ "geojson-equality": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/geojson-equality/-/geojson-equality-0.1.6.tgz",
+ "integrity": "sha1-oXE3TvBD5dR5eZWEC65GSOB1LXI=",
+ "requires": {
+ "deep-equal": "^1.0.0"
+ }
+ },
+ "geojson-rbush": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/geojson-rbush/-/geojson-rbush-2.1.0.tgz",
+ "integrity": "sha1-O9c745H8ELCuaT2bis6iquC4Oo0=",
+ "requires": {
+ "@turf/helpers": "*",
+ "@turf/meta": "*",
+ "rbush": "*"
+ }
+ },
+ "geojson-vt": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-3.2.1.tgz",
+ "integrity": "sha512-EvGQQi/zPrDA6zr6BnJD/YhwAkBP8nnJ9emh3EnHQKVMfg/MRVtPbMYdgVy/IaEmn4UfagD2a6fafPDL5hbtwg=="
+ },
+ "geonames-server-jquery-plugin": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/geonames-server-jquery-plugin/-/geonames-server-jquery-plugin-0.2.2.tgz",
+ "integrity": "sha1-jyUknoIwV7S6pE6VkGlgclxVL8M="
+ },
+ "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
+ },
+ "get-closest": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/get-closest/-/get-closest-0.0.4.tgz",
+ "integrity": "sha1-JprHdtHmAiqg/Vht1wjop9Miaa8="
+ },
+ "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": "3.0.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+ "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
+ "dev": true
+ },
+ "get-value": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+ "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+ "dev": true
+ },
+ "getpass": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+ "requires": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "gl-matrix": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.3.0.tgz",
+ "integrity": "sha512-COb7LDz+SXaHtl/h4LeaFcNdJdAQSDeVqjiIihSXNrkWObZLhDI4hIkZC11Aeqp7bcE72clzB0BnDXr2SmslRA=="
+ },
+ "glob": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
+ "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
+ "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=",
+ "requires": {
+ "glob-parent": "^2.0.0",
+ "is-glob": "^2.0.0"
+ }
+ },
+ "glob-parent": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
+ "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
+ "requires": {
+ "is-glob": "^2.0.0"
+ }
+ },
+ "global": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz",
+ "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=",
+ "requires": {
+ "min-document": "^2.19.0",
+ "process": "~0.5.1"
+ }
+ },
+ "global-dirs": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz",
+ "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=",
+ "dev": true,
+ "requires": {
+ "ini": "^1.3.4"
+ }
+ },
+ "globals": {
+ "version": "9.18.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
+ "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
+ "dev": true
+ },
+ "globule": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.1.tgz",
+ "integrity": "sha512-OVyWOHgw29yosRHCHo7NncwR1hW5ew0W/UrvtwvjefVJeQ26q4/8r8FmPsSF1hJ93IgWkyv16pCTz6WblMzm/g==",
+ "dev": true,
+ "requires": {
+ "glob": "~7.1.1",
+ "lodash": "~4.17.12",
+ "minimatch": "~3.0.2"
+ }
+ },
+ "got": {
+ "version": "6.7.1",
+ "resolved": "http://registry.npmjs.org/got/-/got-6.7.1.tgz",
+ "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=",
+ "dev": true,
+ "requires": {
+ "create-error-class": "^3.0.0",
+ "duplexer3": "^0.1.4",
+ "get-stream": "^3.0.0",
+ "is-redirect": "^1.0.0",
+ "is-retry-allowed": "^1.0.0",
+ "is-stream": "^1.0.0",
+ "lowercase-keys": "^1.0.0",
+ "safe-buffer": "^5.0.1",
+ "timed-out": "^4.0.0",
+ "unzip-response": "^2.0.1",
+ "url-parse-lax": "^1.0.0"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.1.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg="
+ },
+ "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
+ },
+ "gray-matter": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-3.1.1.tgz",
+ "integrity": "sha512-nZ1qjLmayEv0/wt3sHig7I0s3/sJO0dkAaKYQ5YAOApUtYEOonXSFdWvL1khvnZMTvov4UufkqlFsilPnejEXA==",
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "js-yaml": "^3.10.0",
+ "kind-of": "^5.0.2",
+ "strip-bom-string": "^1.0.0"
+ }
+ },
+ "grid-index": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/grid-index/-/grid-index-1.1.0.tgz",
+ "integrity": "sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA=="
+ },
+ "growl": {
+ "version": "1.9.2",
+ "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz",
+ "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=",
+ "dev": true
+ },
+ "growly": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
+ "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=",
+ "dev": true
+ },
+ "gunzip-maybe": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/gunzip-maybe/-/gunzip-maybe-1.4.1.tgz",
+ "integrity": "sha512-qtutIKMthNJJgeHQS7kZ9FqDq59/Wn0G2HYCRNjpup7yKfVI6/eqwpmroyZGFoCYaG+sW6psNVb4zoLADHpp2g==",
+ "optional": true,
+ "requires": {
+ "browserify-zlib": "^0.1.4",
+ "is-deflate": "^1.0.0",
+ "is-gzip": "^1.0.0",
+ "peek-stream": "^1.1.0",
+ "pumpify": "^1.3.3",
+ "through2": "^2.0.3"
+ }
+ },
+ "handle-thing": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.0.tgz",
+ "integrity": "sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ==",
+ "dev": true
+ },
+ "handlebars": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.2.tgz",
+ "integrity": "sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw==",
+ "dev": true,
+ "requires": {
+ "neo-async": "^2.6.0",
+ "optimist": "^0.6.1",
+ "source-map": "^0.6.1",
+ "uglify-js": "^3.1.4"
+ },
+ "dependencies": {
+ "neo-async": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.0.tgz",
+ "integrity": "sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA==",
+ "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.0",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz",
+ "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==",
+ "requires": {
+ "ajv": "^5.3.0",
+ "har-schema": "^2.0.0"
+ }
+ },
+ "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=",
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "has-binary": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/has-binary/-/has-binary-0.1.7.tgz",
+ "integrity": "sha1-aOYesWIQyVRaClzOBqhzkS/h5ow=",
+ "dev": true,
+ "requires": {
+ "isarray": "0.0.1"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+ "dev": true
+ }
+ }
+ },
+ "has-color": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz",
+ "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8="
+ },
+ "has-cors": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz",
+ "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
+ },
+ "has-symbols": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
+ "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
+ "dev": true
+ },
+ "has-unicode": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
+ "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
+ "dev": true
+ },
+ "has-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+ "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+ "dev": true,
+ "requires": {
+ "get-value": "^2.0.6",
+ "has-values": "^1.0.0",
+ "isobject": "^3.0.0"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ }
+ }
+ },
+ "has-values": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
+ "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
+ "dev": true,
+ "requires": {
+ "is-number": "^3.0.0",
+ "kind-of": "^4.0.0"
+ },
+ "dependencies": {
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "kind-of": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "hash-base": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
+ "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "hash.js": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.5.tgz",
+ "integrity": "sha512-eWI5HG9Np+eHV1KQhisXWwM+4EPPYe5dFX1UZZH7k/E3JzDEazVH+VGlZi6R94ZqImq+A3D1mCEtrFIfg/E7sA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "minimalistic-assert": "^1.0.1"
+ }
+ },
+ "hasha": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz",
+ "integrity": "sha1-eNfL/B5tZjA/55g3NlmEUXsvbuE=",
+ "dev": true,
+ "requires": {
+ "is-stream": "^1.0.1",
+ "pinkie-promise": "^2.0.0"
+ }
+ },
+ "hawk": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
+ "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
+ "dev": true,
+ "requires": {
+ "boom": "2.x.x",
+ "cryptiles": "2.x.x",
+ "hoek": "2.x.x",
+ "sntp": "1.x.x"
+ }
+ },
+ "he": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
+ "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
+ "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"
+ }
+ },
+ "hoek": {
+ "version": "2.16.3",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
+ "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
+ "dev": true
+ },
+ "home-or-tmp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz",
+ "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=",
+ "dev": true,
+ "requires": {
+ "os-homedir": "^1.0.0",
+ "os-tmpdir": "^1.0.1"
+ }
+ },
+ "hosted-git-info": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz",
+ "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==",
+ "dev": true
+ },
+ "hpack.js": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz",
+ "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "obuf": "^1.0.0",
+ "readable-stream": "^2.0.1",
+ "wbuf": "^1.1.0"
+ }
+ },
+ "html-comment-regex": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.1.tgz",
+ "integrity": "sha1-ZouTd26q5V696POtRkswekljYl4=",
+ "dev": true
+ },
+ "html-entities": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz",
+ "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=",
+ "dev": true
+ },
+ "http-deceiver": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz",
+ "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=",
+ "dev": true
+ },
+ "http-errors": {
+ "version": "1.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"
+ }
+ },
+ "http-parser-js": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.0.tgz",
+ "integrity": "sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w==",
+ "dev": true
+ },
+ "http-proxy": {
+ "version": "1.17.0",
+ "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz",
+ "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==",
+ "dev": true,
+ "requires": {
+ "eventemitter3": "^3.0.0",
+ "follow-redirects": "^1.0.0",
+ "requires-port": "^1.0.0"
+ }
+ },
+ "http-proxy-middleware": {
+ "version": "0.19.1",
+ "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz",
+ "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==",
+ "dev": true,
+ "requires": {
+ "http-proxy": "^1.17.0",
+ "is-glob": "^4.0.0",
+ "lodash": "^4.17.11",
+ "micromatch": "^3.1.10"
+ },
+ "dependencies": {
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+ "dev": true
+ },
+ "array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+ "dev": true
+ },
+ "braces": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "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"
+ }
+ },
+ "expand-brackets": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+ "dev": true,
+ "requires": {
+ "debug": "^2.3.3",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "posix-character-classes": "^0.1.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ }
+ },
+ "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
+ }
+ }
+ },
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "dev": true,
+ "requires": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4"
+ }
+ }
+ }
+ },
+ "extglob": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+ "dev": true,
+ "requires": {
+ "array-unique": "^0.3.2",
+ "define-property": "^1.0.0",
+ "expand-brackets": "^2.1.4",
+ "extend-shallow": "^2.0.1",
+ "fragment-cache": "^0.2.1",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true
+ },
+ "is-glob": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+ "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true
+ },
+ "micromatch": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "braces": "^2.3.1",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "extglob": "^2.0.4",
+ "fragment-cache": "^0.2.1",
+ "kind-of": "^6.0.2",
+ "nanomatch": "^1.2.9",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.2"
+ }
+ }
+ }
+ },
+ "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"
+ }
+ },
+ "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
+ },
+ "humane-js": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/humane-js/-/humane-js-3.2.2.tgz",
+ "integrity": "sha1-t2KvX4skbz/W9FXrExwlK9XACow="
+ },
+ "i18next": {
+ "version": "8.4.3",
+ "resolved": "https://registry.npmjs.org/i18next/-/i18next-8.4.3.tgz",
+ "integrity": "sha1-Nrb/UWxPmSAQ7tzOJKNsRgnox9w="
+ },
+ "i18next-xhr-backend": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/i18next-xhr-backend/-/i18next-xhr-backend-1.5.1.tgz",
+ "integrity": "sha512-9OLdC/9YxDvTFcgsH5t2BHCODHEotHCa6h7Ly0EUlUC7Y2GS09UeoHOGj3gWKQ3HCqXz8NlH4gOrK3NNc9vPuw=="
+ },
+ "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"
+ }
+ },
+ "icss-replace-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz",
+ "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=",
+ "dev": true
+ },
+ "icss-utils": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-2.1.0.tgz",
+ "integrity": "sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI=",
+ "dev": true,
+ "requires": {
+ "postcss": "^6.0.1"
+ },
+ "dependencies": {
+ "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==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "postcss": {
+ "version": "6.0.23",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz",
+ "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.1",
+ "source-map": "^0.6.1",
+ "supports-color": "^5.4.0"
+ }
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "ieee754": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz",
+ "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA=="
+ },
+ "ignore": {
+ "version": "3.3.10",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz",
+ "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==",
+ "dev": true
+ },
+ "ignore-by-default": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
+ "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=",
+ "dev": true
+ },
+ "import-lazy": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz",
+ "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=",
+ "dev": true
+ },
+ "import-local": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-1.0.0.tgz",
+ "integrity": "sha512-vAaZHieK9qjGo58agRBg+bhHX3hoTZU/Oa3GESWLz7t1U62fk63aHuDJJEteXoDeTCcPmUT+z38gkHPZkkmpmQ==",
+ "dev": true,
+ "requires": {
+ "pkg-dir": "^2.0.0",
+ "resolve-cwd": "^2.0.0"
+ }
+ },
+ "imports-loader": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/imports-loader/-/imports-loader-0.7.1.tgz",
+ "integrity": "sha1-8gS180cCoywdt9SNidXoZ6BEElM=",
+ "dev": true,
+ "requires": {
+ "loader-utils": "^1.0.2",
+ "source-map": "^0.5.6"
+ },
+ "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
+ }
+ }
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+ "dev": true
+ },
+ "in-publish": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.1.tgz",
+ "integrity": "sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ==",
+ "dev": true
+ },
+ "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"
+ }
+ },
+ "indexes-of": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz",
+ "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=",
+ "dev": true
+ },
+ "indexof": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
+ "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=",
+ "dev": true
+ },
+ "individual": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/individual/-/individual-2.0.0.tgz",
+ "integrity": "sha1-gzsJfa0jKU52EXqY+zjg2a1hu5c="
+ },
+ "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.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ },
+ "ini": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
+ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
+ },
+ "inquirer": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz",
+ "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==",
+ "requires": {
+ "ansi-escapes": "^3.0.0",
+ "chalk": "^2.0.0",
+ "cli-cursor": "^2.1.0",
+ "cli-width": "^2.0.0",
+ "external-editor": "^2.0.4",
+ "figures": "^2.0.0",
+ "lodash": "^4.3.0",
+ "mute-stream": "0.0.7",
+ "run-async": "^2.2.0",
+ "rx-lite": "^4.0.8",
+ "rx-lite-aggregates": "^4.0.8",
+ "string-width": "^2.1.0",
+ "strip-ansi": "^4.0.0",
+ "through": "^2.3.6"
+ },
+ "dependencies": {
+ "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"
+ }
+ },
+ "chalk": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ },
+ "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"
+ }
+ }
+ }
+ },
+ "internal-ip": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-1.2.0.tgz",
+ "integrity": "sha1-rp+/k7mEh4eF1QqN4bNWlWBYz1w=",
+ "dev": true,
+ "requires": {
+ "meow": "^3.3.0"
+ }
+ },
+ "interpret": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz",
+ "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=",
+ "dev": true
+ },
+ "invariant": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
+ "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
+ "requires": {
+ "loose-envify": "^1.0.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
+ },
+ "ip": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
+ "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=",
+ "dev": true
+ },
+ "ipaddr.js": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz",
+ "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==",
+ "dev": true
+ },
+ "is-absolute-url": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz",
+ "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=",
+ "dev": true
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+ "dev": true
+ },
+ "is-binary-path": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
+ "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
+ "dev": true,
+ "requires": {
+ "binary-extensions": "^1.0.0"
+ }
+ },
+ "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-builtin-module": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
+ "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
+ "requires": {
+ "builtin-modules": "^1.0.0"
+ }
+ },
+ "is-callable": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz",
+ "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA=="
+ },
+ "is-ci": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.0.tgz",
+ "integrity": "sha512-plgvKjQtalH2P3Gytb7L61Lmz95g2DlpzFiQyRSFew8WoJKxtKRzrZMeyRN2supblm3Psc8OQGy7Xjb6XG11jw==",
+ "requires": {
+ "ci-info": "^1.3.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-date-object": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
+ "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY="
+ },
+ "is-deflate": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-deflate/-/is-deflate-1.0.0.tgz",
+ "integrity": "sha1-yGKQHDwWH7CdrHzcfnhPgOmPLxQ=",
+ "optional": true
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ }
+ },
+ "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-dotfile": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz",
+ "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE="
+ },
+ "is-equal-shallow": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz",
+ "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=",
+ "requires": {
+ "is-primitive": "^2.0.0"
+ }
+ },
+ "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": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
+ "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA="
+ },
+ "is-finite": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
+ "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
+ "dev": true,
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ }
+ },
+ "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-function": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz",
+ "integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU="
+ },
+ "is-glob": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
+ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
+ "requires": {
+ "is-extglob": "^1.0.0"
+ }
+ },
+ "is-gzip": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-gzip/-/is-gzip-1.0.0.tgz",
+ "integrity": "sha1-bKiwe5nHeZgCWQDlVc7Y7YCHmoM=",
+ "optional": true
+ },
+ "is-installed-globally": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz",
+ "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=",
+ "dev": true,
+ "requires": {
+ "global-dirs": "^0.1.0",
+ "is-path-inside": "^1.0.0"
+ }
+ },
+ "is-my-ip-valid": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz",
+ "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==",
+ "dev": true
+ },
+ "is-my-json-valid": {
+ "version": "2.19.0",
+ "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.19.0.tgz",
+ "integrity": "sha512-mG0f/unGX1HZ5ep4uhRaPOS8EkAY8/j6mDRMJrutq4CqhoJWYp7qAlonIPy3TV7p3ju4TK9fo/PbnoksWmsp5Q==",
+ "dev": true,
+ "requires": {
+ "generate-function": "^2.0.0",
+ "generate-object-property": "^1.1.0",
+ "is-my-ip-valid": "^1.0.0",
+ "jsonpointer": "^4.0.0",
+ "xtend": "^4.0.0"
+ }
+ },
+ "is-npm": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz",
+ "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=",
+ "dev": true
+ },
+ "is-number": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz",
+ "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=",
+ "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-obj": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
+ "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
+ "dev": true
+ },
+ "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"
+ }
+ },
+ "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==",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.1"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ }
+ }
+ },
+ "is-posix-bracket": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz",
+ "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q="
+ },
+ "is-primitive": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz",
+ "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU="
+ },
+ "is-promise": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
+ "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o="
+ },
+ "is-property": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
+ "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=",
+ "dev": true
+ },
+ "is-redirect": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz",
+ "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=",
+ "dev": true
+ },
+ "is-regex": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
+ "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
+ "requires": {
+ "has": "^1.0.1"
+ }
+ },
+ "is-resolvable": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz",
+ "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==",
+ "dev": true
+ },
+ "is-retry-allowed": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz",
+ "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=",
+ "dev": true
+ },
+ "is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+ "dev": true
+ },
+ "is-svg": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-2.1.0.tgz",
+ "integrity": "sha1-z2EJDaDZ77yrhyLeum8DIgjbsOk=",
+ "dev": true,
+ "requires": {
+ "html-comment-regex": "^1.1.0"
+ }
+ },
+ "is-symbol": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz",
+ "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI="
+ },
+ "is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
+ },
+ "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-windows": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+ "dev": true
+ },
+ "is-wsl": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
+ "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=",
+ "dev": true
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+ },
+ "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"
+ }
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+ "dev": true
+ },
+ "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"
+ }
+ },
+ "isstream": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
+ },
+ "istanbul": {
+ "version": "0.4.5",
+ "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz",
+ "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=",
+ "dev": true,
+ "requires": {
+ "abbrev": "1.0.x",
+ "async": "1.x",
+ "escodegen": "1.8.x",
+ "esprima": "2.7.x",
+ "glob": "^5.0.15",
+ "handlebars": "^4.0.1",
+ "js-yaml": "3.x",
+ "mkdirp": "0.5.x",
+ "nopt": "3.x",
+ "once": "1.x",
+ "resolve": "1.1.x",
+ "supports-color": "^3.1.0",
+ "which": "^1.1.1",
+ "wordwrap": "^1.0.0"
+ },
+ "dependencies": {
+ "async": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+ "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+ "dev": true
+ },
+ "escodegen": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz",
+ "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=",
+ "dev": true,
+ "requires": {
+ "esprima": "^2.7.1",
+ "estraverse": "^1.9.1",
+ "esutils": "^2.0.2",
+ "optionator": "^0.8.1",
+ "source-map": "~0.2.0"
+ }
+ },
+ "esprima": {
+ "version": "2.7.3",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
+ "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
+ "dev": true
+ },
+ "estraverse": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz",
+ "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=",
+ "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"
+ }
+ },
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
+ "dev": true
+ },
+ "resolve": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
+ "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz",
+ "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "amdefine": ">=0.0.4"
+ }
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "dev": true,
+ "requires": {
+ "has-flag": "^1.0.0"
+ }
+ }
+ }
+ },
+ "istanbul-instrumenter-loader": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-instrumenter-loader/-/istanbul-instrumenter-loader-3.0.1.tgz",
+ "integrity": "sha512-a5SPObZgS0jB/ixaKSMdn6n/gXSrK2S6q/UfRJBT3e6gQmVjwZROTODQsYW5ZNwOu78hG62Y3fWlebaVOL0C+w==",
+ "dev": true,
+ "requires": {
+ "convert-source-map": "^1.5.0",
+ "istanbul-lib-instrument": "^1.7.3",
+ "loader-utils": "^1.1.0",
+ "schema-utils": "^0.3.0"
+ }
+ },
+ "istanbul-lib-instrument": {
+ "version": "1.10.2",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz",
+ "integrity": "sha512-aWHxfxDqvh/ZlxR8BBaEPVSWDPUkGD63VjGQn3jcw8jCp7sHEMKcrj4xfJn/ABzdMEHiQNyvDQhqm5o8+SQg7A==",
+ "dev": true,
+ "requires": {
+ "babel-generator": "^6.18.0",
+ "babel-template": "^6.16.0",
+ "babel-traverse": "^6.18.0",
+ "babel-types": "^6.18.0",
+ "babylon": "^6.18.0",
+ "istanbul-lib-coverage": "^1.2.1",
+ "semver": "^5.3.0"
+ },
+ "dependencies": {
+ "istanbul-lib-coverage": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz",
+ "integrity": "sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ==",
+ "dev": true
+ }
+ }
+ },
+ "jju": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz",
+ "integrity": "sha1-o6vicYryQaKykE+EpiWXDzia4yo=",
+ "dev": true
+ },
+ "jquery": {
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.4.1.tgz",
+ "integrity": "sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw=="
+ },
+ "jquery-lazyload": {
+ "version": "1.9.7",
+ "resolved": "https://registry.npmjs.org/jquery-lazyload/-/jquery-lazyload-1.9.7.tgz",
+ "integrity": "sha1-mYKziMUzwLYRIUs8WqoLn+3gcfc="
+ },
+ "jquery-treeview": {
+ "version": "git+https://github.com/alchemy-fr/jquery-treeview.git#1e9e5a49d2875b878801e904cd08c2d25e85af1e",
+ "from": "git+https://github.com/alchemy-fr/jquery-treeview.git"
+ },
+ "jquery-ui": {
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/jquery-ui/-/jquery-ui-1.10.4.tgz",
+ "integrity": "sha1-oJb+X04PKraaBYXPEEVYd/V1Br0="
+ },
+ "jquery-ui-datepicker-with-i18n": {
+ "version": "1.10.4",
+ "resolved": "https://registry.npmjs.org/jquery-ui-datepicker-with-i18n/-/jquery-ui-datepicker-with-i18n-1.10.4.tgz",
+ "integrity": "sha1-hiy1tI5MUCpROt7tCGTpI0dZM34="
+ },
+ "jquery.fancytree": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/jquery.fancytree/-/jquery.fancytree-2.7.0.tgz",
+ "integrity": "sha1-VCrwAO2bcRghwpd3OjdhYqQCyPg="
+ },
+ "jquery.tree": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/jquery.tree/-/jquery.tree-0.0.5.tgz",
+ "integrity": "sha1-JOUSvHOQRj2zYmDGXYN27RdwZw8=",
+ "requires": {
+ "jquery": "~2.1.1"
+ },
+ "dependencies": {
+ "jquery": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/jquery/-/jquery-2.1.4.tgz",
+ "integrity": "sha1-IoveaYoMYUMdwmMKahVPFYkNIxc="
+ }
+ }
+ },
+ "js-base64": {
+ "version": "2.4.9",
+ "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.9.tgz",
+ "integrity": "sha512-xcinL3AuDJk7VSzsHgb9DvvIXayBbadtMZ4HFPx8rUszbW1MuNMlwYVC4zzCZ6e1sqZpnNS5ZFYOhXqA39T7LQ==",
+ "dev": true
+ },
+ "js-cookie": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz",
+ "integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ=="
+ },
+ "js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+ },
+ "js-yaml": {
+ "version": "3.13.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
+ "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ },
+ "dependencies": {
+ "esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
+ }
+ }
+ },
+ "jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
+ },
+ "jsesc": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
+ "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=",
+ "dev": true
+ },
+ "json-loader": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz",
+ "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==",
+ "dev": true
+ },
+ "json-parse-helpfulerror": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/json-parse-helpfulerror/-/json-parse-helpfulerror-1.0.3.tgz",
+ "integrity": "sha1-E/FM4C7tTpgSl7ZOueO5MuLdE9w=",
+ "dev": true,
+ "requires": {
+ "jju": "^1.1.0"
+ }
+ },
+ "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.3.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
+ "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A="
+ },
+ "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.2",
+ "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz",
+ "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=",
+ "dev": true
+ },
+ "json5": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
+ "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
+ "dev": true
+ },
+ "jsonfile": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
+ "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "jsonlint-lines-primitives": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/jsonlint-lines-primitives/-/jsonlint-lines-primitives-1.6.0.tgz",
+ "integrity": "sha1-u4n2DIubYS/ZE92qI2ZJuEDYZhE=",
+ "requires": {
+ "JSV": ">= 4.0.x",
+ "nomnom": ">= 1.5.x"
+ }
+ },
+ "jsonparse": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
+ "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=",
+ "optional": true
+ },
+ "jsonpointer": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz",
+ "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=",
+ "dev": true
+ },
+ "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"
+ }
+ },
+ "jsx-ast-utils": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-1.4.1.tgz",
+ "integrity": "sha1-OGchPo3Xm/Ho8jAMDPwe+xgsDfE=",
+ "dev": true
+ },
+ "karma": {
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/karma/-/karma-1.7.1.tgz",
+ "integrity": "sha512-k5pBjHDhmkdaUccnC7gE3mBzZjcxyxYsYVaqiL2G5AqlfLyBO5nw2VdNK+O16cveEPd/gIOWULH7gkiYYwVNHg==",
+ "dev": true,
+ "requires": {
+ "bluebird": "^3.3.0",
+ "body-parser": "^1.16.1",
+ "chokidar": "^1.4.1",
+ "colors": "^1.1.0",
+ "combine-lists": "^1.0.0",
+ "connect": "^3.6.0",
+ "core-js": "^2.2.0",
+ "di": "^0.0.1",
+ "dom-serialize": "^2.2.0",
+ "expand-braces": "^0.1.1",
+ "glob": "^7.1.1",
+ "graceful-fs": "^4.1.2",
+ "http-proxy": "^1.13.0",
+ "isbinaryfile": "^3.0.0",
+ "lodash": "^3.8.0",
+ "log4js": "^0.6.31",
+ "mime": "^1.3.4",
+ "minimatch": "^3.0.2",
+ "optimist": "^0.6.1",
+ "qjobs": "^1.1.4",
+ "range-parser": "^1.2.0",
+ "rimraf": "^2.6.0",
+ "safe-buffer": "^5.0.1",
+ "socket.io": "1.7.3",
+ "source-map": "^0.5.3",
+ "tmp": "0.0.31",
+ "useragent": "^2.1.12"
+ },
+ "dependencies": {
+ "lodash": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
+ "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
+ "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
+ },
+ "tmp": {
+ "version": "0.0.31",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz",
+ "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=",
+ "dev": true,
+ "requires": {
+ "os-tmpdir": "~1.0.1"
+ }
+ }
+ }
+ },
+ "karma-chai": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/karma-chai/-/karma-chai-0.1.0.tgz",
+ "integrity": "sha1-vuWtQEAFF4Ea40u5RfdikJEIt5o=",
+ "dev": true
+ },
+ "karma-chrome-launcher": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz",
+ "integrity": "sha512-uf/ZVpAabDBPvdPdveyk1EPgbnloPvFFGgmRhYLTDH7gEB4nZdSBk8yTU47w1g/drLSx5uMOkjKk7IWKfWg/+w==",
+ "dev": true,
+ "requires": {
+ "fs-access": "^1.0.0",
+ "which": "^1.2.1"
+ }
+ },
+ "karma-cli": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/karma-cli/-/karma-cli-1.0.1.tgz",
+ "integrity": "sha1-rmw8WKMTodALRRZMRVubhs4X+WA=",
+ "dev": true,
+ "requires": {
+ "resolve": "^1.1.6"
+ }
+ },
+ "karma-coverage": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-1.1.2.tgz",
+ "integrity": "sha512-eQawj4Cl3z/CjxslYy9ariU4uDh7cCNFZHNWXWRpl0pNeblY/4wHR7M7boTYXWrn9bY0z2pZmr11eKje/S/hIw==",
+ "dev": true,
+ "requires": {
+ "dateformat": "^1.0.6",
+ "istanbul": "^0.4.0",
+ "lodash": "^4.17.0",
+ "minimatch": "^3.0.0",
+ "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
+ }
+ }
+ },
+ "karma-firefox-launcher": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/karma-firefox-launcher/-/karma-firefox-launcher-1.1.0.tgz",
+ "integrity": "sha512-LbZ5/XlIXLeQ3cqnCbYLn+rOVhuMIK9aZwlP6eOLGzWdo1UVp7t6CN3DP4SafiRLjexKwHeKHDm0c38Mtd3VxA==",
+ "dev": true
+ },
+ "karma-ie-launcher": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/karma-ie-launcher/-/karma-ie-launcher-1.0.0.tgz",
+ "integrity": "sha1-SXmGhCxJAZA0bNifVJTKmDDG1Zw=",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.6.1"
+ }
+ },
+ "karma-mocha": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/karma-mocha/-/karma-mocha-1.3.0.tgz",
+ "integrity": "sha1-7qrH/8DiAetjxGdEDStpx883eL8=",
+ "dev": true,
+ "requires": {
+ "minimist": "1.2.0"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "dev": true
+ }
+ }
+ },
+ "karma-mocha-reporter": {
+ "version": "2.2.5",
+ "resolved": "https://registry.npmjs.org/karma-mocha-reporter/-/karma-mocha-reporter-2.2.5.tgz",
+ "integrity": "sha1-FRIAlejtgZGG5HoLAS8810GJVWA=",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.1.0",
+ "log-symbols": "^2.1.0",
+ "strip-ansi": "^4.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ },
+ "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==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "karma-phantomjs-launcher": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/karma-phantomjs-launcher/-/karma-phantomjs-launcher-1.0.4.tgz",
+ "integrity": "sha1-0jyjSAG9qYY60xjju0vUBisTrNI=",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.0.1",
+ "phantomjs-prebuilt": "^2.1.7"
+ }
+ },
+ "karma-sinon": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/karma-sinon/-/karma-sinon-1.0.5.tgz",
+ "integrity": "sha1-TjRD8oMP3s/2JNN0cWPxIX2qKpo=",
+ "dev": true
+ },
+ "karma-sinon-chai": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/karma-sinon-chai/-/karma-sinon-chai-1.3.4.tgz",
+ "integrity": "sha512-Oatu8tdkfWaSveM809euI6KGcNJRdoXFilz9ozSf+vPwrM73kncu54nsfkLcMqR/iht3PXASAGK9La5oU2xDKQ==",
+ "dev": true,
+ "requires": {
+ "lolex": "^1.6.0"
+ },
+ "dependencies": {
+ "lolex": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/lolex/-/lolex-1.6.0.tgz",
+ "integrity": "sha1-OpoCg0UqR9dDnnJzG54H1zhuSfY=",
+ "dev": true
+ }
+ }
+ },
+ "karma-sourcemap-loader": {
+ "version": "0.3.7",
+ "resolved": "https://registry.npmjs.org/karma-sourcemap-loader/-/karma-sourcemap-loader-0.3.7.tgz",
+ "integrity": "sha1-kTIsd/jxPUb+0GKwQuEAnUxFBdg=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2"
+ }
+ },
+ "karma-spec-reporter": {
+ "version": "0.0.31",
+ "resolved": "https://registry.npmjs.org/karma-spec-reporter/-/karma-spec-reporter-0.0.31.tgz",
+ "integrity": "sha1-SDDccUihVcfXoYbmMjOaDYD63sM=",
+ "dev": true,
+ "requires": {
+ "colors": "^1.1.2"
+ }
+ },
+ "karma-webpack": {
+ "version": "2.0.13",
+ "resolved": "https://registry.npmjs.org/karma-webpack/-/karma-webpack-2.0.13.tgz",
+ "integrity": "sha512-2cyII34jfrAabbI2+4Rk4j95Nazl98FvZQhgSiqKUDarT317rxfv/EdzZ60CyATN4PQxJdO5ucR5bOOXkEVrXw==",
+ "dev": true,
+ "requires": {
+ "async": "^2.0.0",
+ "babel-runtime": "^6.0.0",
+ "loader-utils": "^1.0.0",
+ "lodash": "^4.0.0",
+ "source-map": "^0.5.6",
+ "webpack-dev-middleware": "^1.12.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
+ }
+ }
+ },
+ "kdbush": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-3.0.0.tgz",
+ "integrity": "sha512-hRkd6/XW4HTsA9vjVpY9tuXJYLSlelnkTmVFu4M9/7MIYQtFcHpbugAU7UbOfjOiVSVYl2fqgBuJ32JUmRo5Ew=="
+ },
+ "kew": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz",
+ "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=",
+ "dev": true
+ },
+ "keycode": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/keycode/-/keycode-2.2.0.tgz",
+ "integrity": "sha1-PQr1bce4uOXLqNCpfxByBO7CKwQ="
+ },
+ "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": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw=="
+ },
+ "klaw": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
+ "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.9"
+ }
+ },
+ "last-call-webpack-plugin": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/last-call-webpack-plugin/-/last-call-webpack-plugin-2.1.2.tgz",
+ "integrity": "sha512-CZc+m2xZm51J8qSwdODeiiNeqh8CYkKEq6Rw8IkE4i/4yqf2cJhjQPsA6BtAV970ePRNhwEOXhy2U5xc5Jwh9Q==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.4",
+ "webpack-sources": "^1.0.1"
+ }
+ },
+ "latest-version": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz",
+ "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=",
+ "dev": true,
+ "requires": {
+ "package-json": "^4.0.0"
+ }
+ },
+ "lazy-cache": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
+ "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
+ "dev": true
+ },
+ "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"
+ }
+ },
+ "lcov-parse": {
+ "version": "0.0.10",
+ "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.10.tgz",
+ "integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=",
+ "dev": true
+ },
+ "leaflet": {
+ "version": "0.7.7",
+ "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-0.7.7.tgz",
+ "integrity": "sha1-HjUrpU5j0HZFH6NjyQCJDLLPde4="
+ },
+ "leaflet-contextmenu": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/leaflet-contextmenu/-/leaflet-contextmenu-1.0.0.tgz",
+ "integrity": "sha1-M8JfBN4dUZIvJvgA651hSJjLoxE="
+ },
+ "leaflet-draw": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/leaflet-draw/-/leaflet-draw-0.3.0.tgz",
+ "integrity": "sha1-l8bJ1dWyp9w+EDe1C0gv98z5oTc="
+ },
+ "leven": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz",
+ "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=",
+ "optional": true
+ },
+ "levn": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+ "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+ "requires": {
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2"
+ }
+ },
+ "lineclip": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/lineclip/-/lineclip-1.1.5.tgz",
+ "integrity": "sha1-K/JgZ9lDVP6r+R5CdoI221YW/RM="
+ },
+ "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": {
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "dev": true
+ }
+ }
+ },
+ "loader-fs-cache": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/loader-fs-cache/-/loader-fs-cache-1.0.3.tgz",
+ "integrity": "sha512-ldcgZpjNJj71n+2Mf6yetz+c9bM4xpKtNds4LbqXzU/PTdeAX0g3ytnU1AJMEcTk2Lex4Smpe3Q/eCTsvUBxbA==",
+ "dev": true,
+ "requires": {
+ "find-cache-dir": "^0.1.1",
+ "mkdirp": "^0.5.1"
+ },
+ "dependencies": {
+ "find-cache-dir": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-0.1.1.tgz",
+ "integrity": "sha1-yN765XyKUqinhPnjHFfHQumToLk=",
+ "dev": true,
+ "requires": {
+ "commondir": "^1.0.1",
+ "mkdirp": "^0.5.1",
+ "pkg-dir": "^1.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"
+ }
+ },
+ "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"
+ }
+ },
+ "pkg-dir": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz",
+ "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=",
+ "dev": true,
+ "requires": {
+ "find-up": "^1.0.0"
+ }
+ }
+ }
+ },
+ "loader-runner": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.0.tgz",
+ "integrity": "sha1-9IKuqC1UPgeSFwDVpG7yb9rGuKI=",
+ "dev": true
+ },
+ "loader-utils": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz",
+ "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=",
+ "dev": true,
+ "requires": {
+ "big.js": "^3.1.3",
+ "emojis-list": "^2.0.0",
+ "json5": "^0.5.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"
+ }
+ },
+ "lodash": {
+ "version": "4.17.15",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+ "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
+ },
+ "lodash._baseassign": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz",
+ "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=",
+ "dev": true,
+ "requires": {
+ "lodash._basecopy": "^3.0.0",
+ "lodash.keys": "^3.0.0"
+ }
+ },
+ "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._basecreate": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz",
+ "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=",
+ "dev": true
+ },
+ "lodash._bindcallback": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz",
+ "integrity": "sha1-5THCdkTPi1epnhftlbNcdIeJOS4=",
+ "dev": true
+ },
+ "lodash._createassigner": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz",
+ "integrity": "sha1-g4pbri/aymOsIt7o4Z+k5taXCxE=",
+ "dev": true,
+ "requires": {
+ "lodash._bindcallback": "^3.0.0",
+ "lodash._isiterateecall": "^3.0.0",
+ "lodash.restparam": "^3.0.0"
+ }
+ },
+ "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.assign": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
+ "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=",
+ "dev": true
+ },
+ "lodash.camelcase": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
+ "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=",
+ "dev": true
+ },
+ "lodash.create": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz",
+ "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=",
+ "dev": true,
+ "requires": {
+ "lodash._baseassign": "^3.0.0",
+ "lodash._basecreate": "^3.0.0",
+ "lodash._isiterateecall": "^3.0.0"
+ }
+ },
+ "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.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.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=="
+ },
+ "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.tail": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.tail/-/lodash.tail-4.1.1.tgz",
+ "integrity": "sha1-0jM6NtnncXyK0vfKyv7HwytERmQ=",
+ "dev": true
+ },
+ "lodash.toarray": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz",
+ "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=",
+ "optional": true
+ },
+ "lodash.uniq": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
+ "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=",
+ "dev": true
+ },
+ "log-driver": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.5.tgz",
+ "integrity": "sha1-euTsJXMC/XkNVXyxDJcQDYV7AFY=",
+ "dev": true
+ },
+ "log-symbols": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
+ "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.0.1"
+ },
+ "dependencies": {
+ "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==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "log4js": {
+ "version": "0.6.38",
+ "resolved": "http://registry.npmjs.org/log4js/-/log4js-0.6.38.tgz",
+ "integrity": "sha1-LElBFmldb7JUgJQ9P8hy5mKlIv0=",
+ "dev": true,
+ "requires": {
+ "readable-stream": "~1.0.2",
+ "semver": "~4.3.3"
+ },
+ "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.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"
+ }
+ },
+ "semver": {
+ "version": "4.3.6",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz",
+ "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=",
+ "dev": true
+ },
+ "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
+ }
+ }
+ },
+ "loglevel": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.1.tgz",
+ "integrity": "sha1-4PyVEztu8nbNyIh82vJKpvFW+Po=",
+ "dev": true
+ },
+ "lolex": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.0.tgz",
+ "integrity": "sha512-uJkH2e0BVfU5KOJUevbTOtpDduooSarH5PopO+LfM/vZf8Z9sJzODqKev804JYM2i++ktJfUmC1le4LwFQ1VMg==",
+ "dev": true
+ },
+ "longest": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
+ "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=",
+ "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==",
+ "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=",
+ "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": "4.1.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz",
+ "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==",
+ "dev": true,
+ "requires": {
+ "pseudomap": "^1.0.2",
+ "yallist": "^2.1.2"
+ }
+ },
+ "m3u8-parser": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/m3u8-parser/-/m3u8-parser-4.3.0.tgz",
+ "integrity": "sha512-bVbjuBMoVIgFL1vpXVIxjeaoB5TPDJRb0m5qiTdM738SGqv/LAmsnVVPlKjM4fulm/rr1XZsKM+owHm+zvqxYA==",
+ "requires": {
+ "global": "^4.3.2"
+ }
+ },
+ "magic-string": {
+ "version": "0.22.5",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz",
+ "integrity": "sha512-oreip9rJZkzvA8Qzk9HFs8fZGF/u7H/gtrE8EN6RjKJ9kh2HlC+yQ2QezifqTZfGyiuAV0dRv5a+y/8gBb1m9w==",
+ "requires": {
+ "vlq": "^0.2.2"
+ }
+ },
+ "make-dir": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
+ "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==",
+ "dev": true,
+ "requires": {
+ "pify": "^3.0.0"
+ }
+ },
+ "map-cache": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+ "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+ "dev": true
+ },
+ "map-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=",
+ "dev": true,
+ "requires": {
+ "object-visit": "^1.0.0"
+ }
+ },
+ "mapbox": {
+ "version": "1.0.0-beta10",
+ "resolved": "https://registry.npmjs.org/mapbox/-/mapbox-1.0.0-beta10.tgz",
+ "integrity": "sha1-A3VhvLlcvcBm0d/34s4dbIU5y44=",
+ "requires": {
+ "es6-promise": "^4.0.5",
+ "rest": "^2.0.0"
+ }
+ },
+ "mapbox-gl": {
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-1.11.0.tgz",
+ "integrity": "sha512-opIQf3C5RoKU5r9bHttTMhGAPcJet1/Cj2mdP7Ma2ylrAHjNPRc1i7KPyq8wjEZdJBMhd5qkIDlzUPM0TSncCQ==",
+ "requires": {
+ "@mapbox/geojson-rewind": "^0.5.0",
+ "@mapbox/geojson-types": "^1.0.2",
+ "@mapbox/jsonlint-lines-primitives": "^2.0.2",
+ "@mapbox/mapbox-gl-supported": "^1.5.0",
+ "@mapbox/point-geometry": "^0.1.0",
+ "@mapbox/tiny-sdf": "^1.1.1",
+ "@mapbox/unitbezier": "^0.0.0",
+ "@mapbox/vector-tile": "^1.3.1",
+ "@mapbox/whoots-js": "^3.1.0",
+ "csscolorparser": "~1.0.3",
+ "earcut": "^2.2.2",
+ "geojson-vt": "^3.2.1",
+ "gl-matrix": "^3.2.1",
+ "grid-index": "^1.1.0",
+ "minimist": "^1.2.5",
+ "murmurhash-js": "^1.0.0",
+ "pbf": "^3.2.1",
+ "potpack": "^1.0.1",
+ "quickselect": "^2.0.0",
+ "rw": "^1.3.3",
+ "supercluster": "^7.1.0",
+ "tinyqueue": "^2.0.3",
+ "vt-pbf": "^3.1.1"
+ },
+ "dependencies": {
+ "@mapbox/mapbox-gl-supported": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-1.5.0.tgz",
+ "integrity": "sha512-/PT1P6DNf7vjEEiPkVIRJkvibbqWtqnyGaBz3nfRdcxclNSnSdaLU5tfAgcD7I8Yt5i+L19s406YLl1koLnLbg=="
+ },
+ "@mapbox/tiny-sdf": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-1.1.1.tgz",
+ "integrity": "sha512-Ihn1nZcGIswJ5XGbgFAvVumOgWpvIjBX9jiRlIl46uQG9vJOF51ViBYHF95rEZupuyQbEmhLaDPLQlU7fUTsBg=="
+ },
+ "earcut": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.2.tgz",
+ "integrity": "sha512-eZoZPPJcUHnfRZ0PjLvx2qBordSiO8ofC3vt+qACLM95u+4DovnbYNpQtJh0DNsWj8RnxrQytD4WA8gj5cRIaQ=="
+ },
+ "minimist": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
+ },
+ "pbf": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.2.1.tgz",
+ "integrity": "sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ==",
+ "requires": {
+ "ieee754": "^1.1.12",
+ "resolve-protobuf-schema": "^2.1.0"
+ }
+ },
+ "quickselect": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz",
+ "integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw=="
+ },
+ "tinyqueue": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-2.0.3.tgz",
+ "integrity": "sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA=="
+ }
+ }
+ },
+ "mapbox-gl-circle": {
+ "version": "1.6.5",
+ "resolved": "https://registry.npmjs.org/mapbox-gl-circle/-/mapbox-gl-circle-1.6.5.tgz",
+ "integrity": "sha512-VHA6lgxZE/WFtBXmMveU2zt7ZeVcBHe42k4U4b8xGEnrDSQs4/++EBPVywEMNqi01XQrbf1eiAhsIDZasR4drw==",
+ "requires": {
+ "@turf/bbox": "^4.7.3",
+ "@turf/bbox-polygon": "^4.7.3",
+ "@turf/bearing": "^4.5.2",
+ "@turf/circle": "^4.7.3",
+ "@turf/destination": "^4.7.3",
+ "@turf/distance": "^4.7.3",
+ "@turf/helpers": "^4.7.3",
+ "@turf/truncate": "^4.7.3",
+ "core-util-is": "^1.0.2",
+ "debug": "^3.0.0",
+ "events": "^1.1.1",
+ "fsevents": "^1.1.2",
+ "glob": "^7.1.2",
+ "inflight": "^1.0.6",
+ "inherits": "^2.0.3",
+ "jsonparse": "^1.3.1",
+ "lodash": "^4.17.5",
+ "lodash.debounce": "^4.0.8",
+ "mapbox-gl": "^0.44.1",
+ "minimatch": "^3.0.4",
+ "once": "^1.4.0",
+ "punycode": "^2.1.0",
+ "readable-stream": "^2.3.3",
+ "string_decoder": "^1.0.3",
+ "through2": "^2.0.3",
+ "util-deprecate": "^1.0.2",
+ "wrappy": "^1.0.2",
+ "xtend": "^4.0.1",
+ "yarn": "^0.27.5"
+ },
+ "dependencies": {
+ "@turf/bbox": {
+ "version": "4.7.3",
+ "resolved": "https://registry.npmjs.org/@turf/bbox/-/bbox-4.7.3.tgz",
+ "integrity": "sha1-461PEKfptBtSKIDTMIMZgZkFkGc=",
+ "requires": {
+ "@turf/meta": "^4.7.3"
+ }
+ },
+ "@turf/bbox-polygon": {
+ "version": "4.7.3",
+ "resolved": "https://registry.npmjs.org/@turf/bbox-polygon/-/bbox-polygon-4.7.3.tgz",
+ "integrity": "sha1-NYiQ/R8abK2anLUHmeNzJfuIAXo=",
+ "requires": {
+ "@turf/helpers": "^4.7.3"
+ }
+ },
+ "@turf/bearing": {
+ "version": "4.7.3",
+ "resolved": "https://registry.npmjs.org/@turf/bearing/-/bearing-4.7.3.tgz",
+ "integrity": "sha1-79GopcjKDNvsvMAhcsQe0hbf+Pk=",
+ "requires": {
+ "@turf/invariant": "^4.7.3"
+ }
+ },
+ "@turf/circle": {
+ "version": "4.7.3",
+ "resolved": "https://registry.npmjs.org/@turf/circle/-/circle-4.7.3.tgz",
+ "integrity": "sha1-6PmW/4ewyo4+a3S2D2q12vkIZxM=",
+ "requires": {
+ "@turf/destination": "^4.7.3",
+ "@turf/helpers": "^4.7.3"
+ }
+ },
+ "@turf/destination": {
+ "version": "4.7.3",
+ "resolved": "https://registry.npmjs.org/@turf/destination/-/destination-4.7.3.tgz",
+ "integrity": "sha1-8eo7s3Bc9S/tE1p5F9STNuR7jS4=",
+ "requires": {
+ "@turf/helpers": "^4.7.3",
+ "@turf/invariant": "^4.7.3"
+ }
+ },
+ "@turf/distance": {
+ "version": "4.7.3",
+ "resolved": "https://registry.npmjs.org/@turf/distance/-/distance-4.7.3.tgz",
+ "integrity": "sha1-tatIoJpkJwbWXDm5GUM9XSzFcbE=",
+ "requires": {
+ "@turf/helpers": "^4.7.3",
+ "@turf/invariant": "^4.7.3"
+ }
+ },
+ "@turf/helpers": {
+ "version": "4.7.3",
+ "resolved": "https://registry.npmjs.org/@turf/helpers/-/helpers-4.7.3.tgz",
+ "integrity": "sha1-vDEqxDyrPFMqSDFRxMOCxWSUKek="
+ },
+ "@turf/invariant": {
+ "version": "4.7.3",
+ "resolved": "https://registry.npmjs.org/@turf/invariant/-/invariant-4.7.3.tgz",
+ "integrity": "sha1-U482fSPBE/yEnXDJpSS4Vjh0YB0="
+ },
+ "@turf/meta": {
+ "version": "4.7.4",
+ "resolved": "https://registry.npmjs.org/@turf/meta/-/meta-4.7.4.tgz",
+ "integrity": "sha1-beLx6YkLj2S2aeS0fAmyCJMGOXc="
+ },
+ "@turf/truncate": {
+ "version": "4.7.3",
+ "resolved": "https://registry.npmjs.org/@turf/truncate/-/truncate-4.7.3.tgz",
+ "integrity": "sha1-gnqN+P8Mn/+dzxpLMUXL3vgPuZM=",
+ "requires": {
+ "@turf/meta": "^4.7.3"
+ }
+ },
+ "geojson-rewind": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/geojson-rewind/-/geojson-rewind-0.3.1.tgz",
+ "integrity": "sha1-IiQHl8hHzC8MHTE+SqDJFa+n8p0=",
+ "requires": {
+ "@mapbox/geojson-area": "0.2.2",
+ "concat-stream": "~1.6.0",
+ "minimist": "1.2.0",
+ "sharkdown": "^0.1.0"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
+ }
+ }
+ },
+ "kdbush": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/kdbush/-/kdbush-1.0.1.tgz",
+ "integrity": "sha1-PL0D6d6tnA9vZszblkUOXOzGQOA="
+ },
+ "mapbox-gl": {
+ "version": "0.44.2",
+ "resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-0.44.2.tgz",
+ "integrity": "sha512-UzrfDEit6pX+HSj5qQTDG633JiF4JKn1MD8vz58S7kAnGRqnnSfFc7rrSVXZ/E6G5SFKsfESURUbLLuGkOcfWA==",
+ "requires": {
+ "@mapbox/gl-matrix": "^0.0.1",
+ "@mapbox/mapbox-gl-supported": "^1.3.0",
+ "@mapbox/point-geometry": "^0.1.0",
+ "@mapbox/shelf-pack": "^3.1.0",
+ "@mapbox/tiny-sdf": "^1.1.0",
+ "@mapbox/unitbezier": "^0.0.0",
+ "@mapbox/vector-tile": "^1.3.0",
+ "@mapbox/whoots-js": "^3.0.0",
+ "brfs": "^1.4.0",
+ "bubleify": "^0.7.0",
+ "csscolorparser": "~1.0.2",
+ "earcut": "^2.1.3",
+ "geojson-rewind": "^0.3.0",
+ "geojson-vt": "^3.0.0",
+ "gray-matter": "^3.0.8",
+ "grid-index": "^1.0.0",
+ "jsonlint-lines-primitives": "~1.6.0",
+ "minimist": "0.0.8",
+ "package-json-versionify": "^1.0.2",
+ "pbf": "^3.0.5",
+ "quickselect": "^1.0.0",
+ "rw": "^1.3.3",
+ "shuffle-seed": "^1.1.6",
+ "sort-object": "^0.3.2",
+ "supercluster": "^2.3.0",
+ "through2": "^2.0.3",
+ "tinyqueue": "^1.1.0",
+ "unassertify": "^2.0.0",
+ "unflowify": "^1.0.0",
+ "vt-pbf": "^3.0.1",
+ "webworkify": "^1.5.0"
+ }
+ },
+ "supercluster": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/supercluster/-/supercluster-2.3.0.tgz",
+ "integrity": "sha1-h6tWCBu+qaHXJN9TUe6ejDry9Is=",
+ "requires": {
+ "kdbush": "^1.0.1"
+ }
+ }
+ }
+ },
+ "mapbox.js": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/mapbox.js/-/mapbox.js-2.4.0.tgz",
+ "integrity": "sha1-xDsISl3XEzTIPuHfKPpnRD1zwpw=",
+ "requires": {
+ "corslite": "0.0.6",
+ "isarray": "0.0.1",
+ "leaflet": "0.7.7",
+ "mustache": "2.2.1",
+ "sanitize-caja": "0.1.3"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
+ }
+ }
+ },
+ "math-expression-evaluator": {
+ "version": "1.2.17",
+ "resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz",
+ "integrity": "sha1-3oGf282E3M2PrlnGrreWFbnSZqw=",
+ "dev": true
+ },
+ "math-random": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz",
+ "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w="
+ },
+ "md5.js": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz",
+ "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=",
+ "dev": true,
+ "requires": {
+ "hash-base": "^3.0.0",
+ "inherits": "^2.0.1"
+ }
+ },
+ "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": "1.1.0",
+ "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz",
+ "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=",
+ "dev": true,
+ "requires": {
+ "mimic-fn": "^1.0.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"
+ }
+ },
+ "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"
+ }
+ },
+ "minimist": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+ "dev": true
+ },
+ "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.0.4",
+ "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.0.4.tgz",
+ "integrity": "sha1-pd5GU42uhNQRTMXqArR3KmNGcB8=",
+ "requires": {
+ "source-map": "^0.5.6"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ }
+ }
+ },
+ "methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
+ "dev": true
+ },
+ "micromatch": {
+ "version": "2.3.11",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
+ "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=",
+ "requires": {
+ "arr-diff": "^2.0.0",
+ "array-unique": "^0.2.1",
+ "braces": "^1.8.2",
+ "expand-brackets": "^0.1.4",
+ "extglob": "^0.3.1",
+ "filename-regex": "^2.0.0",
+ "is-extglob": "^1.0.0",
+ "is-glob": "^2.0.1",
+ "kind-of": "^3.0.2",
+ "normalize-path": "^2.0.1",
+ "object.omit": "^2.0.0",
+ "parse-glob": "^3.0.4",
+ "regex-cache": "^0.4.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"
+ }
+ }
+ }
+ },
+ "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"
+ }
+ },
+ "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.36.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.36.0.tgz",
+ "integrity": "sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw=="
+ },
+ "mime-types": {
+ "version": "2.1.20",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.20.tgz",
+ "integrity": "sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A==",
+ "requires": {
+ "mime-db": "~1.36.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=="
+ },
+ "min-document": {
+ "version": "2.19.0",
+ "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz",
+ "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=",
+ "requires": {
+ "dom-walk": "^0.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": "0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
+ },
+ "mixin-deep": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
+ "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
+ "dev": true,
+ "requires": {
+ "for-in": "^1.0.2",
+ "is-extendable": "^1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4"
+ }
+ }
+ }
+ },
+ "mixin-object": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/mixin-object/-/mixin-object-2.0.1.tgz",
+ "integrity": "sha1-T7lJRB2rGCVA8f4DW6YOGUel5X4=",
+ "dev": true,
+ "requires": {
+ "for-in": "^0.1.3",
+ "is-extendable": "^0.1.1"
+ },
+ "dependencies": {
+ "for-in": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/for-in/-/for-in-0.1.8.tgz",
+ "integrity": "sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE=",
+ "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==",
+ "requires": {
+ "minimist": "^1.2.5"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
+ }
+ }
+ },
+ "mocha": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-3.5.3.tgz",
+ "integrity": "sha512-/6na001MJWEtYxHOV1WLfsmR4YIynkUEhBwzsb+fk2qmQ3iqsi258l/Q2MWHJMImAcNpZ8DEdYAK72NHoIQ9Eg==",
+ "dev": true,
+ "requires": {
+ "browser-stdout": "1.3.0",
+ "commander": "2.9.0",
+ "debug": "2.6.8",
+ "diff": "3.2.0",
+ "escape-string-regexp": "1.0.5",
+ "glob": "7.1.1",
+ "growl": "1.9.2",
+ "he": "1.1.1",
+ "json3": "3.3.2",
+ "lodash.create": "3.1.1",
+ "mkdirp": "0.5.1",
+ "supports-color": "3.1.2"
+ },
+ "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"
+ }
+ },
+ "debug": {
+ "version": "2.6.8",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
+ "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "glob": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz",
+ "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.2",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
+ "dev": true
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+ "dev": true,
+ "requires": {
+ "minimist": "0.0.8"
+ }
+ },
+ "supports-color": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz",
+ "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=",
+ "dev": true,
+ "requires": {
+ "has-flag": "^1.0.0"
+ }
+ }
+ }
+ },
+ "monotone-convex-hull-2d": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/monotone-convex-hull-2d/-/monotone-convex-hull-2d-1.0.1.tgz",
+ "integrity": "sha1-R/Xa6t88Sv03dkuqGqh4ekDu4Iw=",
+ "requires": {
+ "robust-orientation": "^1.1.3"
+ }
+ },
+ "mpd-parser": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/mpd-parser/-/mpd-parser-0.7.0.tgz",
+ "integrity": "sha512-nkzVIkecaDz3q7p4ToN3GR0FV2Odbh0w2sJ8ijsyw79JcBrJoUD3KHIiI8gL0hEDlex7mrVpTxXBsRHowUBmPw==",
+ "requires": {
+ "global": "^4.3.2",
+ "url-toolkit": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "multi-stage-sourcemap": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/multi-stage-sourcemap/-/multi-stage-sourcemap-0.2.1.tgz",
+ "integrity": "sha1-sJ/IWG6qF/gdV1xK0C4Pej9rEQU=",
+ "requires": {
+ "source-map": "^0.1.34"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.1.43",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz",
+ "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=",
+ "requires": {
+ "amdefine": ">=0.0.4"
+ }
+ }
+ }
+ },
+ "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
+ },
+ "murmurhash-js": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/murmurhash-js/-/murmurhash-js-1.0.0.tgz",
+ "integrity": "sha1-sGJ44h/Gw3+lMTcysEEry2rhX1E="
+ },
+ "mustache": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/mustache/-/mustache-2.2.1.tgz",
+ "integrity": "sha1-LEDKIcJ49TFQaCvPkJDkGjM5uHY="
+ },
+ "mute-stream": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
+ "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s="
+ },
+ "mux.js": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/mux.js/-/mux.js-5.1.1.tgz",
+ "integrity": "sha512-Mf/UYmh5b8jvUP+jmrTbETnyFZprMdbT0RxKm/lJ/4d2Q3xdc5GaHaRPI1zVV5D3+6uxArVPm78QEb1RsrmaQw=="
+ },
+ "nan": {
+ "version": "2.14.1",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz",
+ "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw=="
+ },
+ "nanomatch": {
+ "version": "1.2.13",
+ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
+ "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "fragment-cache": "^0.2.1",
+ "is-windows": "^1.0.2",
+ "kind-of": "^6.0.2",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+ "dev": true
+ },
+ "array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+ "dev": true
+ },
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "dev": true,
+ "requires": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ }
+ },
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4"
+ }
+ },
+ "kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true
+ }
+ }
+ },
+ "native-promise-only": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz",
+ "integrity": "sha1-IKMYwwy0X3H+et+/eyHJnBRy7xE=",
+ "dev": true
+ },
+ "natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+ "dev": true
+ },
+ "negotiator": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
+ "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=",
+ "dev": true
+ },
+ "neo-async": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.5.2.tgz",
+ "integrity": "sha512-vdqTKI9GBIYcAEbFAcpKPErKINfPF5zIuz3/niBfq8WUZjpT2tytLlFVrBgWdOtqI4uaA/Rb6No0hux39XXDuw==",
+ "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
+ },
+ "node-alias": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/node-alias/-/node-alias-1.0.4.tgz",
+ "integrity": "sha1-HxuRa1a56iQcATX5fO1pQPVW8pI=",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.1.1",
+ "lodash": "^4.2.0"
+ }
+ },
+ "node-emoji": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.8.1.tgz",
+ "integrity": "sha512-+ktMAh1Jwas+TnGodfCfjUbJKoANqPaJFN0z0iqh41eqD8dvguNzcitVSBSVK1pidz0AqGbLKcoVuVLRVZ/aVg==",
+ "optional": true,
+ "requires": {
+ "lodash.toarray": "^4.4.0"
+ }
+ },
+ "node-forge": {
+ "version": "0.7.5",
+ "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.5.tgz",
+ "integrity": "sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ==",
+ "dev": true
+ },
+ "node-gyp": {
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz",
+ "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==",
+ "dev": true,
+ "requires": {
+ "fstream": "^1.0.0",
+ "glob": "^7.0.3",
+ "graceful-fs": "^4.1.2",
+ "mkdirp": "^0.5.0",
+ "nopt": "2 || 3",
+ "npmlog": "0 || 1 || 2 || 3 || 4",
+ "osenv": "0",
+ "request": "^2.87.0",
+ "rimraf": "2",
+ "semver": "~5.3.0",
+ "tar": "^2.0.0",
+ "which": "1"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
+ "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
+ "dev": true
+ }
+ }
+ },
+ "node-libs-browser": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz",
+ "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==",
+ "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": "^1.0.0",
+ "https-browserify": "^1.0.0",
+ "os-browserify": "^0.3.0",
+ "path-browserify": "0.0.0",
+ "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.10.3",
+ "vm-browserify": "0.0.4"
+ },
+ "dependencies": {
+ "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"
+ }
+ },
+ "pako": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz",
+ "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==",
+ "dev": true
+ },
+ "process": {
+ "version": "0.11.10",
+ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+ "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=",
+ "dev": true
+ },
+ "punycode": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+ "dev": true
+ }
+ }
+ },
+ "node-notifier": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.2.1.tgz",
+ "integrity": "sha512-MIBs+AAd6dJ2SklbbE8RUDRlIVhU8MaNLh1A9SUZDUHPiZkWLFde6UNwG41yQHZEToHgJMXqyVZ9UcS/ReOVTg==",
+ "dev": true,
+ "requires": {
+ "growly": "^1.3.0",
+ "semver": "^5.4.1",
+ "shellwords": "^0.1.1",
+ "which": "^1.3.0"
+ }
+ },
+ "node-sass": {
+ "version": "4.14.0",
+ "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.14.0.tgz",
+ "integrity": "sha512-AxqU+DFpk0lEz95sI6jO0hU0Rwyw7BXVEv6o9OItoXLyeygPeaSpiV4rwQb10JiTghHaa0gZeD21sz+OsQluaw==",
+ "dev": true,
+ "requires": {
+ "async-foreach": "^0.1.3",
+ "chalk": "^1.1.1",
+ "cross-spawn": "^3.0.0",
+ "gaze": "^1.0.0",
+ "get-stdin": "^4.0.1",
+ "glob": "^7.0.3",
+ "in-publish": "^2.0.0",
+ "lodash": "^4.17.15",
+ "meow": "^3.7.0",
+ "mkdirp": "^0.5.1",
+ "nan": "^2.13.2",
+ "node-gyp": "^3.8.0",
+ "npmlog": "^4.0.0",
+ "request": "^2.88.0",
+ "sass-graph": "^2.2.4",
+ "stdout-stream": "^1.4.0",
+ "true-case-path": "^1.0.2"
+ }
+ },
+ "nodemon": {
+ "version": "1.17.5",
+ "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.17.5.tgz",
+ "integrity": "sha512-FG2mWJU1Y58a9ktgMJ/RZpsiPz3b7ge77t/okZHEa4NbrlXGKZ8s1A6Q+C7+JPXohAfcPALRwvxcAn8S874pmw==",
+ "dev": true,
+ "requires": {
+ "chokidar": "^2.0.2",
+ "debug": "^3.1.0",
+ "ignore-by-default": "^1.0.1",
+ "minimatch": "^3.0.4",
+ "pstree.remy": "^1.1.0",
+ "semver": "^5.5.0",
+ "supports-color": "^5.2.0",
+ "touch": "^3.1.0",
+ "undefsafe": "^2.0.2",
+ "update-notifier": "^2.3.0"
+ },
+ "dependencies": {
+ "anymatch": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+ "dev": true,
+ "requires": {
+ "micromatch": "^3.1.4",
+ "normalize-path": "^2.1.1"
+ }
+ },
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+ "dev": true
+ },
+ "array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+ "dev": true
+ },
+ "braces": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "chokidar": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz",
+ "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==",
+ "dev": true,
+ "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"
+ }
+ },
+ "expand-brackets": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+ "dev": true,
+ "requires": {
+ "debug": "^2.3.3",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "posix-character-classes": "^0.1.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ }
+ },
+ "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
+ }
+ }
+ },
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "dev": true,
+ "requires": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4"
+ }
+ }
+ }
+ },
+ "extglob": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+ "dev": true,
+ "requires": {
+ "array-unique": "^0.3.2",
+ "define-property": "^1.0.0",
+ "expand-brackets": "^2.1.4",
+ "extend-shallow": "^2.0.1",
+ "fragment-cache": "^0.2.1",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "glob-parent": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+ "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+ "dev": true,
+ "requires": {
+ "is-glob": "^3.1.0",
+ "path-dirname": "^1.0.0"
+ },
+ "dependencies": {
+ "is-glob": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.0"
+ }
+ }
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true
+ },
+ "is-glob": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz",
+ "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+ "dev": true
+ },
+ "micromatch": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "braces": "^2.3.1",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "extglob": "^2.0.4",
+ "fragment-cache": "^0.2.1",
+ "kind-of": "^6.0.2",
+ "nanomatch": "^1.2.9",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.2"
+ }
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "nomnom": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.8.1.tgz",
+ "integrity": "sha1-IVH3Ikcrp55Qp2/BJbuMjy5Nwqc=",
+ "requires": {
+ "chalk": "~0.4.0",
+ "underscore": "~1.6.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz",
+ "integrity": "sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg="
+ },
+ "chalk": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz",
+ "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=",
+ "requires": {
+ "ansi-styles": "~1.0.0",
+ "has-color": "~0.1.0",
+ "strip-ansi": "~0.1.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz",
+ "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE="
+ },
+ "underscore": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz",
+ "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag="
+ }
+ }
+ },
+ "nopt": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
+ "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
+ "dev": true,
+ "requires": {
+ "abbrev": "1"
+ }
+ },
+ "normalize-package-data": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
+ "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==",
+ "dev": true,
+ "requires": {
+ "hosted-git-info": "^2.1.4",
+ "is-builtin-module": "^1.0.0",
+ "semver": "2 || 3 || 4 || 5",
+ "validate-npm-package-license": "^3.0.1"
+ }
+ },
+ "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": "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"
+ }
+ },
+ "nouislider": {
+ "version": "9.2.0",
+ "resolved": "https://registry.npmjs.org/nouislider/-/nouislider-9.2.0.tgz",
+ "integrity": "sha1-6HxQfeKwtNB1A4taQlR8fbvrr2k="
+ },
+ "npm": {
+ "version": "3.10.10",
+ "resolved": "http://registry.npmjs.org/npm/-/npm-3.10.10.tgz",
+ "integrity": "sha1-Wx1XfkyIadbIYDvInpzRY3MD5G4=",
+ "dev": true,
+ "requires": {
+ "abbrev": "~1.0.9",
+ "ansi-regex": "*",
+ "ansicolors": "~0.3.2",
+ "ansistyles": "~0.1.3",
+ "aproba": "~1.0.4",
+ "archy": "~1.0.0",
+ "asap": "~2.0.5",
+ "chownr": "~1.0.1",
+ "cmd-shim": "~2.0.2",
+ "columnify": "~1.5.4",
+ "config-chain": "~1.1.11",
+ "debuglog": "*",
+ "dezalgo": "~1.0.3",
+ "editor": "~1.0.0",
+ "fs-vacuum": "~1.2.9",
+ "fs-write-stream-atomic": "~1.0.8",
+ "fstream": "~1.0.10",
+ "fstream-npm": "~1.2.0",
+ "glob": "~7.1.0",
+ "graceful-fs": "~4.1.9",
+ "has-unicode": "~2.0.1",
+ "hosted-git-info": "~2.1.5",
+ "iferr": "~0.1.5",
+ "imurmurhash": "*",
+ "inflight": "~1.0.5",
+ "inherits": "~2.0.3",
+ "ini": "~1.3.4",
+ "init-package-json": "~1.9.4",
+ "lockfile": "~1.0.2",
+ "lodash._baseindexof": "*",
+ "lodash._baseuniq": "~4.6.0",
+ "lodash._bindcallback": "*",
+ "lodash._cacheindexof": "*",
+ "lodash._createcache": "*",
+ "lodash._getnative": "*",
+ "lodash.clonedeep": "~4.5.0",
+ "lodash.restparam": "*",
+ "lodash.union": "~4.6.0",
+ "lodash.uniq": "~4.5.0",
+ "lodash.without": "~4.4.0",
+ "mkdirp": "~0.5.1",
+ "node-gyp": "~3.4.0",
+ "nopt": "~3.0.6",
+ "normalize-git-url": "~3.0.2",
+ "normalize-package-data": "~2.3.5",
+ "npm-cache-filename": "~1.0.2",
+ "npm-install-checks": "~3.0.0",
+ "npm-package-arg": "~4.2.0",
+ "npm-registry-client": "~7.2.1",
+ "npm-user-validate": "~0.1.5",
+ "npmlog": "~4.0.0",
+ "once": "~1.4.0",
+ "opener": "~1.4.2",
+ "osenv": "~0.1.3",
+ "path-is-inside": "~1.0.2",
+ "read": "~1.0.7",
+ "read-cmd-shim": "~1.0.1",
+ "read-installed": "~4.0.3",
+ "read-package-json": "~2.0.4",
+ "read-package-tree": "~5.1.5",
+ "readable-stream": "~2.1.5",
+ "readdir-scoped-modules": "*",
+ "realize-package-specifier": "~3.0.3",
+ "request": "~2.75.0",
+ "retry": "~0.10.0",
+ "rimraf": "~2.5.4",
+ "semver": "~5.3.0",
+ "sha": "~2.0.1",
+ "slide": "~1.1.6",
+ "sorted-object": "~2.0.1",
+ "strip-ansi": "~3.0.1",
+ "tar": "~2.2.1",
+ "text-table": "~0.2.0",
+ "uid-number": "0.0.6",
+ "umask": "~1.1.0",
+ "unique-filename": "~1.1.0",
+ "unpipe": "~1.0.0",
+ "validate-npm-package-license": "*",
+ "validate-npm-package-name": "~2.2.2",
+ "which": "~1.2.11",
+ "wrappy": "~1.0.2",
+ "write-file-atomic": "~1.2.0"
+ },
+ "dependencies": {
+ "abbrev": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz",
+ "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=",
+ "dev": true
+ },
+ "ansi-regex": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz",
+ "integrity": "sha1-xQYbbg74qBd15Q9dZhUb9r83EQc=",
+ "dev": true
+ },
+ "ansicolors": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz",
+ "integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=",
+ "dev": true
+ },
+ "ansistyles": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/ansistyles/-/ansistyles-0.1.3.tgz",
+ "integrity": "sha1-XeYEFb2gcbs3EnhUyGT0GyMlRTk=",
+ "dev": true
+ },
+ "aproba": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.0.4.tgz",
+ "integrity": "sha1-JxNoB3XnYUyLoYbAZdTi5S0QcsA=",
+ "dev": true
+ },
+ "archy": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
+ "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=",
+ "dev": true
+ },
+ "asap": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.5.tgz",
+ "integrity": "sha1-UidltQw1EEkOUtfc/ghe+bqWlY8=",
+ "dev": true
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "chownr": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz",
+ "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=",
+ "dev": true
+ },
+ "cmd-shim": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-2.0.2.tgz",
+ "integrity": "sha1-b8vamUg6j9FdfTChlspp1oii79s=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "mkdirp": "~0.5.0"
+ }
+ },
+ "columnify": {
+ "version": "1.5.4",
+ "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.5.4.tgz",
+ "integrity": "sha1-Rzfd8ce2mop8NAVweC6UfuyOeLs=",
+ "dev": true,
+ "requires": {
+ "strip-ansi": "^3.0.0",
+ "wcwidth": "^1.0.0"
+ },
+ "dependencies": {
+ "wcwidth": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.0.tgz",
+ "integrity": "sha1-AtBZ/3qPx0Hg9rXaHmmytA2uym8=",
+ "dev": true,
+ "requires": {
+ "defaults": "^1.0.0"
+ },
+ "dependencies": {
+ "defaults": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz",
+ "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=",
+ "dev": true,
+ "requires": {
+ "clone": "^1.0.2"
+ },
+ "dependencies": {
+ "clone": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz",
+ "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=",
+ "dev": true
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+ "dev": true
+ },
+ "config-chain": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.11.tgz",
+ "integrity": "sha1-q6CXR9++TD5w52am5BWG4YWfxvI=",
+ "dev": true,
+ "requires": {
+ "ini": "^1.3.4",
+ "proto-list": "~1.2.1"
+ },
+ "dependencies": {
+ "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
+ }
+ }
+ },
+ "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=",
+ "dev": true
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "debuglog": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz",
+ "integrity": "sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=",
+ "dev": true
+ },
+ "dezalgo": {
+ "version": "1.0.3",
+ "resolved": false,
+ "integrity": "sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=",
+ "dev": true,
+ "requires": {
+ "asap": "^2.0.0",
+ "wrappy": "1"
+ }
+ },
+ "editor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/editor/-/editor-1.0.0.tgz",
+ "integrity": "sha1-YMf4e9YrzGqJT6jM1q+3gjok90I=",
+ "dev": true
+ },
+ "fs-vacuum": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/fs-vacuum/-/fs-vacuum-1.2.9.tgz",
+ "integrity": "sha1-T5AZOrjqAokJlbzU6ARlml02ay0=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "path-is-inside": "^1.0.1",
+ "rimraf": "^2.5.2"
+ }
+ },
+ "fs-write-stream-atomic": {
+ "version": "1.0.8",
+ "resolved": false,
+ "integrity": "sha1-5Jqt3yiPh9Rv+eiC8hahOrxAd4s=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "iferr": "^0.1.5",
+ "imurmurhash": "^0.1.4",
+ "readable-stream": "1 || 2"
+ }
+ },
+ "fstream": {
+ "version": "1.0.12",
+ "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
+ "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "inherits": "~2.0.0",
+ "mkdirp": ">=0.5 0",
+ "rimraf": "2"
+ }
+ },
+ "fstream-npm": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/fstream-npm/-/fstream-npm-1.2.0.tgz",
+ "integrity": "sha1-0sPIkQE0aYLWTlcJHDhIe9qRb84=",
+ "dev": true,
+ "requires": {
+ "fstream-ignore": "^1.0.0",
+ "inherits": "2"
+ },
+ "dependencies": {
+ "fstream-ignore": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.5.tgz",
+ "integrity": "sha1-nDHa40dnAY/h0kmyTa2mfQktoQU=",
+ "dev": true,
+ "requires": {
+ "fstream": "^1.0.0",
+ "inherits": "2",
+ "minimatch": "^3.0.0"
+ },
+ "dependencies": {
+ "minimatch": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz",
+ "integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.0.0"
+ }
+ }
+ }
+ }
+ }
+ },
+ "glob": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.0.tgz",
+ "integrity": "sha1-Nq3YVtdG0NmeTMJ5e7oa4sZycv0=",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.2",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "dependencies": {
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz",
+ "integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.0.0"
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "dev": true
+ }
+ }
+ },
+ "graceful-fs": {
+ "version": "4.1.9",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.9.tgz",
+ "integrity": "sha1-uqy6N9GdEfnRRtNXi8mZWMN4fik=",
+ "dev": true
+ },
+ "has-unicode": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
+ "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
+ "dev": true
+ },
+ "hosted-git-info": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.1.5.tgz",
+ "integrity": "sha1-C6gdkNouJas0ozLm7HeTbhWYEYs=",
+ "dev": true
+ },
+ "iferr": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz",
+ "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=",
+ "dev": true
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+ "dev": true
+ },
+ "inflight": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.5.tgz",
+ "integrity": "sha1-2zIEzVqd4ubNiQuFxuL2a89PYgo=",
+ "dev": true,
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+ "dev": true
+ },
+ "ini": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz",
+ "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=",
+ "dev": true
+ },
+ "init-package-json": {
+ "version": "1.9.4",
+ "resolved": "https://registry.npmjs.org/init-package-json/-/init-package-json-1.9.4.tgz",
+ "integrity": "sha1-tAU9C0Dwz4QqQZZpN8s9wPU06FY=",
+ "dev": true,
+ "requires": {
+ "glob": "^6.0.0",
+ "npm-package-arg": "^4.0.0",
+ "promzard": "^0.3.0",
+ "read": "~1.0.1",
+ "read-package-json": "1 || 2",
+ "semver": "2.x || 3.x || 4 || 5",
+ "validate-npm-package-license": "^3.0.1",
+ "validate-npm-package-name": "^2.0.1"
+ },
+ "dependencies": {
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "glob": {
+ "version": "6.0.4",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz",
+ "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=",
+ "dev": true,
+ "requires": {
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "2 || 3",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "dependencies": {
+ "minimatch": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz",
+ "integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.0.0"
+ }
+ }
+ }
+ },
+ "promzard": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/promzard/-/promzard-0.3.0.tgz",
+ "integrity": "sha1-JqXW7ox97kyxIggwWs+5O6OCqe4=",
+ "dev": true,
+ "requires": {
+ "read": "1"
+ }
+ }
+ }
+ },
+ "is-my-json-valid": {
+ "version": "2.20.0",
+ "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.20.0.tgz",
+ "integrity": "sha512-XTHBZSIIxNsIsZXg7XB5l8z/OBFosl1Wao4tXLpeC7eKU4Vm/kdop2azkPqULwnfGQjmeDIyey9g7afMMtdWAA==",
+ "dev": true,
+ "requires": {
+ "generate-function": "^2.0.0",
+ "generate-object-property": "^1.1.0",
+ "is-my-ip-valid": "^1.0.0",
+ "jsonpointer": "^4.0.0",
+ "xtend": "^4.0.0"
+ }
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
+ "lockfile": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/lockfile/-/lockfile-1.0.2.tgz",
+ "integrity": "sha1-l+GZAXT2lsvgo6zVikO4SqMMfIM=",
+ "dev": true
+ },
+ "lodash._baseindexof": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/lodash._baseindexof/-/lodash._baseindexof-3.1.0.tgz",
+ "integrity": "sha1-/lK1OhxnYeQmGNZU5KJXie1hgiw=",
+ "dev": true
+ },
+ "lodash._baseuniq": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz",
+ "integrity": "sha1-DrtE5FaBSveQXGIS+iybLVG4Qeg=",
+ "dev": true,
+ "requires": {
+ "lodash._createset": "~4.0.0",
+ "lodash._root": "~3.0.0"
+ },
+ "dependencies": {
+ "lodash._createset": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/lodash._createset/-/lodash._createset-4.0.3.tgz",
+ "integrity": "sha1-D0ZZ+7CddRlPqeK4imZE02PJ/iY=",
+ "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._bindcallback": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz",
+ "integrity": "sha1-5THCdkTPi1epnhftlbNcdIeJOS4=",
+ "dev": true
+ },
+ "lodash._cacheindexof": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/lodash._cacheindexof/-/lodash._cacheindexof-3.0.2.tgz",
+ "integrity": "sha1-PcaayCSY0u5ePOVgkbr9Ktx73pI=",
+ "dev": true
+ },
+ "lodash._createcache": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/lodash._createcache/-/lodash._createcache-3.1.2.tgz",
+ "integrity": "sha1-VtagZAF2JeeevKa4AY4XRAvc8JM=",
+ "dev": true,
+ "requires": {
+ "lodash._getnative": "^3.0.0"
+ }
+ },
+ "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.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.restparam": {
+ "version": "3.6.1",
+ "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz",
+ "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=",
+ "dev": true
+ },
+ "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.without": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/lodash.without/-/lodash.without-4.4.0.tgz",
+ "integrity": "sha1-PNRXSgC2e643OpS3SHcmQFB7eqw=",
+ "dev": true
+ },
+ "minimist": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+ "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"
+ }
+ },
+ "node-gyp": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.4.0.tgz",
+ "integrity": "sha1-3aVYOTs+y74kyea4cDxxGUxj+jY=",
+ "dev": true,
+ "requires": {
+ "fstream": "^1.0.0",
+ "glob": "^7.0.3",
+ "graceful-fs": "^4.1.2",
+ "minimatch": "^3.0.2",
+ "mkdirp": "^0.5.0",
+ "nopt": "2 || 3",
+ "npmlog": "0 || 1 || 2 || 3",
+ "osenv": "0",
+ "path-array": "^1.0.0",
+ "request": "2",
+ "rimraf": "2",
+ "semver": "2.x || 3.x || 4 || 5",
+ "tar": "^2.0.0",
+ "which": "1"
+ },
+ "dependencies": {
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "minimatch": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz",
+ "integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.0.0"
+ }
+ },
+ "npmlog": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-3.1.2.tgz",
+ "integrity": "sha1-LUb6h0M3r5SYovErtD2NC+SjaHM=",
+ "dev": true,
+ "requires": {
+ "are-we-there-yet": "~1.1.2",
+ "console-control-strings": "~1.1.0",
+ "gauge": "~2.6.0",
+ "set-blocking": "~2.0.0"
+ },
+ "dependencies": {
+ "are-we-there-yet": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.2.tgz",
+ "integrity": "sha1-gORw6VoIR5T+GJkmLFZnxuiN4bM=",
+ "dev": true,
+ "requires": {
+ "delegates": "^1.0.0",
+ "readable-stream": "^2.0.0 || ^1.1.13"
+ },
+ "dependencies": {
+ "delegates": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
+ "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
+ "dev": true
+ }
+ }
+ },
+ "console-control-strings": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
+ "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
+ "dev": true
+ },
+ "gauge": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.6.0.tgz",
+ "integrity": "sha1-01MBrRjpaQK0dR3LvkD0IYuUKkY=",
+ "dev": true,
+ "requires": {
+ "aproba": "^1.0.3",
+ "console-control-strings": "^1.0.0",
+ "has-color": "^0.1.7",
+ "has-unicode": "^2.0.0",
+ "object-assign": "^4.1.0",
+ "signal-exit": "^3.0.0",
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1",
+ "wide-align": "^1.1.0"
+ },
+ "dependencies": {
+ "has-color": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz",
+ "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=",
+ "dev": true
+ },
+ "object-assign": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz",
+ "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=",
+ "dev": true
+ },
+ "signal-exit": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.0.tgz",
+ "integrity": "sha1-PAVDtl17T7xgts2UWT2b9DZzm+g=",
+ "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"
+ },
+ "dependencies": {
+ "code-point-at": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.0.0.tgz",
+ "integrity": "sha1-9psZLT99keOC5Lcb3bd4eGGasMY=",
+ "dev": true,
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ },
+ "dependencies": {
+ "number-is-nan": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.0.tgz",
+ "integrity": "sha1-wCD1KcUoKt/dIz2R1LGBw9aG3Es=",
+ "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"
+ },
+ "dependencies": {
+ "number-is-nan": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.0.tgz",
+ "integrity": "sha1-wCD1KcUoKt/dIz2R1LGBw9aG3Es=",
+ "dev": true
+ }
+ }
+ }
+ }
+ },
+ "wide-align": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.0.tgz",
+ "integrity": "sha1-QO3egCpx/qHwcNo+YtzaLnrdlq0=",
+ "dev": true,
+ "requires": {
+ "string-width": "^1.0.1"
+ }
+ }
+ }
+ },
+ "set-blocking": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
+ "dev": true
+ }
+ }
+ },
+ "path-array": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-array/-/path-array-1.0.1.tgz",
+ "integrity": "sha1-fi8PNfB6IBUSK4aLfqwOssT+wnE=",
+ "dev": true,
+ "requires": {
+ "array-index": "^1.0.0"
+ },
+ "dependencies": {
+ "array-index": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/array-index/-/array-index-1.0.0.tgz",
+ "integrity": "sha1-7FanSe4QPk4Ix5C5w1PfFgVbl/k=",
+ "dev": true,
+ "requires": {
+ "debug": "^2.2.0",
+ "es6-symbol": "^3.0.2"
+ },
+ "dependencies": {
+ "es6-symbol": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.0.tgz",
+ "integrity": "sha1-lEgcZV56fK2C66gy2X1UM0ltf/o=",
+ "dev": true,
+ "requires": {
+ "d": "~0.1.1",
+ "es5-ext": "~0.10.11"
+ },
+ "dependencies": {
+ "d": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/d/-/d-0.1.1.tgz",
+ "integrity": "sha1-2hhMU10Y2O57oqoim5FACfrhEwk=",
+ "dev": true,
+ "requires": {
+ "es5-ext": "~0.10.2"
+ }
+ },
+ "es5-ext": {
+ "version": "0.10.12",
+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.12.tgz",
+ "integrity": "sha1-qoRkHU23a2Krul5F/YBey6sUAEc=",
+ "dev": true,
+ "requires": {
+ "es6-iterator": "2",
+ "es6-symbol": "~3.1"
+ },
+ "dependencies": {
+ "es6-iterator": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.0.tgz",
+ "integrity": "sha1-vZaFZ9YWNeM8C4BydhPJy0sJa6w=",
+ "dev": true,
+ "requires": {
+ "d": "^0.1.1",
+ "es5-ext": "^0.10.7",
+ "es6-symbol": "3"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "nopt": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
+ "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
+ "dev": true,
+ "requires": {
+ "abbrev": "1"
+ }
+ },
+ "normalize-git-url": {
+ "version": "3.0.2",
+ "resolved": false,
+ "integrity": "sha1-jl8Uvgva7bc+ByADEKpBbCc1D8Q=",
+ "dev": true
+ },
+ "normalize-package-data": {
+ "version": "2.3.5",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.3.5.tgz",
+ "integrity": "sha1-jZJPFClg4Xd+f/4XBUNjHMfLAt8=",
+ "dev": true,
+ "requires": {
+ "hosted-git-info": "^2.1.4",
+ "is-builtin-module": "^1.0.0",
+ "semver": "2 || 3 || 4 || 5",
+ "validate-npm-package-license": "^3.0.1"
+ },
+ "dependencies": {
+ "is-builtin-module": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
+ "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
+ "dev": true,
+ "requires": {
+ "builtin-modules": "^1.0.0"
+ },
+ "dependencies": {
+ "builtin-modules": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
+ "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
+ "dev": true
+ }
+ }
+ }
+ }
+ },
+ "npm-cache-filename": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/npm-cache-filename/-/npm-cache-filename-1.0.2.tgz",
+ "integrity": "sha1-3tMGxbC/yHCp6fr4I7xfKD4FrhE=",
+ "dev": true
+ },
+ "npm-install-checks": {
+ "version": "3.0.0",
+ "resolved": false,
+ "integrity": "sha1-1K7N/VGlPjcjt7L5Oy7ijjB7wNc=",
+ "dev": true,
+ "requires": {
+ "semver": "^2.3.0 || 3.x || 4 || 5"
+ }
+ },
+ "npm-package-arg": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-4.2.0.tgz",
+ "integrity": "sha1-gJvGHKv1S9X/lPYWXIm6juiMEVw=",
+ "dev": true,
+ "requires": {
+ "hosted-git-info": "^2.1.5",
+ "semver": "^5.1.0"
+ }
+ },
+ "npm-registry-client": {
+ "version": "7.2.1",
+ "resolved": "https://registry.npmjs.org/npm-registry-client/-/npm-registry-client-7.2.1.tgz",
+ "integrity": "sha1-x5ImawiMwxP4Ul5+NSSGJscj23U=",
+ "dev": true,
+ "requires": {
+ "concat-stream": "^1.5.2",
+ "graceful-fs": "^4.1.6",
+ "normalize-package-data": "~1.0.1 || ^2.0.0",
+ "npm-package-arg": "^3.0.0 || ^4.0.0",
+ "npmlog": "~2.0.0 || ~3.1.0",
+ "once": "^1.3.3",
+ "request": "^2.74.0",
+ "retry": "^0.10.0",
+ "semver": "2 >=2.2.1 || 3.x || 4 || 5",
+ "slide": "^1.1.3"
+ },
+ "dependencies": {
+ "concat-stream": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz",
+ "integrity": "sha1-cIl4Yk2FavQaWnQd790mHadSwmY=",
+ "dev": true,
+ "requires": {
+ "inherits": "~2.0.1",
+ "readable-stream": "~2.0.0",
+ "typedarray": "~0.0.5"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz",
+ "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~1.0.6",
+ "string_decoder": "~0.10.x",
+ "util-deprecate": "~1.0.1"
+ },
+ "dependencies": {
+ "process-nextick-args": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
+ "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
+ "dev": true
+ }
+ }
+ },
+ "typedarray": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+ "dev": true
+ }
+ }
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+ "dev": true
+ },
+ "npmlog": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-3.1.2.tgz",
+ "integrity": "sha1-LUb6h0M3r5SYovErtD2NC+SjaHM=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "are-we-there-yet": "~1.1.2",
+ "console-control-strings": "~1.1.0",
+ "gauge": "~2.6.0",
+ "set-blocking": "~2.0.0"
+ },
+ "dependencies": {
+ "are-we-there-yet": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.2.tgz",
+ "integrity": "sha1-gORw6VoIR5T+GJkmLFZnxuiN4bM=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "delegates": "^1.0.0",
+ "readable-stream": "^2.0.0 || ^1.1.13"
+ },
+ "dependencies": {
+ "delegates": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
+ "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "console-control-strings": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
+ "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
+ "dev": true,
+ "optional": true
+ },
+ "gauge": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.6.0.tgz",
+ "integrity": "sha1-01MBrRjpaQK0dR3LvkD0IYuUKkY=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "aproba": "^1.0.3",
+ "console-control-strings": "^1.0.0",
+ "has-color": "^0.1.7",
+ "has-unicode": "^2.0.0",
+ "object-assign": "^4.1.0",
+ "signal-exit": "^3.0.0",
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1",
+ "wide-align": "^1.1.0"
+ },
+ "dependencies": {
+ "has-color": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz",
+ "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=",
+ "dev": true,
+ "optional": true
+ },
+ "object-assign": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz",
+ "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=",
+ "dev": true,
+ "optional": true
+ },
+ "signal-exit": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.0.tgz",
+ "integrity": "sha1-PAVDtl17T7xgts2UWT2b9DZzm+g=",
+ "dev": true,
+ "optional": 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,
+ "optional": true,
+ "requires": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ },
+ "dependencies": {
+ "code-point-at": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.0.0.tgz",
+ "integrity": "sha1-9psZLT99keOC5Lcb3bd4eGGasMY=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ },
+ "dependencies": {
+ "number-is-nan": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.0.tgz",
+ "integrity": "sha1-wCD1KcUoKt/dIz2R1LGBw9aG3Es=",
+ "dev": true,
+ "optional": 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,
+ "optional": true,
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ },
+ "dependencies": {
+ "number-is-nan": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.0.tgz",
+ "integrity": "sha1-wCD1KcUoKt/dIz2R1LGBw9aG3Es=",
+ "dev": true,
+ "optional": true
+ }
+ }
+ }
+ }
+ },
+ "wide-align": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.0.tgz",
+ "integrity": "sha1-QO3egCpx/qHwcNo+YtzaLnrdlq0=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "string-width": "^1.0.1"
+ }
+ }
+ }
+ },
+ "set-blocking": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "retry": {
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.0.tgz",
+ "integrity": "sha1-ZJ4VykCEItmDGBYZNef31lLUNd0=",
+ "dev": true
+ },
+ "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
+ }
+ }
+ },
+ "npm-user-validate": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/npm-user-validate/-/npm-user-validate-0.1.5.tgz",
+ "integrity": "sha1-UkZdUMLSApSlcSW5lrrtv1bFAEs=",
+ "dev": true
+ },
+ "npmlog": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.0.0.tgz",
+ "integrity": "sha1-4JRQOWHHDBd063ZpIIDo1Xip+I8=",
+ "dev": true,
+ "requires": {
+ "are-we-there-yet": "~1.1.2",
+ "console-control-strings": "~1.1.0",
+ "gauge": "~2.6.0",
+ "set-blocking": "~2.0.0"
+ },
+ "dependencies": {
+ "are-we-there-yet": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.2.tgz",
+ "integrity": "sha1-gORw6VoIR5T+GJkmLFZnxuiN4bM=",
+ "dev": true,
+ "requires": {
+ "delegates": "^1.0.0",
+ "readable-stream": "^2.0.0 || ^1.1.13"
+ },
+ "dependencies": {
+ "delegates": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
+ "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
+ "dev": true
+ }
+ }
+ },
+ "console-control-strings": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
+ "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
+ "dev": true
+ },
+ "gauge": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.6.0.tgz",
+ "integrity": "sha1-01MBrRjpaQK0dR3LvkD0IYuUKkY=",
+ "dev": true,
+ "requires": {
+ "aproba": "^1.0.3",
+ "console-control-strings": "^1.0.0",
+ "has-color": "^0.1.7",
+ "has-unicode": "^2.0.0",
+ "object-assign": "^4.1.0",
+ "signal-exit": "^3.0.0",
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1",
+ "wide-align": "^1.1.0"
+ },
+ "dependencies": {
+ "has-color": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz",
+ "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=",
+ "dev": true
+ },
+ "object-assign": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz",
+ "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=",
+ "dev": true
+ },
+ "signal-exit": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.0.tgz",
+ "integrity": "sha1-PAVDtl17T7xgts2UWT2b9DZzm+g=",
+ "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"
+ },
+ "dependencies": {
+ "code-point-at": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.0.0.tgz",
+ "integrity": "sha1-9psZLT99keOC5Lcb3bd4eGGasMY=",
+ "dev": true,
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ },
+ "dependencies": {
+ "number-is-nan": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.0.tgz",
+ "integrity": "sha1-wCD1KcUoKt/dIz2R1LGBw9aG3Es=",
+ "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"
+ },
+ "dependencies": {
+ "number-is-nan": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.0.tgz",
+ "integrity": "sha1-wCD1KcUoKt/dIz2R1LGBw9aG3Es=",
+ "dev": true
+ }
+ }
+ }
+ }
+ },
+ "wide-align": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.0.tgz",
+ "integrity": "sha1-QO3egCpx/qHwcNo+YtzaLnrdlq0=",
+ "dev": true,
+ "requires": {
+ "string-width": "^1.0.1"
+ }
+ }
+ }
+ },
+ "set-blocking": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
+ "dev": true
+ }
+ }
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "dev": true,
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "opener": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/opener/-/opener-1.4.2.tgz",
+ "integrity": "sha1-syWCCABCr4aAw4mkmRdbTFT/9SM=",
+ "dev": true
+ },
+ "osenv": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.3.tgz",
+ "integrity": "sha1-g88FxtZFj8TVrGNi6jJdkvJ1Qhc=",
+ "dev": true,
+ "requires": {
+ "os-homedir": "^1.0.0",
+ "os-tmpdir": "^1.0.0"
+ },
+ "dependencies": {
+ "os-homedir": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.1.tgz",
+ "integrity": "sha1-DWK99EuRb9O73PLKsZGUj7CU8Ac=",
+ "dev": true
+ },
+ "os-tmpdir": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.1.tgz",
+ "integrity": "sha1-6bQjoe2vR5iCVi6S7XHXdDoHG24=",
+ "dev": true
+ }
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz",
+ "integrity": "sha1-Jj2tpmqz8vsQv3+dJN2PPlcO+RI=",
+ "dev": true
+ },
+ "path-is-inside": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+ "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
+ "dev": true
+ },
+ "read": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz",
+ "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=",
+ "dev": true,
+ "requires": {
+ "mute-stream": "~0.0.4"
+ },
+ "dependencies": {
+ "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
+ }
+ }
+ },
+ "read-cmd-shim": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-1.0.1.tgz",
+ "integrity": "sha1-LV0Vd4ajfAVdIgd8MsU/gynpHHs=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2"
+ }
+ },
+ "read-installed": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/read-installed/-/read-installed-4.0.3.tgz",
+ "integrity": "sha1-/5uLZ/GH0eTCm5/rMfayI6zRkGc=",
+ "dev": true,
+ "requires": {
+ "debuglog": "^1.0.1",
+ "graceful-fs": "^4.1.2",
+ "read-package-json": "^2.0.0",
+ "readdir-scoped-modules": "^1.0.0",
+ "semver": "2 || 3 || 4 || 5",
+ "slide": "~1.1.3",
+ "util-extend": "^1.0.1"
+ },
+ "dependencies": {
+ "util-extend": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/util-extend/-/util-extend-1.0.3.tgz",
+ "integrity": "sha1-p8IW0mdUUWljeztu3GypEZ4v+T8=",
+ "dev": true
+ }
+ }
+ },
+ "read-package-json": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-2.0.4.tgz",
+ "integrity": "sha1-Ye0bIlbqQ42ACIlQkL6EuOeZyFM=",
+ "dev": true,
+ "requires": {
+ "glob": "^6.0.0",
+ "graceful-fs": "^4.1.2",
+ "json-parse-helpfulerror": "^1.0.2",
+ "normalize-package-data": "^2.0.0"
+ },
+ "dependencies": {
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "glob": {
+ "version": "6.0.4",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz",
+ "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=",
+ "dev": true,
+ "requires": {
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "2 || 3",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "dependencies": {
+ "minimatch": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz",
+ "integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.0.0"
+ }
+ }
+ }
+ },
+ "json-parse-helpfulerror": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/json-parse-helpfulerror/-/json-parse-helpfulerror-1.0.3.tgz",
+ "integrity": "sha1-E/FM4C7tTpgSl7ZOueO5MuLdE9w=",
+ "dev": true,
+ "requires": {
+ "jju": "^1.1.0"
+ },
+ "dependencies": {
+ "jju": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/jju/-/jju-1.3.0.tgz",
+ "integrity": "sha1-2t2e8BkkvHKLA/L3l5vb1i96Kqo=",
+ "dev": true
+ }
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz",
+ "integrity": "sha1-Jj2tpmqz8vsQv3+dJN2PPlcO+RI=",
+ "dev": true
+ }
+ }
+ },
+ "read-package-tree": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/read-package-tree/-/read-package-tree-5.1.5.tgz",
+ "integrity": "sha1-rOfmOBx2hPlwqqmPx8XStmat2rY=",
+ "dev": true,
+ "requires": {
+ "debuglog": "^1.0.1",
+ "dezalgo": "^1.0.0",
+ "once": "^1.3.0",
+ "read-package-json": "^2.0.0",
+ "readdir-scoped-modules": "^1.0.0"
+ }
+ },
+ "readable-stream": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.1.5.tgz",
+ "integrity": "sha1-ZvqLcg4UOLNkaB8q0aY8YYRIydA=",
+ "dev": true,
+ "requires": {
+ "buffer-shims": "^1.0.0",
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~1.0.6",
+ "string_decoder": "~0.10.x",
+ "util-deprecate": "~1.0.1"
+ },
+ "dependencies": {
+ "buffer-shims": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz",
+ "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=",
+ "dev": true
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
+ "process-nextick-args": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
+ "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
+ "dev": true
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+ "dev": true
+ }
+ }
+ },
+ "readdir-scoped-modules": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/readdir-scoped-modules/-/readdir-scoped-modules-1.0.2.tgz",
+ "integrity": "sha1-n6+jfShr5dksuuve4DDcm19AZ0c=",
+ "dev": true,
+ "requires": {
+ "debuglog": "^1.0.1",
+ "dezalgo": "^1.0.0",
+ "graceful-fs": "^4.1.2",
+ "once": "^1.3.0"
+ }
+ },
+ "realize-package-specifier": {
+ "version": "3.0.3",
+ "resolved": false,
+ "integrity": "sha1-0N74gpUrjeP2frpekRmWYScfQfQ=",
+ "dev": true,
+ "requires": {
+ "dezalgo": "^1.0.1",
+ "npm-package-arg": "^4.1.1"
+ }
+ },
+ "request": {
+ "version": "2.75.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.75.0.tgz",
+ "integrity": "sha1-0rgmiihtoT6qXQGt9dGMyQ9lfZM=",
+ "dev": true,
+ "requires": {
+ "aws-sign2": "~0.6.0",
+ "aws4": "^1.2.1",
+ "bl": "~1.1.2",
+ "caseless": "~0.11.0",
+ "combined-stream": "~1.0.5",
+ "extend": "~3.0.0",
+ "forever-agent": "~0.6.1",
+ "form-data": "~2.0.0",
+ "har-validator": "~2.0.6",
+ "hawk": "~3.1.3",
+ "http-signature": "~1.1.0",
+ "is-typedarray": "~1.0.0",
+ "isstream": "~0.1.2",
+ "json-stringify-safe": "~5.0.1",
+ "mime-types": "~2.1.7",
+ "node-uuid": "~1.4.7",
+ "oauth-sign": "~0.8.1",
+ "qs": "~6.2.0",
+ "stringstream": "~0.0.4",
+ "tough-cookie": "~2.3.0",
+ "tunnel-agent": "~0.4.1"
+ },
+ "dependencies": {
+ "aws-sign2": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
+ "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=",
+ "dev": true
+ },
+ "aws4": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.4.1.tgz",
+ "integrity": "sha1-/efVKSRm0jDl7g9OA42d+qsI/GE=",
+ "dev": true
+ },
+ "bl": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-1.1.2.tgz",
+ "integrity": "sha1-/cqHGplxOqANGeO7ukHER4emU5g=",
+ "dev": true,
+ "requires": {
+ "readable-stream": "~2.0.5"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz",
+ "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~1.0.6",
+ "string_decoder": "~0.10.x",
+ "util-deprecate": "~1.0.1"
+ },
+ "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=",
+ "dev": true
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ },
+ "process-nextick-args": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
+ "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
+ "dev": true
+ },
+ "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
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+ "dev": true
+ }
+ }
+ }
+ }
+ },
+ "caseless": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz",
+ "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=",
+ "dev": true
+ },
+ "combined-stream": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
+ "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
+ "dev": true,
+ "requires": {
+ "delayed-stream": "~1.0.0"
+ },
+ "dependencies": {
+ "delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+ "dev": true
+ }
+ }
+ },
+ "extend": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz",
+ "integrity": "sha1-WkdDU7nzNT3dgXbf03uRyDpG8dQ=",
+ "dev": true
+ },
+ "forever-agent": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+ "dev": true
+ },
+ "form-data": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.0.0.tgz",
+ "integrity": "sha1-bwrrrcxdoWwT4ezBETfYX5uIOyU=",
+ "dev": true,
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.5",
+ "mime-types": "^2.1.11"
+ },
+ "dependencies": {
+ "asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+ "dev": true
+ }
+ }
+ },
+ "har-validator": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz",
+ "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.1.1",
+ "commander": "^2.9.0",
+ "is-my-json-valid": "^2.12.4",
+ "pinkie-promise": "^2.0.0"
+ },
+ "dependencies": {
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "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=",
+ "dev": true
+ },
+ "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"
+ }
+ },
+ "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
+ }
+ }
+ },
+ "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"
+ },
+ "dependencies": {
+ "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
+ }
+ }
+ },
+ "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"
+ },
+ "dependencies": {
+ "pinkie": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+ "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
+ "dev": true
+ }
+ }
+ }
+ }
+ },
+ "hawk": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
+ "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
+ "dev": true,
+ "requires": {
+ "boom": "2.x.x",
+ "cryptiles": "2.x.x",
+ "hoek": "2.x.x",
+ "sntp": "1.x.x"
+ },
+ "dependencies": {
+ "boom": {
+ "version": "2.10.1",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
+ "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
+ "dev": true,
+ "requires": {
+ "hoek": "2.x.x"
+ }
+ },
+ "cryptiles": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
+ "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
+ "dev": true,
+ "requires": {
+ "boom": "2.x.x"
+ }
+ },
+ "hoek": {
+ "version": "2.16.3",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
+ "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
+ "dev": true
+ },
+ "sntp": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
+ "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=",
+ "dev": true,
+ "requires": {
+ "hoek": "2.x.x"
+ }
+ }
+ }
+ },
+ "http-signature": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
+ "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^0.2.0",
+ "jsprim": "^1.2.2",
+ "sshpk": "^1.7.0"
+ },
+ "dependencies": {
+ "assert-plus": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
+ "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
+ "dev": true
+ },
+ "jsprim": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.3.1.tgz",
+ "integrity": "sha1-KnJW9wQSop7jZwqspiWZTE3P8lI=",
+ "dev": true,
+ "requires": {
+ "extsprintf": "1.0.2",
+ "json-schema": "0.2.3",
+ "verror": "1.3.6"
+ },
+ "dependencies": {
+ "extsprintf": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz",
+ "integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=",
+ "dev": true
+ },
+ "json-schema": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+ "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+ "dev": true
+ },
+ "verror": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz",
+ "integrity": "sha1-z/XfEpRtKX0rqu+qJoniW+AcAFw=",
+ "dev": true,
+ "requires": {
+ "extsprintf": "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=",
+ "dev": true
+ },
+ "isstream": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
+ "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=",
+ "dev": true
+ },
+ "mime-types": {
+ "version": "2.1.12",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.12.tgz",
+ "integrity": "sha1-FSuiVndwIN1GY/VMLnvCY4HnFyk=",
+ "dev": true,
+ "requires": {
+ "mime-db": "~1.24.0"
+ },
+ "dependencies": {
+ "mime-db": {
+ "version": "1.24.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.24.0.tgz",
+ "integrity": "sha1-4tE/k58AFsbk6a0lqGUvEmxGfww=",
+ "dev": true
+ }
+ }
+ },
+ "node-uuid": {
+ "version": "1.4.7",
+ "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.7.tgz",
+ "integrity": "sha1-baWhdmjEs91ZYjvaEc9/pMH2Cm8=",
+ "dev": true
+ },
+ "oauth-sign": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
+ "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
+ "dev": true
+ },
+ "qs": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.1.tgz",
+ "integrity": "sha1-zgPF/wk1vB2daanxTL0Y5WjWdiU=",
+ "dev": true
+ },
+ "stringstream": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
+ "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=",
+ "dev": true
+ },
+ "tough-cookie": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.1.tgz",
+ "integrity": "sha1-mcd9+7fYBCSeiimdTLD9gf7wg/0=",
+ "dev": true
+ },
+ "tunnel-agent": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz",
+ "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=",
+ "dev": true
+ }
+ }
+ },
+ "retry": {
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.0.tgz",
+ "integrity": "sha1-ZJ4VykCEItmDGBYZNef31lLUNd0=",
+ "dev": true
+ },
+ "rimraf": {
+ "version": "2.5.4",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz",
+ "integrity": "sha1-loAAk8vxoMhr2VtGJUZ1NcKd+gQ=",
+ "dev": true,
+ "requires": {
+ "glob": "^7.0.5"
+ }
+ },
+ "semver": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
+ "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
+ "dev": true
+ },
+ "sha": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/sha/-/sha-2.0.1.tgz",
+ "integrity": "sha1-YDCCL70smCOUn49y7WQR7lzyWq4=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "readable-stream": "^2.0.2"
+ }
+ },
+ "slide": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz",
+ "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=",
+ "dev": true
+ },
+ "sorted-object": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/sorted-object/-/sorted-object-2.0.1.tgz",
+ "integrity": "sha1-fWMfS9OnmKJK8d/8+/6DM3pd9fw=",
+ "dev": true
+ },
+ "spdx-license-ids": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.0.tgz",
+ "integrity": "sha1-tUndD2Pct0Whfi6joHQC4OMy0eI=",
+ "dev": true
+ },
+ "sshpk": {
+ "version": "1.16.1",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
+ "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
+ "dev": true,
+ "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"
+ }
+ },
+ "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"
+ }
+ },
+ "tar": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
+ "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=",
+ "dev": true,
+ "requires": {
+ "block-stream": "*",
+ "fstream": "^1.0.2",
+ "inherits": "2"
+ },
+ "dependencies": {
+ "block-stream": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.8.tgz",
+ "integrity": "sha1-Boj0baK7+c/wxPaCJaDLlcvopGs=",
+ "dev": true,
+ "requires": {
+ "inherits": "~2.0.0"
+ }
+ }
+ }
+ },
+ "text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+ "dev": true
+ },
+ "uid-number": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz",
+ "integrity": "sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=",
+ "dev": true
+ },
+ "umask": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/umask/-/umask-1.1.0.tgz",
+ "integrity": "sha1-8pzr8B31F5ErtY/5xOUP3o4zMg0=",
+ "dev": true
+ },
+ "unique-filename": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.0.tgz",
+ "integrity": "sha1-0F8v5AMlYIcfMOk8vnNe6iAVFPM=",
+ "dev": true,
+ "requires": {
+ "unique-slug": "^2.0.0"
+ },
+ "dependencies": {
+ "unique-slug": {
+ "version": "2.0.0",
+ "resolved": false,
+ "integrity": "sha1-22Z258fMBimHj/GWCXx4hVrp9Ks=",
+ "dev": true,
+ "requires": {
+ "imurmurhash": "^0.1.4"
+ }
+ }
+ }
+ },
+ "unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
+ "dev": true
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+ "dev": true
+ },
+ "validate-npm-package-license": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz",
+ "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=",
+ "dev": true,
+ "requires": {
+ "spdx-correct": "~1.0.0",
+ "spdx-expression-parse": "~1.0.0"
+ },
+ "dependencies": {
+ "spdx-correct": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz",
+ "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=",
+ "dev": true,
+ "requires": {
+ "spdx-license-ids": "^1.0.2"
+ },
+ "dependencies": {
+ "spdx-license-ids": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.0.tgz",
+ "integrity": "sha1-tUndD2Pct0Whfi6joHQC4OMy0eI=",
+ "dev": true
+ }
+ }
+ },
+ "spdx-expression-parse": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.2.tgz",
+ "integrity": "sha1-1SsUtelnB3FECvIlvLVjEirEUvY=",
+ "dev": true,
+ "requires": {
+ "spdx-exceptions": "^1.0.4",
+ "spdx-license-ids": "^1.0.0"
+ },
+ "dependencies": {
+ "spdx-exceptions": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-1.0.4.tgz",
+ "integrity": "sha1-IguEI5EZrpBFqJLbgag/TOFvgP0=",
+ "dev": true
+ }
+ }
+ }
+ }
+ },
+ "validate-npm-package-name": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-2.2.2.tgz",
+ "integrity": "sha1-9laVsi9zJEQgGaPH+jmm5/0pkIU=",
+ "dev": true,
+ "requires": {
+ "builtins": "0.0.7"
+ },
+ "dependencies": {
+ "builtins": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/builtins/-/builtins-0.0.7.tgz",
+ "integrity": "sha1-NVIZzWzxjb58Acx/0tznZc/cVJo=",
+ "dev": true
+ }
+ }
+ },
+ "which": {
+ "version": "1.2.11",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.2.11.tgz",
+ "integrity": "sha1-yLLu6muMFln6fB3U/aq+lTPcXos=",
+ "dev": true,
+ "requires": {
+ "isexe": "^1.1.1"
+ },
+ "dependencies": {
+ "isexe": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-1.1.2.tgz",
+ "integrity": "sha1-NvPiLmB1CSD15yQaR2qMakInWtA=",
+ "dev": true
+ }
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+ "dev": true
+ },
+ "write-file-atomic": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.2.0.tgz",
+ "integrity": "sha1-FMZtTkyzygVlwozzt6bz5NWTj6s=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "imurmurhash": "^0.1.4",
+ "slide": "^1.1.5"
+ }
+ }
+ }
+ },
+ "npm-check-updates": {
+ "version": "2.14.2",
+ "resolved": "https://registry.npmjs.org/npm-check-updates/-/npm-check-updates-2.14.2.tgz",
+ "integrity": "sha512-kyrLnGIImPb4WK/S/4AgsxKZ21ztC9KP+6aNTZN31cGJm4+GyH+aNq7ASvvJQO3iOdg/c60qLdZVtLTOn4l0gQ==",
+ "dev": true,
+ "requires": {
+ "bluebird": "^3.4.3",
+ "chalk": "^1.1.3",
+ "cint": "^8.2.1",
+ "cli-table": "^0.3.1",
+ "commander": "^2.9.0",
+ "fast-diff": "^1.0.1",
+ "find-up": "1.1.2",
+ "get-stdin": "^5.0.1",
+ "json-parse-helpfulerror": "^1.0.3",
+ "lodash": "^4.15.0",
+ "node-alias": "^1.0.4",
+ "npm": "^3.10.6",
+ "npmi": "^2.0.1",
+ "rc-config-loader": "^2.0.1",
+ "semver": "^5.3.0",
+ "semver-utils": "^1.1.1",
+ "spawn-please": "^0.3.0",
+ "update-notifier": "^2.2.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"
+ }
+ },
+ "get-stdin": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz",
+ "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=",
+ "dev": true
+ },
+ "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"
+ }
+ }
+ }
+ },
+ "npm-run-path": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+ "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
+ "dev": true,
+ "requires": {
+ "path-key": "^2.0.0"
+ }
+ },
+ "npmi": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/npmi/-/npmi-2.0.1.tgz",
+ "integrity": "sha1-MmB2V+G9R8qFerTp2Y8KDP+WvOo=",
+ "dev": true,
+ "requires": {
+ "npm": "^3",
+ "semver": "^4.1.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "4.3.6",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz",
+ "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=",
+ "dev": true
+ }
+ }
+ },
+ "npmlog": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
+ "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
+ "dev": true,
+ "requires": {
+ "are-we-there-yet": "~1.1.2",
+ "console-control-strings": "~1.1.0",
+ "gauge": "~2.7.3",
+ "set-blocking": "~2.0.0"
+ }
+ },
+ "null-check": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz",
+ "integrity": "sha1-l33/1xdgErnsMNKjnbXPcqBDnt0=",
+ "dev": true
+ },
+ "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=",
+ "dev": true
+ },
+ "oauth-sign": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
+ },
+ "object-component": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz",
+ "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=",
+ "dev": true
+ },
+ "object-copy": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+ "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+ "dev": true,
+ "requires": {
+ "copy-descriptor": "^0.1.0",
+ "define-property": "^0.2.5",
+ "kind-of": "^3.0.3"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "object-hash": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.3.0.tgz",
+ "integrity": "sha512-05KzQ70lSeGSrZJQXE5wNDiTkBJDlUT/myi6RX9dVIvz7a7Qh4oH93BQdiPMn27nldYvVQCKMUaM83AfizZlsQ==",
+ "dev": true
+ },
+ "object-inspect": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.4.1.tgz",
+ "integrity": "sha512-wqdhLpfCUbEsoEwl3FXwGyv8ief1k/1aUdIPCqVnupM6e8l63BEJdiF/0swtn04/8p05tG/T0FrpTlfwvljOdw=="
+ },
+ "object-keys": {
+ "version": "1.0.12",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz",
+ "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag=="
+ },
+ "object-path": {
+ "version": "0.11.4",
+ "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.4.tgz",
+ "integrity": "sha1-NwrnUvvzfePqcKhhwju6iRVpGUk=",
+ "optional": true
+ },
+ "object-visit": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+ "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.0"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "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"
+ }
+ },
+ "object.omit": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz",
+ "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=",
+ "requires": {
+ "for-own": "^0.1.4",
+ "is-extendable": "^0.1.1"
+ }
+ },
+ "object.pick": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.1"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ }
+ }
+ },
+ "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"
+ }
+ },
+ "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"
+ }
+ },
+ "optimist": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
+ "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
+ "dev": true,
+ "requires": {
+ "minimist": "~0.0.1",
+ "wordwrap": "~0.0.2"
+ },
+ "dependencies": {
+ "wordwrap": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
+ "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=",
+ "dev": true
+ }
+ }
+ },
+ "optimize-css-assets-webpack-plugin": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-3.2.0.tgz",
+ "integrity": "sha512-Fjn7wyyadPAriuH2DHamDQw5B8GohEWbroBkKoPeP+vSF2PIAPI7WDihi8WieMRb/At4q7Ea7zTKaMDuSoIAAg==",
+ "dev": true,
+ "requires": {
+ "cssnano": "^3.4.0",
+ "last-call-webpack-plugin": "^2.1.2"
+ }
+ },
+ "optionator": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
+ "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
+ "requires": {
+ "deep-is": "~0.1.3",
+ "fast-levenshtein": "~2.0.4",
+ "levn": "~0.3.0",
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2",
+ "wordwrap": "~1.0.0"
+ }
+ },
+ "options": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz",
+ "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=",
+ "dev": true
+ },
+ "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": "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"
+ }
+ },
+ "os-shim": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/os-shim/-/os-shim-0.1.3.tgz",
+ "integrity": "sha1-a2LDeRz3kJ6jXtRuF2WLtBfLORc=",
+ "dev": true
+ },
+ "os-tmpdir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
+ },
+ "osenv": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
+ "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
+ "dev": true,
+ "requires": {
+ "os-homedir": "^1.0.0",
+ "os-tmpdir": "^1.0.0"
+ }
+ },
+ "output-file-sync": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-1.1.2.tgz",
+ "integrity": "sha1-0KM+7+YaIF+suQCS6CZZjVJFznY=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.4",
+ "mkdirp": "^0.5.1",
+ "object-assign": "^4.1.0"
+ }
+ },
+ "p-finally": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+ "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
+ "dev": true
+ },
+ "p-limit": {
+ "version": "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-map": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz",
+ "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==",
+ "dev": true
+ },
+ "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
+ },
+ "package-json": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz",
+ "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=",
+ "dev": true,
+ "requires": {
+ "got": "^6.7.1",
+ "registry-auth-token": "^3.0.1",
+ "registry-url": "^3.0.3",
+ "semver": "^5.1.0"
+ }
+ },
+ "package-json-versionify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/package-json-versionify/-/package-json-versionify-1.0.4.tgz",
+ "integrity": "sha1-WGBYepRIc6a35tJujlH/siMVvxc=",
+ "requires": {
+ "browserify-package-json": "^1.0.0"
+ }
+ },
+ "pako": {
+ "version": "0.2.9",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
+ "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=",
+ "optional": true
+ },
+ "parse-asn1": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz",
+ "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==",
+ "dev": true,
+ "requires": {
+ "asn1.js": "^4.0.0",
+ "browserify-aes": "^1.0.0",
+ "create-hash": "^1.1.0",
+ "evp_bytestokey": "^1.0.0",
+ "pbkdf2": "^3.0.3"
+ }
+ },
+ "parse-glob": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz",
+ "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=",
+ "requires": {
+ "glob-base": "^0.3.0",
+ "is-dotfile": "^1.0.0",
+ "is-extglob": "^1.0.0",
+ "is-glob": "^2.0.0"
+ }
+ },
+ "parse-headers": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.2.tgz",
+ "integrity": "sha512-/LypJhzFmyBIDYP9aDVgeyEb5sQfbfY5mnDq4hVhlQ69js87wXfmEI5V3xI6vvXasqebp0oCytYFLxsBVfCzSg==",
+ "requires": {
+ "for-each": "^0.3.3",
+ "string.prototype.trim": "^1.1.2"
+ }
+ },
+ "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"
+ }
+ },
+ "parsejson": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/parsejson/-/parsejson-0.0.3.tgz",
+ "integrity": "sha1-q343WfIJ7OmUN5c/fQ8fZK4OZKs=",
+ "dev": true,
+ "requires": {
+ "better-assert": "~1.0.0"
+ }
+ },
+ "parseqs": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz",
+ "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=",
+ "dev": true,
+ "requires": {
+ "better-assert": "~1.0.0"
+ }
+ },
+ "parseuri": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz",
+ "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=",
+ "dev": true,
+ "requires": {
+ "better-assert": "~1.0.0"
+ }
+ },
+ "parseurl": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
+ "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=",
+ "dev": true
+ },
+ "pascalcase": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+ "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
+ "dev": true
+ },
+ "path-browserify": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz",
+ "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=",
+ "dev": true
+ },
+ "path-dirname": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
+ "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=",
+ "dev": true
+ },
+ "path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+ "dev": true
+ },
+ "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=",
+ "dev": true
+ },
+ "path-parse": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
+ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw=="
+ },
+ "path-to-regexp": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz",
+ "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=",
+ "dev": true,
+ "requires": {
+ "isarray": "0.0.1"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+ "dev": true
+ }
+ }
+ },
+ "path-type": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
+ "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=",
+ "dev": true,
+ "requires": {
+ "pify": "^2.0.0"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "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"
+ }
+ },
+ "pbf": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.2.0.tgz",
+ "integrity": "sha512-98Eh7rsJNJF/Im6XYMLaOW3cLnNyedlOd6hu3iWMD5I7FZGgpw8yN3vQBrmLbLodu7G784Irb9Qsv2yFrxSAGw==",
+ "requires": {
+ "ieee754": "^1.1.12",
+ "resolve-protobuf-schema": "^2.1.0"
+ }
+ },
+ "pbkdf2": {
+ "version": "3.0.16",
+ "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.16.tgz",
+ "integrity": "sha512-y4CXP3thSxqf7c0qmOF+9UeOTrifiVTIM+u7NWlq+PRsHbr7r7dpCmvzrZxa96JJUNi0Y5w9VqG5ZNeCVMoDcA==",
+ "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"
+ }
+ },
+ "peek-stream": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/peek-stream/-/peek-stream-1.1.3.tgz",
+ "integrity": "sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA==",
+ "optional": true,
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "duplexify": "^3.5.0",
+ "through2": "^2.0.3"
+ }
+ },
+ "pend": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+ "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
+ "dev": true
+ },
+ "performance-now": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
+ },
+ "phantomjs-polyfill": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/phantomjs-polyfill/-/phantomjs-polyfill-0.0.2.tgz",
+ "integrity": "sha1-jGpxY+m8j9n/2+fWBctTUvn7iR4=",
+ "dev": true
+ },
+ "phantomjs-prebuilt": {
+ "version": "2.1.16",
+ "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz",
+ "integrity": "sha1-79ISpKOWbTZHaE6ouniFSb4q7+8=",
+ "dev": true,
+ "requires": {
+ "es6-promise": "^4.0.3",
+ "extract-zip": "^1.6.5",
+ "fs-extra": "^1.0.0",
+ "hasha": "^2.2.0",
+ "kew": "^0.7.0",
+ "progress": "^1.1.8",
+ "request": "^2.81.0",
+ "request-progress": "^2.0.1",
+ "which": "^1.2.10"
+ }
+ },
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "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"
+ }
+ },
+ "pkcs7": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/pkcs7/-/pkcs7-1.0.2.tgz",
+ "integrity": "sha1-ttulJ1KMKUK/wSLOLa/NteWQdOc="
+ },
+ "pkg-dir": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz",
+ "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=",
+ "dev": true,
+ "requires": {
+ "find-up": "^2.1.0"
+ }
+ },
+ "pluralize": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz",
+ "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==",
+ "dev": true
+ },
+ "point-in-polygon": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/point-in-polygon/-/point-in-polygon-1.0.1.tgz",
+ "integrity": "sha1-1Ztk6P7kHElFiqyCtWcYxZV7Kvc="
+ },
+ "portfinder": {
+ "version": "1.0.25",
+ "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.25.tgz",
+ "integrity": "sha512-6ElJnHBbxVA1XSLgBp7G1FiCkQdlqGzuF7DswL5tcea+E8UpuvPU7beVAjjRwCioTS9ZluNbu+ZyRvgTsmqEBg==",
+ "dev": true,
+ "requires": {
+ "async": "^2.6.2",
+ "debug": "^3.1.1",
+ "mkdirp": "^0.5.1"
+ },
+ "dependencies": {
+ "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"
+ }
+ },
+ "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"
+ }
+ },
+ "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
+ }
+ }
+ },
+ "posix-character-classes": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.1.3",
+ "js-base64": "^2.1.9",
+ "source-map": "^0.5.6",
+ "supports-color": "^3.2.3"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "dev": true,
+ "requires": {
+ "has-flag": "^1.0.0"
+ }
+ }
+ }
+ },
+ "postcss-calc": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz",
+ "integrity": "sha1-d7rnypKK2FcW4v2kLyYb98HWW14=",
+ "dev": true,
+ "requires": {
+ "postcss": "^5.0.2",
+ "postcss-message-helpers": "^2.0.0",
+ "reduce-css-calc": "^1.2.6"
+ }
+ },
+ "postcss-colormin": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-2.2.2.tgz",
+ "integrity": "sha1-ZjFBfV8OkJo9fsJrJMio0eT5bks=",
+ "dev": true,
+ "requires": {
+ "colormin": "^1.0.5",
+ "postcss": "^5.0.13",
+ "postcss-value-parser": "^3.2.3"
+ }
+ },
+ "postcss-convert-values": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz",
+ "integrity": "sha1-u9hZPFwf0uPRwyK7kl3K6Nrk1i0=",
+ "dev": true,
+ "requires": {
+ "postcss": "^5.0.11",
+ "postcss-value-parser": "^3.1.2"
+ }
+ },
+ "postcss-discard-comments": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz",
+ "integrity": "sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0=",
+ "dev": true,
+ "requires": {
+ "postcss": "^5.0.14"
+ }
+ },
+ "postcss-discard-duplicates": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz",
+ "integrity": "sha1-uavye4isGIFYpesSq8riAmO5GTI=",
+ "dev": true,
+ "requires": {
+ "postcss": "^5.0.4"
+ }
+ },
+ "postcss-discard-empty": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz",
+ "integrity": "sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU=",
+ "dev": true,
+ "requires": {
+ "postcss": "^5.0.14"
+ }
+ },
+ "postcss-discard-overridden": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz",
+ "integrity": "sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg=",
+ "dev": true,
+ "requires": {
+ "postcss": "^5.0.16"
+ }
+ },
+ "postcss-discard-unused": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz",
+ "integrity": "sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM=",
+ "dev": true,
+ "requires": {
+ "postcss": "^5.0.14",
+ "uniqs": "^2.0.0"
+ }
+ },
+ "postcss-filter-plugins": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-filter-plugins/-/postcss-filter-plugins-2.0.3.tgz",
+ "integrity": "sha512-T53GVFsdinJhgwm7rg1BzbeBRomOg9y5MBVhGcsV0CxurUdVj1UlPdKtn7aqYA/c/QVkzKMjq2bSV5dKG5+AwQ==",
+ "dev": true,
+ "requires": {
+ "postcss": "^5.0.4"
+ }
+ },
+ "postcss-load-config": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-1.2.0.tgz",
+ "integrity": "sha1-U56a/J3chiASHr+djDZz4M5Q0oo=",
+ "dev": true,
+ "requires": {
+ "cosmiconfig": "^2.1.0",
+ "object-assign": "^4.1.0",
+ "postcss-load-options": "^1.2.0",
+ "postcss-load-plugins": "^2.3.0"
+ }
+ },
+ "postcss-load-options": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-load-options/-/postcss-load-options-1.2.0.tgz",
+ "integrity": "sha1-sJixVZ3awt8EvAuzdfmaXP4rbYw=",
+ "dev": true,
+ "requires": {
+ "cosmiconfig": "^2.1.0",
+ "object-assign": "^4.1.0"
+ }
+ },
+ "postcss-load-plugins": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/postcss-load-plugins/-/postcss-load-plugins-2.3.0.tgz",
+ "integrity": "sha1-dFdoEWWZrKLwCfrUJrABdQSdjZI=",
+ "dev": true,
+ "requires": {
+ "cosmiconfig": "^2.1.1",
+ "object-assign": "^4.1.0"
+ }
+ },
+ "postcss-loader": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.1.5.tgz",
+ "integrity": "sha512-pV7kB5neJ0/1tZ8L1uGOBNTVBCSCXQoIsZMsrwvO8V2rKGa2tBl/f80GGVxow2jJnRJ2w1ocx693EKhZAb9Isg==",
+ "dev": true,
+ "requires": {
+ "loader-utils": "^1.1.0",
+ "postcss": "^6.0.0",
+ "postcss-load-config": "^1.2.0",
+ "schema-utils": "^0.4.0"
+ },
+ "dependencies": {
+ "ajv": {
+ "version": "6.5.3",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.3.tgz",
+ "integrity": "sha512-LqZ9wY+fx3UMiiPd741yB2pj3hhil+hQc8taf4o2QGRFpWgZ2V5C8HA165DY9sS3fJwsk7uT7ZlFEyC3Ig3lLg==",
+ "dev": true,
+ "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-keywords": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz",
+ "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.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=",
+ "dev": true
+ },
+ "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
+ },
+ "postcss": {
+ "version": "6.0.23",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz",
+ "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.1",
+ "source-map": "^0.6.1",
+ "supports-color": "^5.4.0"
+ }
+ },
+ "schema-utils": {
+ "version": "0.4.7",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz",
+ "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.1.0",
+ "ajv-keywords": "^3.1.0"
+ }
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "postcss-merge-idents": {
+ "version": "2.1.7",
+ "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz",
+ "integrity": "sha1-TFUwMTwI4dWzu/PSu8dH4njuonA=",
+ "dev": true,
+ "requires": {
+ "has": "^1.0.1",
+ "postcss": "^5.0.10",
+ "postcss-value-parser": "^3.1.1"
+ }
+ },
+ "postcss-merge-longhand": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz",
+ "integrity": "sha1-I9kM0Sewp3mUkVMyc5A0oaTz1lg=",
+ "dev": true,
+ "requires": {
+ "postcss": "^5.0.4"
+ }
+ },
+ "postcss-merge-rules": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz",
+ "integrity": "sha1-0d9d+qexrMO+VT8OnhDofGG19yE=",
+ "dev": true,
+ "requires": {
+ "browserslist": "^1.5.2",
+ "caniuse-api": "^1.5.2",
+ "postcss": "^5.0.4",
+ "postcss-selector-parser": "^2.2.2",
+ "vendors": "^1.0.0"
+ }
+ },
+ "postcss-message-helpers": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz",
+ "integrity": "sha1-pPL0+rbk/gAvCu0ABHjN9S+bpg4=",
+ "dev": true
+ },
+ "postcss-minify-font-values": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz",
+ "integrity": "sha1-S1jttWZB66fIR0qzUmyv17vey2k=",
+ "dev": true,
+ "requires": {
+ "object-assign": "^4.0.1",
+ "postcss": "^5.0.4",
+ "postcss-value-parser": "^3.0.2"
+ }
+ },
+ "postcss-minify-gradients": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz",
+ "integrity": "sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE=",
+ "dev": true,
+ "requires": {
+ "postcss": "^5.0.12",
+ "postcss-value-parser": "^3.3.0"
+ }
+ },
+ "postcss-minify-params": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz",
+ "integrity": "sha1-rSzgcTc7lDs9kwo/pZo1jCjW8fM=",
+ "dev": true,
+ "requires": {
+ "alphanum-sort": "^1.0.1",
+ "postcss": "^5.0.2",
+ "postcss-value-parser": "^3.0.2",
+ "uniqs": "^2.0.0"
+ }
+ },
+ "postcss-minify-selectors": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz",
+ "integrity": "sha1-ssapjAByz5G5MtGkllCBFDEXNb8=",
+ "dev": true,
+ "requires": {
+ "alphanum-sort": "^1.0.2",
+ "has": "^1.0.1",
+ "postcss": "^5.0.14",
+ "postcss-selector-parser": "^2.0.0"
+ }
+ },
+ "postcss-modules-extract-imports": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.0.tgz",
+ "integrity": "sha1-ZhQOzs447wa/DT41XWm/WdFB6oU=",
+ "dev": true,
+ "requires": {
+ "postcss": "^6.0.1"
+ },
+ "dependencies": {
+ "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==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "postcss": {
+ "version": "6.0.23",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz",
+ "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.1",
+ "source-map": "^0.6.1",
+ "supports-color": "^5.4.0"
+ }
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "postcss-modules-local-by-default": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz",
+ "integrity": "sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk=",
+ "dev": true,
+ "requires": {
+ "css-selector-tokenizer": "^0.7.0",
+ "postcss": "^6.0.1"
+ },
+ "dependencies": {
+ "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==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "postcss": {
+ "version": "6.0.23",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz",
+ "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.1",
+ "source-map": "^0.6.1",
+ "supports-color": "^5.4.0"
+ }
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "postcss-modules-scope": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz",
+ "integrity": "sha1-1upkmUx5+XtipytCb75gVqGUu5A=",
+ "dev": true,
+ "requires": {
+ "css-selector-tokenizer": "^0.7.0",
+ "postcss": "^6.0.1"
+ },
+ "dependencies": {
+ "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==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "postcss": {
+ "version": "6.0.23",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz",
+ "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.1",
+ "source-map": "^0.6.1",
+ "supports-color": "^5.4.0"
+ }
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "postcss-modules-values": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz",
+ "integrity": "sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA=",
+ "dev": true,
+ "requires": {
+ "icss-replace-symbols": "^1.1.0",
+ "postcss": "^6.0.1"
+ },
+ "dependencies": {
+ "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==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "postcss": {
+ "version": "6.0.23",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz",
+ "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.1",
+ "source-map": "^0.6.1",
+ "supports-color": "^5.4.0"
+ }
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "postcss-normalize-charset": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz",
+ "integrity": "sha1-757nEhLX/nWceO0WL2HtYrXLk/E=",
+ "dev": true,
+ "requires": {
+ "postcss": "^5.0.5"
+ }
+ },
+ "postcss-normalize-url": {
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz",
+ "integrity": "sha1-EI90s/L82viRov+j6kWSJ5/HgiI=",
+ "dev": true,
+ "requires": {
+ "is-absolute-url": "^2.0.0",
+ "normalize-url": "^1.4.0",
+ "postcss": "^5.0.14",
+ "postcss-value-parser": "^3.2.3"
+ }
+ },
+ "postcss-ordered-values": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz",
+ "integrity": "sha1-7sbCpntsQSqNsgQud/6NpD+VwR0=",
+ "dev": true,
+ "requires": {
+ "postcss": "^5.0.4",
+ "postcss-value-parser": "^3.0.1"
+ }
+ },
+ "postcss-reduce-idents": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz",
+ "integrity": "sha1-wsbSDMlYKE9qv75j92Cb9AkFmtM=",
+ "dev": true,
+ "requires": {
+ "postcss": "^5.0.4",
+ "postcss-value-parser": "^3.0.2"
+ }
+ },
+ "postcss-reduce-initial": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz",
+ "integrity": "sha1-aPgGlfBF0IJjqHmtJA343WT2ROo=",
+ "dev": true,
+ "requires": {
+ "postcss": "^5.0.4"
+ }
+ },
+ "postcss-reduce-transforms": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz",
+ "integrity": "sha1-/3b02CEkN7McKYpC0uFEQCV3GuE=",
+ "dev": true,
+ "requires": {
+ "has": "^1.0.1",
+ "postcss": "^5.0.8",
+ "postcss-value-parser": "^3.0.1"
+ }
+ },
+ "postcss-selector-parser": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz",
+ "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=",
+ "dev": true,
+ "requires": {
+ "flatten": "^1.0.2",
+ "indexes-of": "^1.0.1",
+ "uniq": "^1.0.1"
+ }
+ },
+ "postcss-svgo": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz",
+ "integrity": "sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0=",
+ "dev": true,
+ "requires": {
+ "is-svg": "^2.0.0",
+ "postcss": "^5.0.14",
+ "postcss-value-parser": "^3.2.3",
+ "svgo": "^0.7.0"
+ }
+ },
+ "postcss-unique-selectors": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz",
+ "integrity": "sha1-mB1X0p3csz57Hf4f1DuGSfkzyh0=",
+ "dev": true,
+ "requires": {
+ "alphanum-sort": "^1.0.1",
+ "postcss": "^5.0.4",
+ "uniqs": "^2.0.0"
+ }
+ },
+ "postcss-value-parser": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz",
+ "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=",
+ "dev": true
+ },
+ "postcss-zindex": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-2.2.0.tgz",
+ "integrity": "sha1-0hCd3AVbka9n/EyzsCWUZjnSryI=",
+ "dev": true,
+ "requires": {
+ "has": "^1.0.1",
+ "postcss": "^5.0.4",
+ "uniqs": "^2.0.0"
+ }
+ },
+ "potpack": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/potpack/-/potpack-1.0.1.tgz",
+ "integrity": "sha512-15vItUAbViaYrmaB/Pbw7z6qX2xENbFSTA7Ii4tgbPtasxm5v6ryKhKtL91tpWovDJzTiZqdwzhcFBCwiMVdVw=="
+ },
+ "pre-commit": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/pre-commit/-/pre-commit-1.2.2.tgz",
+ "integrity": "sha1-287g7p3nI15X95xW186UZBpp7sY=",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^5.0.1",
+ "spawn-sync": "^1.0.15",
+ "which": "1.2.x"
+ },
+ "dependencies": {
+ "cross-spawn": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
+ "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^4.0.1",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ }
+ },
+ "which": {
+ "version": "1.2.14",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz",
+ "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ }
+ }
+ },
+ "prelude-ls": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
+ },
+ "prepend-http": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
+ "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
+ "dev": true
+ },
+ "preserve": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz",
+ "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks="
+ },
+ "private": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
+ "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==",
+ "dev": true
+ },
+ "process": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz",
+ "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8="
+ },
+ "process-nextick-args": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
+ "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
+ },
+ "progress": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz",
+ "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=",
+ "dev": true
+ },
+ "prop-types": {
+ "version": "15.6.2",
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.2.tgz",
+ "integrity": "sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ==",
+ "dev": true,
+ "requires": {
+ "loose-envify": "^1.3.1",
+ "object-assign": "^4.1.1"
+ }
+ },
+ "proper-lockfile": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-2.0.1.tgz",
+ "integrity": "sha1-FZ+wYZPTIAP0s2kd0uwaY0qoDR0=",
+ "optional": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "retry": "^0.10.0"
+ }
+ },
+ "protocol-buffers-schema": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.3.2.tgz",
+ "integrity": "sha512-Xdayp8sB/mU+sUV4G7ws8xtYMGdQnxbeIfLjyO9TZZRJdztBGhlmbI5x1qcY4TG5hBkIKGnc28i7nXxaugu88w=="
+ },
+ "proxy-addr": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz",
+ "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==",
+ "dev": true,
+ "requires": {
+ "forwarded": "~0.1.2",
+ "ipaddr.js": "1.9.0"
+ }
+ },
+ "prr": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
+ "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
+ "dev": true
+ },
+ "ps-tree": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.1.0.tgz",
+ "integrity": "sha1-tCGyQUDWID8e08dplrRCewjowBQ=",
+ "dev": true,
+ "requires": {
+ "event-stream": "~3.3.0"
+ }
+ },
+ "pseudomap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
+ "dev": true
+ },
+ "psl": {
+ "version": "1.1.29",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz",
+ "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ=="
+ },
+ "pstree.remy": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.0.tgz",
+ "integrity": "sha512-q5I5vLRMVtdWa8n/3UEzZX7Lfghzrg9eG2IKk2ENLSofKRCXVqMvMUHxCKgXNaqH/8ebhBxrqftHWnyTFweJ5Q==",
+ "dev": true,
+ "requires": {
+ "ps-tree": "^1.1.0"
+ }
+ },
+ "public-encrypt": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz",
+ "integrity": "sha512-4kJ5Esocg8X3h8YgJsKAuoesBgB7mqH3eowiDzMUPKiRDDE7E/BqqZD1hnTByIaAFiwAw246YEltSq7tdrOH0Q==",
+ "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"
+ }
+ },
+ "pump": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
+ "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
+ "optional": true,
+ "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==",
+ "optional": true,
+ "requires": {
+ "duplexify": "^3.6.0",
+ "inherits": "^2.0.3",
+ "pump": "^2.0.0"
+ }
+ },
+ "punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
+ },
+ "pym.js": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/pym.js/-/pym.js-1.3.2.tgz",
+ "integrity": "sha512-/fFzHFB4BTsJQP5id0wzUdYsDT4VPkfAxk+uENBE9/aP6YbvhAEpcuJHdjxqisqfXOCrcz7duTK1fbtF2rz8RQ=="
+ },
+ "q": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
+ "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
+ "dev": true
+ },
+ "qjobs": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz",
+ "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==",
+ "dev": true
+ },
+ "qs": {
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
+ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
+ },
+ "query-string": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz",
+ "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=",
+ "dev": true,
+ "requires": {
+ "object-assign": "^4.1.0",
+ "strict-uri-encode": "^1.0.0"
+ }
+ },
+ "querystring": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
+ "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
+ "dev": true
+ },
+ "querystring-es3": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
+ "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=",
+ "dev": true
+ },
+ "querystringify": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz",
+ "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==",
+ "dev": true
+ },
+ "quickselect": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-1.1.1.tgz",
+ "integrity": "sha512-qN0Gqdw4c4KGPsBOQafj6yj/PA6c/L63f6CaZ/DCF/xF4Esu3jVmKLUDYxghFx8Kb/O7y9tI7x2RjTSXwdK1iQ=="
+ },
+ "quote-stream": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/quote-stream/-/quote-stream-1.0.2.tgz",
+ "integrity": "sha1-hJY/jJwmuULhU/7rU6rnRlK34LI=",
+ "requires": {
+ "buffer-equal": "0.0.1",
+ "minimist": "^1.1.3",
+ "through2": "^2.0.0"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
+ }
+ }
+ },
+ "randomatic": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.0.tgz",
+ "integrity": "sha512-KnGPVE0lo2WoXxIZ7cPR8YBpiol4gsSuOwDSg410oHh80ZMp5EiypNqL2K4Z77vJn6lB5rap7IkAmcUlalcnBQ==",
+ "requires": {
+ "is-number": "^4.0.0",
+ "kind-of": "^6.0.0",
+ "math-random": "^1.0.1"
+ },
+ "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=="
+ },
+ "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=="
+ }
+ }
+ },
+ "randombytes": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz",
+ "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==",
+ "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.0",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
+ "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=",
+ "dev": true
+ },
+ "raw-body": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz",
+ "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==",
+ "dev": true,
+ "requires": {
+ "bytes": "3.0.0",
+ "http-errors": "1.6.3",
+ "iconv-lite": "0.4.23",
+ "unpipe": "1.0.0"
+ },
+ "dependencies": {
+ "bytes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+ "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
+ "dev": true
+ },
+ "iconv-lite": {
+ "version": "0.4.23",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz",
+ "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==",
+ "dev": true,
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
+ }
+ }
+ },
+ "rbush": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/rbush/-/rbush-2.0.2.tgz",
+ "integrity": "sha512-XBOuALcTm+O/H8G90b6pzu6nX6v2zCKiFG4BJho8a+bY6AER6t8uQUZdi5bomQc0AprCWhEGa7ncAbbRap0bRA==",
+ "requires": {
+ "quickselect": "^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"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+ "dev": true
+ }
+ }
+ },
+ "rc-config-loader": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/rc-config-loader/-/rc-config-loader-2.0.2.tgz",
+ "integrity": "sha512-Nx9SNM47eNRqe0TdntOY600qWb8NDh+xU9sv5WnTscEtzfTB0ukihlqwuCLPteyJksvZ0sEVPoySNE01TKrmTQ==",
+ "dev": true,
+ "requires": {
+ "debug": "^3.1.0",
+ "js-yaml": "^3.12.0",
+ "json5": "^1.0.1",
+ "object-assign": "^4.1.0",
+ "object-keys": "^1.0.12",
+ "path-exists": "^3.0.0",
+ "require-from-string": "^2.0.2"
+ },
+ "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"
+ }
+ },
+ "minimist": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+ "dev": true
+ }
+ }
+ },
+ "read": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz",
+ "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=",
+ "optional": true,
+ "requires": {
+ "mute-stream": "~0.0.4"
+ }
+ },
+ "read-pkg": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
+ "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=",
+ "dev": true,
+ "requires": {
+ "load-json-file": "^2.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^2.0.0"
+ }
+ },
+ "read-pkg-up": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz",
+ "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=",
+ "dev": true,
+ "requires": {
+ "find-up": "^2.0.0",
+ "read-pkg": "^2.0.0"
+ }
+ },
+ "readable-stream": {
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+ "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"
+ }
+ },
+ "readdirp": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz",
+ "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "minimatch": "^3.0.2",
+ "readable-stream": "^2.0.2",
+ "set-immediate-shim": "^1.0.1"
+ }
+ },
+ "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"
+ }
+ },
+ "redeyed": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-0.4.4.tgz",
+ "integrity": "sha1-N+mQpvKyGyoRwuakj9QTVpjLqX8=",
+ "requires": {
+ "esprima": "~1.0.4"
+ }
+ },
+ "reduce-css-calc": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz",
+ "integrity": "sha1-dHyRTgSWFKTJz7umKYca0dKSdxY=",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^0.4.2",
+ "math-expression-evaluator": "^1.2.14",
+ "reduce-function-call": "^1.0.1"
+ },
+ "dependencies": {
+ "balanced-match": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
+ "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=",
+ "dev": true
+ }
+ }
+ },
+ "reduce-function-call": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.2.tgz",
+ "integrity": "sha1-WiAL+S4ON3UXUv5FsKszD9S2vpk=",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^0.4.2"
+ },
+ "dependencies": {
+ "balanced-match": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
+ "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=",
+ "dev": true
+ }
+ }
+ },
+ "regenerate": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz",
+ "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==",
+ "dev": true
+ },
+ "regenerator-runtime": {
+ "version": "0.11.1",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
+ "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
+ },
+ "regenerator-transform": {
+ "version": "0.10.1",
+ "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz",
+ "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.18.0",
+ "babel-types": "^6.19.0",
+ "private": "^0.1.6"
+ }
+ },
+ "regex-cache": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz",
+ "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==",
+ "requires": {
+ "is-equal-shallow": "^0.1.3"
+ }
+ },
+ "regex-not": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+ "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^3.0.2",
+ "safe-regex": "^1.1.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "dev": true,
+ "requires": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ }
+ },
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4"
+ }
+ }
+ }
+ },
+ "regex-parser": {
+ "version": "2.2.9",
+ "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.9.tgz",
+ "integrity": "sha512-VncXxOF6uFlYog5prG2j+e2UGJeam5MfNiJnB/qEgo4KTnMm2XrELCg4rNZ6IlaEUZnGlb8aB6lXowCRQtTkkA==",
+ "dev": true
+ },
+ "regexpu-core": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz",
+ "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=",
+ "dev": true,
+ "requires": {
+ "regenerate": "^1.2.1",
+ "regjsgen": "^0.2.0",
+ "regjsparser": "^0.1.4"
+ }
+ },
+ "registry-auth-token": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz",
+ "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==",
+ "dev": true,
+ "requires": {
+ "rc": "^1.1.6",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "registry-url": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz",
+ "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=",
+ "dev": true,
+ "requires": {
+ "rc": "^1.0.1"
+ }
+ },
+ "regjsgen": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
+ "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=",
+ "dev": true
+ },
+ "regjsparser": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz",
+ "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=",
+ "dev": true,
+ "requires": {
+ "jsesc": "~0.5.0"
+ },
+ "dependencies": {
+ "jsesc": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+ "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
+ "dev": true
+ }
+ }
+ },
+ "remove-trailing-separator": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
+ "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8="
+ },
+ "repeat-element": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
+ "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g=="
+ },
+ "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"
+ }
+ },
+ "request": {
+ "version": "2.88.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
+ "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
+ "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"
+ }
+ },
+ "request-capture-har": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/request-capture-har/-/request-capture-har-1.2.2.tgz",
+ "integrity": "sha1-zWks+yzHRP2EozWKrG7lFSjPcg0=",
+ "optional": true
+ },
+ "request-progress": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz",
+ "integrity": "sha1-XTa7V5YcZzqlt4jbyBQf3yO0Tgg=",
+ "dev": true,
+ "requires": {
+ "throttleit": "^1.0.0"
+ }
+ },
+ "require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+ "dev": true
+ },
+ "require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "dev": true
+ },
+ "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
+ },
+ "require-uncached": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
+ "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=",
+ "dev": true,
+ "requires": {
+ "caller-path": "^0.1.0",
+ "resolve-from": "^1.0.0"
+ }
+ },
+ "requires-port": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+ "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
+ "dev": true
+ },
+ "resolve": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz",
+ "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==",
+ "requires": {
+ "path-parse": "^1.0.5"
+ }
+ },
+ "resolve-cwd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz",
+ "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=",
+ "dev": true,
+ "requires": {
+ "resolve-from": "^3.0.0"
+ },
+ "dependencies": {
+ "resolve-from": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
+ "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
+ "dev": true
+ }
+ }
+ },
+ "resolve-from": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz",
+ "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=",
+ "dev": true
+ },
+ "resolve-protobuf-schema": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz",
+ "integrity": "sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==",
+ "requires": {
+ "protocol-buffers-schema": "^3.3.1"
+ }
+ },
+ "resolve-url": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
+ "dev": true
+ },
+ "resolve-url-loader": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-2.3.0.tgz",
+ "integrity": "sha512-RaEUWgF/B6aTg9VKaOv2o6dfm5f75/lGh8S+SQwoMcBm48WkA2nhLR+V7KEawkxXjU4lLB16IVeHCe7F69nyVw==",
+ "dev": true,
+ "requires": {
+ "adjust-sourcemap-loader": "^1.1.0",
+ "camelcase": "^4.1.0",
+ "convert-source-map": "^1.5.1",
+ "loader-utils": "^1.1.0",
+ "lodash.defaults": "^4.0.0",
+ "rework": "^1.0.1",
+ "rework-visit": "^1.0.0",
+ "source-map": "^0.5.7",
+ "urix": "^0.1.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
+ }
+ }
+ },
+ "rest": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/rest/-/rest-2.0.0.tgz",
+ "integrity": "sha1-bfrfZqQFxJz71bS9JbWf0pzYYbw="
+ },
+ "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==",
+ "dev": true
+ },
+ "retry": {
+ "version": "0.10.1",
+ "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz",
+ "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=",
+ "optional": true
+ },
+ "rework": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/rework/-/rework-1.0.1.tgz",
+ "integrity": "sha1-MIBqhBNCtUUQqkEQhQzUhTQUSqc=",
+ "dev": true,
+ "requires": {
+ "convert-source-map": "^0.3.3",
+ "css": "^2.0.0"
+ },
+ "dependencies": {
+ "convert-source-map": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-0.3.5.tgz",
+ "integrity": "sha1-8dgClQr33SYxof6+BZZVDIarMZA=",
+ "dev": true
+ }
+ }
+ },
+ "rework-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/rework-visit/-/rework-visit-1.0.0.tgz",
+ "integrity": "sha1-mUWygD8hni96ygCtuLyfZA+ELJo=",
+ "dev": true
+ },
+ "right-align": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
+ "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
+ "dev": true,
+ "requires": {
+ "align-text": "^0.1.1"
+ }
+ },
+ "rimraf": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
+ "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
+ "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"
+ }
+ },
+ "robust-orientation": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/robust-orientation/-/robust-orientation-1.1.3.tgz",
+ "integrity": "sha1-2v9bANO+TmByLw6cAVbvln8cIEk=",
+ "requires": {
+ "robust-scale": "^1.0.2",
+ "robust-subtract": "^1.0.0",
+ "robust-sum": "^1.0.0",
+ "two-product": "^1.0.2"
+ }
+ },
+ "robust-scale": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/robust-scale/-/robust-scale-1.0.2.tgz",
+ "integrity": "sha1-d1Ey7QlULQKOWLLMecBikLz3jDI=",
+ "requires": {
+ "two-product": "^1.0.2",
+ "two-sum": "^1.0.0"
+ }
+ },
+ "robust-subtract": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/robust-subtract/-/robust-subtract-1.0.0.tgz",
+ "integrity": "sha1-4LFk4e2LpOOl3aRaEgODSNvtPpo="
+ },
+ "robust-sum": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/robust-sum/-/robust-sum-1.0.0.tgz",
+ "integrity": "sha1-FmRuUlKStNJdgnV6KGlV4Lv6U9k="
+ },
+ "run-async": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz",
+ "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=",
+ "requires": {
+ "is-promise": "^2.1.0"
+ }
+ },
+ "rust-result": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/rust-result/-/rust-result-1.0.0.tgz",
+ "integrity": "sha1-NMdbLm3Dn+WHXlveyFteD5FTb3I=",
+ "requires": {
+ "individual": "^2.0.0"
+ }
+ },
+ "rw": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz",
+ "integrity": "sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q="
+ },
+ "rx": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz",
+ "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I="
+ },
+ "rx-lite": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
+ "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ="
+ },
+ "rx-lite-aggregates": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz",
+ "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=",
+ "requires": {
+ "rx-lite": "*"
+ }
+ },
+ "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-json-parse": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-4.0.0.tgz",
+ "integrity": "sha1-fA9XjPzNEtM6ccDgVBPi7KFx6qw=",
+ "requires": {
+ "rust-result": "^1.0.0"
+ }
+ },
+ "safe-regex": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+ "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+ "dev": true,
+ "requires": {
+ "ret": "~0.1.10"
+ }
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ },
+ "samsam": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz",
+ "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==",
+ "dev": true
+ },
+ "sanitize-caja": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/sanitize-caja/-/sanitize-caja-0.1.3.tgz",
+ "integrity": "sha1-zvvXyw6Qe+p06KvLjoZ1PsVEVXY="
+ },
+ "sass-graph": {
+ "version": "2.2.6",
+ "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.6.tgz",
+ "integrity": "sha512-MKuEYXFSGuRSi8FZ3A7imN1CeVn9Gpw0/SFJKdL1ejXJneI9a5rwlEZrKejhEFAA3O6yr3eIyl/WuvASvlT36g==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.0.0",
+ "lodash": "^4.0.0",
+ "scss-tokenizer": "^0.2.3",
+ "yargs": "^7.0.0"
+ }
+ },
+ "sass-loader": {
+ "version": "6.0.7",
+ "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-6.0.7.tgz",
+ "integrity": "sha512-JoiyD00Yo1o61OJsoP2s2kb19L1/Y2p3QFcCdWdF6oomBGKVYuZyqHWemRBfQ2uGYsk+CH3eCguXNfpjzlcpaA==",
+ "dev": true,
+ "requires": {
+ "clone-deep": "^2.0.1",
+ "loader-utils": "^1.0.1",
+ "lodash.tail": "^4.1.1",
+ "neo-async": "^2.5.0",
+ "pify": "^3.0.0"
+ }
+ },
+ "sax": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
+ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
+ "dev": true
+ },
+ "schema-utils": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz",
+ "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=",
+ "dev": true,
+ "requires": {
+ "ajv": "^5.0.0"
+ }
+ },
+ "scss-tokenizer": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz",
+ "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=",
+ "dev": true,
+ "requires": {
+ "js-base64": "^2.1.8",
+ "source-map": "^0.4.2"
+ },
+ "dependencies": {
+ "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"
+ }
+ }
+ }
+ },
+ "seedrandom": {
+ "version": "2.4.4",
+ "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.4.tgz",
+ "integrity": "sha512-9A+PDmgm+2du77B5i0Ip2cxOqqHjgNxnBgglxLcX78A2D6c2rTo61z4jnVABpF4cKeDMDG+cmXXvdnqse2VqMA=="
+ },
+ "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.4",
+ "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.4.tgz",
+ "integrity": "sha512-9AukTiDmHXGXWtWjembZ5NDmVvP2695EtpgbCsxCa68w3c88B+alqbmZ4O3hZ4VWGXeGWzEVdvqgAJD8DQPCDw==",
+ "dev": true,
+ "requires": {
+ "node-forge": "0.7.5"
+ }
+ },
+ "semver": {
+ "version": "5.5.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz",
+ "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw=="
+ },
+ "semver-diff": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz",
+ "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=",
+ "dev": true,
+ "requires": {
+ "semver": "^5.0.3"
+ }
+ },
+ "semver-utils": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/semver-utils/-/semver-utils-1.1.2.tgz",
+ "integrity": "sha512-+RvtdCZJdLJXN6ozVqbypYII/m4snihgWvmFHW8iWusxqGVdEP31QdUVVaC6GeJ9EYE0JCMdWiNlLF3edjifEw==",
+ "dev": true
+ },
+ "send": {
+ "version": "0.16.2",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
+ "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==",
+ "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.6.2",
+ "mime": "1.4.1",
+ "ms": "2.0.0",
+ "on-finished": "~2.3.0",
+ "range-parser": "~1.2.0",
+ "statuses": "~1.4.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "mime": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
+ "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==",
+ "dev": true
+ },
+ "statuses": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
+ "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==",
+ "dev": true
+ }
+ }
+ },
+ "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": {
+ "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"
+ },
+ "dependencies": {
+ "mime-types": {
+ "version": "2.1.24",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz",
+ "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==",
+ "dev": true,
+ "requires": {
+ "mime-db": "1.40.0"
+ }
+ }
+ }
+ },
+ "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"
+ }
+ },
+ "mime-db": {
+ "version": "1.40.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
+ "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==",
+ "dev": true
+ },
+ "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
+ }
+ }
+ },
+ "serve-static": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz",
+ "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==",
+ "dev": true,
+ "requires": {
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.2",
+ "send": "0.16.2"
+ }
+ },
+ "set-blocking": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
+ "dev": true
+ },
+ "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=",
+ "dev": true
+ },
+ "set-value": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
+ "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-extendable": "^0.1.1",
+ "is-plain-object": "^2.0.3",
+ "split-string": "^3.0.1"
+ }
+ },
+ "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.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
+ "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
+ "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": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-1.0.0.tgz",
+ "integrity": "sha512-oeXreoKR/SyNJtRJMAKPDSvd28OqEwG4eR/xc856cRGBII7gX9lvAqDxusPm0846z/w/hWYjI1NpKwJ00NHzRA==",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.1",
+ "kind-of": "^5.0.0",
+ "mixin-object": "^2.0.1"
+ }
+ },
+ "shallow-copy": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/shallow-copy/-/shallow-copy-0.0.1.tgz",
+ "integrity": "sha1-QV9CcC1z2BAzApLMXuhurhoRoXA="
+ },
+ "sharkdown": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/sharkdown/-/sharkdown-0.1.1.tgz",
+ "integrity": "sha512-exwooSpmo5s45lrexgz6Q0rFQM574wYIX3iDZ7RLLqOb7IAoQZu9nxlZODU972g19sR69OIpKP2cpHTzU+PHIg==",
+ "requires": {
+ "cardinal": "~0.4.2",
+ "minimist": "0.0.5",
+ "split": "~0.2.10"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.5.tgz",
+ "integrity": "sha1-16oye87PUY+RBqxrjwA/o7zqhWY="
+ }
+ }
+ },
+ "shebang-command": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^1.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+ "dev": true
+ },
+ "shellwords": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz",
+ "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==",
+ "dev": true
+ },
+ "shuffle-seed": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/shuffle-seed/-/shuffle-seed-1.1.6.tgz",
+ "integrity": "sha1-UzwSaDurO0+j6HUfxOViFGdEJgs=",
+ "requires": {
+ "seedrandom": "^2.4.2"
+ }
+ },
+ "signal-exit": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
+ },
+ "sinon": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/sinon/-/sinon-2.4.1.tgz",
+ "integrity": "sha512-vFTrO9Wt0ECffDYIPSP/E5bBugt0UjcBQOfQUMh66xzkyPEnhl/vM2LRZi2ajuTdkH07sA6DzrM6KvdvGIH8xw==",
+ "dev": true,
+ "requires": {
+ "diff": "^3.1.0",
+ "formatio": "1.2.0",
+ "lolex": "^1.6.0",
+ "native-promise-only": "^0.8.1",
+ "path-to-regexp": "^1.7.0",
+ "samsam": "^1.1.3",
+ "text-encoding": "0.6.4",
+ "type-detect": "^4.0.0"
+ },
+ "dependencies": {
+ "lolex": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/lolex/-/lolex-1.6.0.tgz",
+ "integrity": "sha1-OpoCg0UqR9dDnnJzG54H1zhuSfY=",
+ "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
+ }
+ }
+ },
+ "sinon-chai": {
+ "version": "2.14.0",
+ "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-2.14.0.tgz",
+ "integrity": "sha512-9stIF1utB0ywNHNT7RgiXbdmen8QDCRsrTjw+G9TgKt1Yexjiv8TOWZ6WHsTPz57Yky3DIswZvEqX8fpuHNDtQ==",
+ "dev": true
+ },
+ "skmeans": {
+ "version": "0.9.7",
+ "resolved": "https://registry.npmjs.org/skmeans/-/skmeans-0.9.7.tgz",
+ "integrity": "sha512-hNj1/oZ7ygsfmPZ7ZfN5MUBRoGg1gtpnImuJBgLO0ljQ67DtJuiQaiYdS4lUA6s0KCwnPhGivtC/WRwIZLkHyg=="
+ },
+ "slash": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
+ "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=",
+ "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,
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0"
+ }
+ },
+ "snapdragon": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
+ "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
+ "dev": true,
+ "requires": {
+ "base": "^0.11.1",
+ "debug": "^2.2.0",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "map-cache": "^0.2.2",
+ "source-map": "^0.5.6",
+ "source-map-resolve": "^0.5.0",
+ "use": "^3.1.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
+ }
+ }
+ },
+ "snapdragon-node": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
+ "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+ "dev": true,
+ "requires": {
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.0",
+ "snapdragon-util": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+ "dev": true
+ }
+ }
+ },
+ "snapdragon-util": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+ "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.2.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "sntp": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
+ "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=",
+ "dev": true,
+ "requires": {
+ "hoek": "2.x.x"
+ }
+ },
+ "socket.io": {
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-1.7.3.tgz",
+ "integrity": "sha1-uK+cq6AJSeVo42nxMn6pvp6iRhs=",
+ "dev": true,
+ "requires": {
+ "debug": "2.3.3",
+ "engine.io": "1.8.3",
+ "has-binary": "0.1.7",
+ "object-assign": "4.1.0",
+ "socket.io-adapter": "0.5.0",
+ "socket.io-client": "1.7.3",
+ "socket.io-parser": "2.3.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
+ "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=",
+ "dev": true,
+ "requires": {
+ "ms": "0.7.2"
+ }
+ },
+ "ms": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
+ "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=",
+ "dev": true
+ },
+ "object-assign": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz",
+ "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=",
+ "dev": true
+ }
+ }
+ },
+ "socket.io-adapter": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-0.5.0.tgz",
+ "integrity": "sha1-y21LuL7IHhB4uZZ3+c7QBGBmu4s=",
+ "dev": true,
+ "requires": {
+ "debug": "2.3.3",
+ "socket.io-parser": "2.3.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
+ "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=",
+ "dev": true,
+ "requires": {
+ "ms": "0.7.2"
+ }
+ },
+ "ms": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
+ "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=",
+ "dev": true
+ }
+ }
+ },
+ "socket.io-client": {
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-1.7.3.tgz",
+ "integrity": "sha1-sw6GqhDV7zVGYBwJzeR2Xjgdo3c=",
+ "dev": true,
+ "requires": {
+ "backo2": "1.0.2",
+ "component-bind": "1.0.0",
+ "component-emitter": "1.2.1",
+ "debug": "2.3.3",
+ "engine.io-client": "1.8.3",
+ "has-binary": "0.1.7",
+ "indexof": "0.0.1",
+ "object-component": "0.0.3",
+ "parseuri": "0.0.5",
+ "socket.io-parser": "2.3.1",
+ "to-array": "0.1.4"
+ },
+ "dependencies": {
+ "component-emitter": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+ "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
+ "dev": true
+ },
+ "debug": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz",
+ "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=",
+ "dev": true,
+ "requires": {
+ "ms": "0.7.2"
+ }
+ },
+ "ms": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz",
+ "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=",
+ "dev": true
+ }
+ }
+ },
+ "socket.io-parser": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-2.3.1.tgz",
+ "integrity": "sha1-3VMgJRA85Clpcya+/WQAX8/ltKA=",
+ "dev": true,
+ "requires": {
+ "component-emitter": "1.1.2",
+ "debug": "2.2.0",
+ "isarray": "0.0.1",
+ "json3": "3.3.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
+ "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
+ "dev": true,
+ "requires": {
+ "ms": "0.7.1"
+ }
+ },
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+ "dev": true
+ },
+ "ms": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
+ "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=",
+ "dev": true
+ }
+ }
+ },
+ "sockjs": {
+ "version": "0.3.19",
+ "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz",
+ "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==",
+ "dev": true,
+ "requires": {
+ "faye-websocket": "^0.10.0",
+ "uuid": "^3.0.1"
+ }
+ },
+ "sockjs-client": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.1.5.tgz",
+ "integrity": "sha1-G7fA9yIsQPQq3xT0RCy9Eml3GoM=",
+ "dev": true,
+ "requires": {
+ "debug": "^2.6.6",
+ "eventsource": "0.1.6",
+ "faye-websocket": "~0.11.0",
+ "inherits": "^2.0.1",
+ "json3": "^3.3.2",
+ "url-parse": "^1.1.8"
+ },
+ "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"
+ }
+ },
+ "faye-websocket": {
+ "version": "0.11.1",
+ "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz",
+ "integrity": "sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=",
+ "dev": true,
+ "requires": {
+ "websocket-driver": ">=0.5.1"
+ }
+ }
+ }
+ },
+ "sort-asc": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/sort-asc/-/sort-asc-0.1.0.tgz",
+ "integrity": "sha1-q3md9h/HPqCVbHnEtTHtHp53J+k="
+ },
+ "sort-desc": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/sort-desc/-/sort-desc-0.1.1.tgz",
+ "integrity": "sha1-GYuMDN6wlcRjNBhh45JdTuNZqe4="
+ },
+ "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"
+ }
+ },
+ "sort-object": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/sort-object/-/sort-object-0.3.2.tgz",
+ "integrity": "sha1-mODRme3kDgfGGoRAPGHWw7KQ+eI=",
+ "requires": {
+ "sort-asc": "^0.1.0",
+ "sort-desc": "^0.1.1"
+ }
+ },
+ "source-list-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz",
+ "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==",
+ "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=="
+ },
+ "source-map-resolve": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
+ "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==",
+ "dev": true,
+ "requires": {
+ "atob": "^2.1.1",
+ "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.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"
+ },
+ "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
+ }
+ }
+ },
+ "source-map-url": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
+ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
+ "dev": true
+ },
+ "spawn-please": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/spawn-please/-/spawn-please-0.3.0.tgz",
+ "integrity": "sha1-2zOOxM/2Orxp8dDgjO6euL69nRE=",
+ "dev": true
+ },
+ "spawn-sync": {
+ "version": "1.0.15",
+ "resolved": "https://registry.npmjs.org/spawn-sync/-/spawn-sync-1.0.15.tgz",
+ "integrity": "sha1-sAeZVX63+wyDdsKdROih6mfldHY=",
+ "dev": true,
+ "requires": {
+ "concat-stream": "^1.4.7",
+ "os-shim": "^0.1.2"
+ }
+ },
+ "spdx-correct": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz",
+ "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==",
+ "requires": {
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-exceptions": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz",
+ "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg=="
+ },
+ "spdx-expression-parse": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
+ "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
+ "requires": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-license-ids": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz",
+ "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA=="
+ },
+ "spdy": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.0.tgz",
+ "integrity": "sha512-ot0oEGT/PGUpzf/6uk4AWLqkq+irlqHXkrdbk51oWONh3bxQmBuljxPNl66zlRRcIJStWq0QkLUCPOPjgjvU0Q==",
+ "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.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "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
+ }
+ }
+ },
+ "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.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "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
+ },
+ "readable-stream": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.3.0.tgz",
+ "integrity": "sha512-EsI+s3k3XsW+fU8fQACLN59ky34AZ14LoeVZpYwmZvldCFo0r0gnelwF2TcMjLor/BTL5aDJVBMkss0dthToPw==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ }
+ }
+ },
+ "split": {
+ "version": "0.2.10",
+ "resolved": "https://registry.npmjs.org/split/-/split-0.2.10.tgz",
+ "integrity": "sha1-Zwl8YB1pfOE2j0GPBs0gHPBSGlc=",
+ "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==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^3.0.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "dev": true,
+ "requires": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ }
+ },
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4"
+ }
+ }
+ }
+ },
+ "sprintf-js": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.1.tgz",
+ "integrity": "sha1-Nr54Mgr+WAH2zqPueLblqrlA6gw="
+ },
+ "sshpk": {
+ "version": "1.14.2",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz",
+ "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=",
+ "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"
+ }
+ },
+ "static-eval": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz",
+ "integrity": "sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg==",
+ "requires": {
+ "escodegen": "^1.8.1"
+ }
+ },
+ "static-extend": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+ "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
+ "dev": true,
+ "requires": {
+ "define-property": "^0.2.5",
+ "object-copy": "^0.1.0"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ }
+ }
+ },
+ "static-module": {
+ "version": "2.2.5",
+ "resolved": "https://registry.npmjs.org/static-module/-/static-module-2.2.5.tgz",
+ "integrity": "sha512-D8vv82E/Kpmz3TXHKG8PPsCPg+RAX6cbCOyvjM6x04qZtQ47EtJFVwRsdov3n5d6/6ynrOY9XB4JkaZwB2xoRQ==",
+ "requires": {
+ "concat-stream": "~1.6.0",
+ "convert-source-map": "^1.5.1",
+ "duplexer2": "~0.1.4",
+ "escodegen": "~1.9.0",
+ "falafel": "^2.1.0",
+ "has": "^1.0.1",
+ "magic-string": "^0.22.4",
+ "merge-source-map": "1.0.4",
+ "object-inspect": "~1.4.0",
+ "quote-stream": "~1.0.2",
+ "readable-stream": "~2.3.3",
+ "shallow-copy": "~0.0.1",
+ "static-eval": "^2.0.0",
+ "through2": "~2.0.3"
+ }
+ },
+ "statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
+ "dev": true
+ },
+ "stdout-stream": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz",
+ "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==",
+ "dev": true,
+ "requires": {
+ "readable-stream": "^2.0.1"
+ }
+ },
+ "stream-browserify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz",
+ "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=",
+ "dev": true,
+ "requires": {
+ "inherits": "~2.0.1",
+ "readable-stream": "^2.0.2"
+ }
+ },
+ "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-http": {
+ "version": "2.8.3",
+ "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz",
+ "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==",
+ "dev": true,
+ "requires": {
+ "builtin-status-codes": "^3.0.0",
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.3.6",
+ "to-arraybuffer": "^1.0.0",
+ "xtend": "^4.0.0"
+ }
+ },
+ "stream-shift": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz",
+ "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=",
+ "optional": true
+ },
+ "strict-uri-encode": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
+ "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
+ "dev": true
+ },
+ "string-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": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
+ },
+ "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.trim": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz",
+ "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=",
+ "requires": {
+ "define-properties": "^1.1.2",
+ "es-abstract": "^1.5.0",
+ "function-bind": "^1.0.2"
+ }
+ },
+ "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"
+ }
+ },
+ "stringstream": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz",
+ "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==",
+ "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=",
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM="
+ },
+ "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="
+ },
+ "strip-eof": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+ "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
+ "dev": true
+ },
+ "strip-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": "0.18.2",
+ "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.18.2.tgz",
+ "integrity": "sha512-WPpJPZGUxWYHWIUMNNOYqql7zh85zGmr84FdTVWq52WTIkqlW9xSxD3QYWi/T31cqn9UNSsietVEgGn2aaSCzw==",
+ "dev": true,
+ "requires": {
+ "loader-utils": "^1.0.2",
+ "schema-utils": "^0.3.0"
+ }
+ },
+ "supercluster": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/supercluster/-/supercluster-7.1.0.tgz",
+ "integrity": "sha512-LDasImUAFMhTqhK+cUXfy9C2KTUqJ3gucLjmNLNFmKWOnDUBxLFLH9oKuXOTCLveecmxh8fbk8kgh6Q0gsfe2w==",
+ "requires": {
+ "kdbush": "^3.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="
+ },
+ "svgo": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/svgo/-/svgo-0.7.2.tgz",
+ "integrity": "sha1-n1dyQTlSE1xv779Ar+ak+qiLS7U=",
+ "dev": true,
+ "requires": {
+ "coa": "~1.0.1",
+ "colors": "~1.1.2",
+ "csso": "~2.3.1",
+ "js-yaml": "~3.7.0",
+ "mkdirp": "~0.5.1",
+ "sax": "~1.2.1",
+ "whet.extend": "~0.9.9"
+ },
+ "dependencies": {
+ "esprima": {
+ "version": "2.7.3",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
+ "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=",
+ "dev": true
+ },
+ "js-yaml": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.7.0.tgz",
+ "integrity": "sha1-XJZ93YN6m/3KXy3oQlOr6KHAO4A=",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^2.6.0"
+ }
+ }
+ }
+ },
+ "table": {
+ "version": "4.0.2",
+ "resolved": "http://registry.npmjs.org/table/-/table-4.0.2.tgz",
+ "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==",
+ "dev": true,
+ "requires": {
+ "ajv": "^5.2.3",
+ "ajv-keywords": "^2.1.0",
+ "chalk": "^2.1.0",
+ "lodash": "^4.17.4",
+ "slice-ansi": "1.0.0",
+ "string-width": "^2.1.1"
+ },
+ "dependencies": {
+ "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==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "tapable": {
+ "version": "0.2.8",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.8.tgz",
+ "integrity": "sha1-mTcqXJmb8t8WCvwNdL7U9HlIzSI=",
+ "dev": true
+ },
+ "tar": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz",
+ "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==",
+ "dev": true,
+ "requires": {
+ "block-stream": "*",
+ "fstream": "^1.0.12",
+ "inherits": "2"
+ }
+ },
+ "tar-fs": {
+ "version": "1.16.3",
+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.3.tgz",
+ "integrity": "sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw==",
+ "optional": true,
+ "requires": {
+ "chownr": "^1.0.1",
+ "mkdirp": "^0.5.1",
+ "pump": "^1.0.0",
+ "tar-stream": "^1.1.2"
+ },
+ "dependencies": {
+ "pump": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz",
+ "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==",
+ "optional": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ }
+ }
+ },
+ "tar-stream": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.1.tgz",
+ "integrity": "sha512-IFLM5wp3QrJODQFPm6/to3LJZrONdBY/otxcvDIQzu217zKye6yVR3hhi9lAjrC2Z+m/j5oDxMPb1qcd8cIvpA==",
+ "optional": true,
+ "requires": {
+ "bl": "^1.0.0",
+ "buffer-alloc": "^1.1.0",
+ "end-of-stream": "^1.0.0",
+ "fs-constants": "^1.0.0",
+ "readable-stream": "^2.3.0",
+ "to-buffer": "^1.1.0",
+ "xtend": "^4.0.0"
+ }
+ },
+ "term-size": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz",
+ "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=",
+ "dev": true,
+ "requires": {
+ "execa": "^0.7.0"
+ }
+ },
+ "text-encoding": {
+ "version": "0.6.4",
+ "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz",
+ "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=",
+ "dev": true
+ },
+ "text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+ "dev": true
+ },
+ "throttleit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz",
+ "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=",
+ "dev": true
+ },
+ "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.3",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
+ "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
+ "requires": {
+ "readable-stream": "^2.1.5",
+ "xtend": "~4.0.1"
+ }
+ },
+ "thunky": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.0.3.tgz",
+ "integrity": "sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow==",
+ "dev": true
+ },
+ "time-stamp": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-2.1.0.tgz",
+ "integrity": "sha512-lJbq6KsFhZJtN3fPUVje1tq/hHsJOKUUcUj/MGCiQR6qWBDcyi5kxL9J7/RnaEChCn0+L/DUN2WvemDrkk4i3Q==",
+ "dev": true
+ },
+ "timed-out": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
+ "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=",
+ "dev": true
+ },
+ "timers-browserify": {
+ "version": "2.0.10",
+ "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz",
+ "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==",
+ "dev": true,
+ "requires": {
+ "setimmediate": "^1.0.4"
+ }
+ },
+ "tinyqueue": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-1.2.3.tgz",
+ "integrity": "sha512-Qz9RgWuO9l8lT+Y9xvbzhPT2efIUIFd69N7eF7tJ9lnQl0iLj1M7peK7IoUGZL9DJHw9XftqLreccfxcQgYLxA=="
+ },
+ "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"
+ }
+ },
+ "to-array": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz",
+ "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=",
+ "dev": true
+ },
+ "to-arraybuffer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
+ "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=",
+ "dev": true
+ },
+ "to-buffer": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz",
+ "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==",
+ "optional": true
+ },
+ "to-fast-properties": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz",
+ "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=",
+ "dev": true
+ },
+ "to-object-path": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+ "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "to-regex": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+ "dev": true,
+ "requires": {
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "regex-not": "^1.0.2",
+ "safe-regex": "^1.1.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "dev": true,
+ "requires": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ }
+ },
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4"
+ }
+ }
+ }
+ },
+ "to-regex-range": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+ "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+ "dev": true,
+ "requires": {
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1"
+ },
+ "dependencies": {
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ }
+ },
+ "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"
+ }
+ }
+ }
+ },
+ "topojson-client": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/topojson-client/-/topojson-client-3.0.0.tgz",
+ "integrity": "sha1-H5kpOnfvQqRI0DKoGqmCtz82DS8=",
+ "requires": {
+ "commander": "2"
+ }
+ },
+ "topojson-server": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/topojson-server/-/topojson-server-3.0.0.tgz",
+ "integrity": "sha1-N4546Hw5cqe1vixdYENptrrmnF4=",
+ "requires": {
+ "commander": "2"
+ }
+ },
+ "touch": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
+ "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==",
+ "dev": true,
+ "requires": {
+ "nopt": "~1.0.10"
+ },
+ "dependencies": {
+ "nopt": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
+ "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=",
+ "dev": true,
+ "requires": {
+ "abbrev": "1"
+ }
+ }
+ }
+ },
+ "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==",
+ "requires": {
+ "psl": "^1.1.24",
+ "punycode": "^1.4.1"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
+ }
+ }
+ },
+ "trim-newlines": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
+ "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=",
+ "dev": true
+ },
+ "trim-right": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz",
+ "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=",
+ "dev": true
+ },
+ "true-case-path": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz",
+ "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.2"
+ }
+ },
+ "tsml": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/tsml/-/tsml-1.0.1.tgz",
+ "integrity": "sha1-ifghi52eJX9H1/a1bQHFpNLGj8M="
+ },
+ "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-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"
+ }
+ },
+ "turf-jsts": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/turf-jsts/-/turf-jsts-1.2.3.tgz",
+ "integrity": "sha512-Ja03QIJlPuHt4IQ2FfGex4F4JAr8m3jpaHbFbQrgwr7s7L6U8ocrHiF3J1+wf9jzhGKxvDeaCAnGDot8OjGFyA=="
+ },
+ "tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
+ },
+ "two-product": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/two-product/-/two-product-1.0.2.tgz",
+ "integrity": "sha1-Z9ldSyV6kh4stL16+VEfkIhSLqo="
+ },
+ "two-sum": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/two-sum/-/two-sum-1.0.0.tgz",
+ "integrity": "sha1-MdPzIjnk9zHsqd+RVeKyl/AIq2Q="
+ },
+ "type-check": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+ "requires": {
+ "prelude-ls": "~1.1.2"
+ }
+ },
+ "type-detect": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-1.0.0.tgz",
+ "integrity": "sha1-diIXzAbbJY7EiQihKY6LlRIejqI=",
+ "dev": true
+ },
+ "type-is": {
+ "version": "1.6.16",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",
+ "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==",
+ "dev": true,
+ "requires": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.18"
+ }
+ },
+ "typedarray": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
+ },
+ "uglify-js": {
+ "version": "3.4.9",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz",
+ "integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "commander": "~2.17.1",
+ "source-map": "~0.6.1"
+ }
+ },
+ "uglify-to-browserify": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
+ "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
+ "dev": true,
+ "optional": true
+ },
+ "uglifyjs-webpack-plugin": {
+ "version": "0.4.6",
+ "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz",
+ "integrity": "sha1-uVH0q7a9YX5m9j64kUmOORdj4wk=",
+ "dev": true,
+ "requires": {
+ "source-map": "^0.5.6",
+ "uglify-js": "^2.8.29",
+ "webpack-sources": "^1.0.1"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
+ "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=",
+ "dev": true
+ },
+ "cliui": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
+ "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
+ "dev": true,
+ "requires": {
+ "center-align": "^0.1.1",
+ "right-align": "^0.1.1",
+ "wordwrap": "0.0.2"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
+ },
+ "uglify-js": {
+ "version": "2.8.29",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
+ "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=",
+ "dev": true,
+ "requires": {
+ "source-map": "~0.5.1",
+ "uglify-to-browserify": "~1.0.0",
+ "yargs": "~3.10.0"
+ }
+ },
+ "wordwrap": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
+ "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=",
+ "dev": true
+ },
+ "yargs": {
+ "version": "3.10.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
+ "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
+ "dev": true,
+ "requires": {
+ "camelcase": "^1.0.2",
+ "cliui": "^2.1.0",
+ "decamelize": "^1.0.0",
+ "window-size": "0.1.0"
+ }
+ }
+ }
+ },
+ "ultron": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz",
+ "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=",
+ "dev": true
+ },
+ "unassert": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/unassert/-/unassert-1.5.1.tgz",
+ "integrity": "sha1-y8iOw4dBfFpeTALTzQe+mL11/3Y=",
+ "requires": {
+ "acorn": "^4.0.0",
+ "call-matcher": "^1.0.1",
+ "deep-equal": "^1.0.0",
+ "espurify": "^1.3.0",
+ "estraverse": "^4.1.0",
+ "esutils": "^2.0.2",
+ "object-assign": "^4.1.0"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "4.0.13",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz",
+ "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c="
+ }
+ }
+ },
+ "unassertify": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/unassertify/-/unassertify-2.1.1.tgz",
+ "integrity": "sha512-YIAaIlc6/KC9Oib8cVZLlpDDhK1UTEuaDyx9BwD97xqxDZC0cJOqwFcs/Y6K3m73B5VzHsRTBLXNO0dxS/GkTw==",
+ "requires": {
+ "acorn": "^5.1.0",
+ "convert-source-map": "^1.1.1",
+ "escodegen": "^1.6.1",
+ "multi-stage-sourcemap": "^0.2.1",
+ "through": "^2.3.7",
+ "unassert": "^1.3.1"
+ }
+ },
+ "undefsafe": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz",
+ "integrity": "sha1-Il9rngM3Zj4Njnz9aG/Cg2zKznY=",
+ "dev": true,
+ "requires": {
+ "debug": "^2.2.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ }
+ }
+ },
+ "underscore": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz",
+ "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg=="
+ },
+ "unflowify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/unflowify/-/unflowify-1.0.1.tgz",
+ "integrity": "sha1-ouoNJcCv/MRpVeZHNXX3xaH0ppY=",
+ "requires": {
+ "flow-remove-types": "^1.1.2",
+ "through": "^2.3.8"
+ }
+ },
+ "union-value": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
+ "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
+ "dev": true,
+ "requires": {
+ "arr-union": "^3.1.0",
+ "get-value": "^2.0.6",
+ "is-extendable": "^0.1.1",
+ "set-value": "^2.0.1"
+ }
+ },
+ "uniq": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
+ "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=",
+ "dev": true
+ },
+ "uniqs": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz",
+ "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=",
+ "dev": true
+ },
+ "unique-string": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz",
+ "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=",
+ "dev": true,
+ "requires": {
+ "crypto-random-string": "^1.0.0"
+ }
+ },
+ "unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
+ "dev": true
+ },
+ "unset-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+ "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+ "dev": true,
+ "requires": {
+ "has-value": "^0.3.1",
+ "isobject": "^3.0.0"
+ },
+ "dependencies": {
+ "has-value": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+ "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+ "dev": true,
+ "requires": {
+ "get-value": "^2.0.3",
+ "has-values": "^0.1.4",
+ "isobject": "^2.0.0"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+ "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+ "dev": true,
+ "requires": {
+ "isarray": "1.0.0"
+ }
+ }
+ }
+ },
+ "has-values": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+ "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
+ "dev": true
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ }
+ }
+ },
+ "unzip-response": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz",
+ "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=",
+ "dev": true
+ },
+ "upath": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz",
+ "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==",
+ "dev": true
+ },
+ "update-notifier": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz",
+ "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==",
+ "dev": true,
+ "requires": {
+ "boxen": "^1.2.1",
+ "chalk": "^2.0.1",
+ "configstore": "^3.0.0",
+ "import-lazy": "^2.1.0",
+ "is-ci": "^1.0.10",
+ "is-installed-globally": "^0.1.0",
+ "is-npm": "^1.0.0",
+ "latest-version": "^3.0.0",
+ "semver-diff": "^2.0.0",
+ "xdg-basedir": "^3.0.0"
+ },
+ "dependencies": {
+ "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==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "uri-js": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
+ "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
+ "dev": true,
+ "requires": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "urix": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+ "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+ "dev": true
+ },
+ "url": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
+ "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
+ "dev": true,
+ "requires": {
+ "punycode": "1.3.2",
+ "querystring": "0.2.0"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
+ "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
+ "dev": true
+ }
+ }
+ },
+ "url-loader": {
+ "version": "0.5.9",
+ "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-0.5.9.tgz",
+ "integrity": "sha512-B7QYFyvv+fOBqBVeefsxv6koWWtjmHaMFT6KZWti4KRw8YUD/hOU+3AECvXuzyVawIBx3z7zQRejXCDSO5kk1Q==",
+ "dev": true,
+ "requires": {
+ "loader-utils": "^1.0.2",
+ "mime": "1.3.x"
+ },
+ "dependencies": {
+ "mime": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.6.tgz",
+ "integrity": "sha1-WR2E02U6awtKO5343lqoEI5y5eA=",
+ "dev": true
+ }
+ }
+ },
+ "url-parse": {
+ "version": "1.4.7",
+ "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz",
+ "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==",
+ "dev": true,
+ "requires": {
+ "querystringify": "^2.1.1",
+ "requires-port": "^1.0.0"
+ }
+ },
+ "url-parse-lax": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
+ "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
+ "dev": true,
+ "requires": {
+ "prepend-http": "^1.0.1"
+ }
+ },
+ "url-toolkit": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/url-toolkit/-/url-toolkit-2.1.6.tgz",
+ "integrity": "sha512-UaZ2+50am4HwrV2crR/JAf63Q4VvPYphe63WGeoJxeu8gmOm0qxPt+KsukfakPNrX9aymGNEkkaoICwn+OuvBw=="
+ },
+ "use": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
+ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
+ "dev": true
+ },
+ "user-home": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz",
+ "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=",
+ "dev": true
+ },
+ "useragent": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz",
+ "integrity": "sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "4.1.x",
+ "tmp": "0.0.x"
+ }
+ },
+ "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"
+ },
+ "dependencies": {
+ "inherits": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
+ "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
+ "dev": true
+ }
+ }
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
+ },
+ "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.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
+ "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
+ },
+ "v8-compile-cache": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-1.1.2.tgz",
+ "integrity": "sha512-ejdrifsIydN1XDH7EuR2hn8ZrkRKUYF7tUcBjBy/lhrCvs2K+zRlbW9UHc0IQ9RsYFZJFqJrieoIHfkCa0DBRA==",
+ "optional": true
+ },
+ "v8flags": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz",
+ "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=",
+ "dev": true,
+ "requires": {
+ "user-home": "^1.1.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"
+ }
+ },
+ "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.2",
+ "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.2.tgz",
+ "integrity": "sha512-w/hry/368nO21AN9QljsaIhb9ZiZtZARoVH5f3CsFbawdLdayCgKRPup7CggujvySMxx0I91NOyxdVENohprLQ==",
+ "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"
+ }
+ },
+ "video.js": {
+ "version": "7.5.5",
+ "resolved": "https://registry.npmjs.org/video.js/-/video.js-7.5.5.tgz",
+ "integrity": "sha512-25eZciVCBJrJe0lhr5hUT9fQfGSBIBek9FoFfFgJEyXDmPwRMR3NCxYarW+qpPAC1Re8V6MSgaCg1oIbZdqBpA==",
+ "requires": {
+ "@babel/runtime": "^7.2.0",
+ "@videojs/http-streaming": "1.9.3",
+ "global": "4.3.2",
+ "keycode": "^2.2.0",
+ "safe-json-parse": "4.0.0",
+ "tsml": "1.0.1",
+ "videojs-font": "3.1.0",
+ "videojs-vtt.js": "0.14.1",
+ "xhr": "2.4.0"
+ }
+ },
+ "videojs-flash": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/videojs-flash/-/videojs-flash-2.1.0.tgz",
+ "integrity": "sha512-ZuuG5jrrfrYTmi5ggg1km0jbR9g/eRKtvCHw1wzBucsM+tvRKq2oiK1Vz9cs0w7Vk/hw3mMLmLHWEQZOgdrJaQ==",
+ "requires": {
+ "global": "^4.3.2",
+ "video.js": "^6.1.0",
+ "videojs-swf": "5.4.1"
+ },
+ "dependencies": {
+ "video.js": {
+ "version": "6.13.0",
+ "resolved": "https://registry.npmjs.org/video.js/-/video.js-6.13.0.tgz",
+ "integrity": "sha512-36/JR/GhPQSZj0o+GNbhcEYv/b0SkV9SQsjlodAnzMQYN0TA7VhmqrKPYMCi1NGRYu7S9W3OaFCFoUxkYfSVlg==",
+ "requires": {
+ "babel-runtime": "^6.9.2",
+ "global": "4.3.2",
+ "safe-json-parse": "4.0.0",
+ "tsml": "1.0.1",
+ "videojs-font": "2.1.0",
+ "videojs-ie8": "1.1.2",
+ "videojs-vtt.js": "0.12.6",
+ "xhr": "2.4.0"
+ }
+ },
+ "videojs-font": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/videojs-font/-/videojs-font-2.1.0.tgz",
+ "integrity": "sha1-olkwpn9snPvyu4jay4xrRR8JM3k="
+ },
+ "videojs-vtt.js": {
+ "version": "0.12.6",
+ "resolved": "https://registry.npmjs.org/videojs-vtt.js/-/videojs-vtt.js-0.12.6.tgz",
+ "integrity": "sha512-XFXeGBQiljnElMhwCcZst0RDbZn2n8LU7ZScXryd3a00OaZsHAjdZu/7/RdSr7Z1jHphd45FnOvOQkGK4YrWCQ==",
+ "requires": {
+ "global": "^4.3.1"
+ }
+ }
+ }
+ },
+ "videojs-font": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/videojs-font/-/videojs-font-3.1.0.tgz",
+ "integrity": "sha512-rxB68SVgbHD+kSwoNWNCHicKJuR2ga3bGfvGxmB+8fupsiLbnyCwTBVtrZUq4bZnD64mrKP1DxHiutxwrs59pQ=="
+ },
+ "videojs-hotkeys": {
+ "version": "0.2.21",
+ "resolved": "https://registry.npmjs.org/videojs-hotkeys/-/videojs-hotkeys-0.2.21.tgz",
+ "integrity": "sha512-GtGQ4l3P5qhddYLG7jaxZ/eMu1n63ZRodoCNQl6OjDM8CUvOe02/H/shGBR4KJKiPBh4kFFbyFSKYiqdFxhjrg=="
+ },
+ "videojs-ie8": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/videojs-ie8/-/videojs-ie8-1.1.2.tgz",
+ "integrity": "sha1-oj09hgitcZK2nGB3/E64SJmNNdk=",
+ "requires": {
+ "es5-shim": "^4.5.1"
+ }
+ },
+ "videojs-swf": {
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/videojs-swf/-/videojs-swf-5.4.1.tgz",
+ "integrity": "sha1-IHfvccdJ8seCPvSbq65N0qywj4c="
+ },
+ "videojs-vtt.js": {
+ "version": "0.14.1",
+ "resolved": "https://registry.npmjs.org/videojs-vtt.js/-/videojs-vtt.js-0.14.1.tgz",
+ "integrity": "sha512-YxOiywx6N9t3J5nqsE5WN2Sw4CSqVe3zV+AZm2T4syOc2buNJaD6ZoexSdeszx2sHLU/RRo2r4BJAXFDQ7Qo2Q==",
+ "requires": {
+ "global": "^4.3.1"
+ }
+ },
+ "vlq": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz",
+ "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow=="
+ },
+ "vm-browserify": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz",
+ "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=",
+ "dev": true,
+ "requires": {
+ "indexof": "0.0.1"
+ }
+ },
+ "void-elements": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz",
+ "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=",
+ "dev": true
+ },
+ "vt-pbf": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/vt-pbf/-/vt-pbf-3.1.1.tgz",
+ "integrity": "sha512-pHjWdrIoxurpmTcbfBWXaPwSmtPAHS105253P1qyEfSTV2HJddqjM+kIHquaT/L6lVJIk9ltTGc0IxR/G47hYA==",
+ "requires": {
+ "@mapbox/point-geometry": "0.1.0",
+ "@mapbox/vector-tile": "^1.3.1",
+ "pbf": "^3.0.5"
+ }
+ },
+ "watchpack": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz",
+ "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==",
+ "dev": true,
+ "requires": {
+ "chokidar": "^2.0.2",
+ "graceful-fs": "^4.1.2",
+ "neo-async": "^2.5.0"
+ },
+ "dependencies": {
+ "anymatch": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+ "dev": true,
+ "requires": {
+ "micromatch": "^3.1.4",
+ "normalize-path": "^2.1.1"
+ }
+ },
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+ "dev": true
+ },
+ "array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+ "dev": true
+ },
+ "braces": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "chokidar": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz",
+ "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==",
+ "dev": true,
+ "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"
+ }
+ },
+ "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"
+ }
+ },
+ "expand-brackets": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+ "dev": true,
+ "requires": {
+ "debug": "^2.3.3",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "posix-character-classes": "^0.1.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ }
+ },
+ "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
+ }
+ }
+ },
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "dev": true,
+ "requires": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4"
+ }
+ }
+ }
+ },
+ "extglob": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+ "dev": true,
+ "requires": {
+ "array-unique": "^0.3.2",
+ "define-property": "^1.0.0",
+ "expand-brackets": "^2.1.4",
+ "extend-shallow": "^2.0.1",
+ "fragment-cache": "^0.2.1",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "glob-parent": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+ "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+ "dev": true,
+ "requires": {
+ "is-glob": "^3.1.0",
+ "path-dirname": "^1.0.0"
+ },
+ "dependencies": {
+ "is-glob": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.0"
+ }
+ }
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true
+ },
+ "is-glob": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz",
+ "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+ "dev": true
+ },
+ "micromatch": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "braces": "^2.3.1",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "extglob": "^2.0.4",
+ "fragment-cache": "^0.2.1",
+ "kind-of": "^6.0.2",
+ "nanomatch": "^1.2.9",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.2"
+ }
+ }
+ }
+ },
+ "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"
+ }
+ },
+ "webpack": {
+ "version": "3.12.0",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.12.0.tgz",
+ "integrity": "sha512-Sw7MdIIOv/nkzPzee4o0EdvCuPmxT98+vVpIvwtcwcF1Q4SDSNp92vwcKc4REe7NItH9f1S4ra9FuQ7yuYZ8bQ==",
+ "dev": true,
+ "requires": {
+ "acorn": "^5.0.0",
+ "acorn-dynamic-import": "^2.0.0",
+ "ajv": "^6.1.0",
+ "ajv-keywords": "^3.1.0",
+ "async": "^2.1.2",
+ "enhanced-resolve": "^3.4.0",
+ "escope": "^3.6.0",
+ "interpret": "^1.0.0",
+ "json-loader": "^0.5.4",
+ "json5": "^0.5.1",
+ "loader-runner": "^2.3.0",
+ "loader-utils": "^1.1.0",
+ "memory-fs": "~0.4.1",
+ "mkdirp": "~0.5.0",
+ "node-libs-browser": "^2.0.0",
+ "source-map": "^0.5.3",
+ "supports-color": "^4.2.1",
+ "tapable": "^0.2.7",
+ "uglifyjs-webpack-plugin": "^0.4.6",
+ "watchpack": "^1.4.0",
+ "webpack-sources": "^1.0.1",
+ "yargs": "^8.0.2"
+ },
+ "dependencies": {
+ "ajv": {
+ "version": "6.5.3",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.3.tgz",
+ "integrity": "sha512-LqZ9wY+fx3UMiiPd741yB2pj3hhil+hQc8taf4o2QGRFpWgZ2V5C8HA165DY9sS3fJwsk7uT7ZlFEyC3Ig3lLg==",
+ "dev": true,
+ "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-keywords": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz",
+ "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=",
+ "dev": true
+ },
+ "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=",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "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
+ },
+ "os-locale": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz",
+ "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==",
+ "dev": true,
+ "requires": {
+ "execa": "^0.7.0",
+ "lcid": "^1.0.0",
+ "mem": "^1.1.0"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+ "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+ "dev": true,
+ "requires": {
+ "has-flag": "^2.0.0"
+ }
+ },
+ "which-module": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
+ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
+ "dev": true
+ },
+ "yargs": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz",
+ "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=",
+ "dev": true,
+ "requires": {
+ "camelcase": "^4.1.0",
+ "cliui": "^3.2.0",
+ "decamelize": "^1.1.1",
+ "get-caller-file": "^1.0.1",
+ "os-locale": "^2.0.0",
+ "read-pkg-up": "^2.0.0",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^1.0.1",
+ "set-blocking": "^2.0.0",
+ "string-width": "^2.0.0",
+ "which-module": "^2.0.0",
+ "y18n": "^3.2.1",
+ "yargs-parser": "^7.0.0"
+ }
+ },
+ "yargs-parser": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz",
+ "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=",
+ "dev": true,
+ "requires": {
+ "camelcase": "^4.1.0"
+ }
+ }
+ }
+ },
+ "webpack-dev-middleware": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-1.12.2.tgz",
+ "integrity": "sha512-FCrqPy1yy/sN6U/SaEZcHKRXGlqU0DUaEBL45jkUYoB8foVb6wCnbIJ1HKIx+qUFTW+3JpVcCJCxZ8VATL4e+A==",
+ "dev": true,
+ "requires": {
+ "memory-fs": "~0.4.1",
+ "mime": "^1.5.0",
+ "path-is-absolute": "^1.0.0",
+ "range-parser": "^1.0.3",
+ "time-stamp": "^2.0.0"
+ }
+ },
+ "webpack-dev-server": {
+ "version": "2.11.5",
+ "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-2.11.5.tgz",
+ "integrity": "sha512-7TdOKKt7G3sWEhPKV0zP+nD0c4V9YKUJ3wDdBwQsZNo58oZIRoVIu66pg7PYkBW8A74msP9C2kLwmxGHndz/pw==",
+ "dev": true,
+ "requires": {
+ "ansi-html": "0.0.7",
+ "array-includes": "^3.0.3",
+ "bonjour": "^3.5.0",
+ "chokidar": "^2.1.2",
+ "compression": "^1.7.3",
+ "connect-history-api-fallback": "^1.3.0",
+ "debug": "^3.1.0",
+ "del": "^3.0.0",
+ "express": "^4.16.2",
+ "html-entities": "^1.2.0",
+ "http-proxy-middleware": "^0.19.1",
+ "import-local": "^1.0.0",
+ "internal-ip": "1.2.0",
+ "ip": "^1.1.5",
+ "killable": "^1.0.0",
+ "loglevel": "^1.4.1",
+ "opn": "^5.1.0",
+ "portfinder": "^1.0.9",
+ "selfsigned": "^1.9.1",
+ "serve-index": "^1.9.1",
+ "sockjs": "0.3.19",
+ "sockjs-client": "1.1.5",
+ "spdy": "^4.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^5.1.0",
+ "webpack-dev-middleware": "1.12.2",
+ "yargs": "6.6.0"
+ },
+ "dependencies": {
+ "anymatch": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+ "dev": true,
+ "requires": {
+ "micromatch": "^3.1.4",
+ "normalize-path": "^2.1.1"
+ },
+ "dependencies": {
+ "normalize-path": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+ "dev": true,
+ "requires": {
+ "remove-trailing-separator": "^1.0.1"
+ }
+ }
+ }
+ },
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+ "dev": true
+ },
+ "array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+ "dev": true
+ },
+ "braces": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "camelcase": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+ "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
+ "dev": true
+ },
+ "chokidar": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.5.tgz",
+ "integrity": "sha512-i0TprVWp+Kj4WRPtInjexJ8Q+BqTE909VpH8xVhXrJkoc5QC8VO9TryGOqTr+2hljzc1sC62t22h5tZePodM/A==",
+ "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"
+ }
+ },
+ "del": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz",
+ "integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=",
+ "dev": true,
+ "requires": {
+ "globby": "^6.1.0",
+ "is-path-cwd": "^1.0.0",
+ "is-path-in-cwd": "^1.0.0",
+ "p-map": "^1.1.1",
+ "pify": "^3.0.0",
+ "rimraf": "^2.2.8"
+ }
+ },
+ "expand-brackets": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+ "dev": true,
+ "requires": {
+ "debug": "^2.3.3",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "posix-character-classes": "^0.1.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ }
+ },
+ "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
+ }
+ }
+ },
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "dev": true,
+ "requires": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4"
+ }
+ }
+ }
+ },
+ "extglob": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+ "dev": true,
+ "requires": {
+ "array-unique": "^0.3.2",
+ "define-property": "^1.0.0",
+ "expand-brackets": "^2.1.4",
+ "extend-shallow": "^2.0.1",
+ "fragment-cache": "^0.2.1",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "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"
+ }
+ },
+ "glob-parent": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+ "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+ "dev": true,
+ "requires": {
+ "is-glob": "^3.1.0",
+ "path-dirname": "^1.0.0"
+ },
+ "dependencies": {
+ "is-glob": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.0"
+ }
+ }
+ }
+ },
+ "globby": {
+ "version": "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-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "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"
+ }
+ },
+ "is-glob": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+ "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+ "dev": true
+ },
+ "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"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "dev": true
+ }
+ }
+ },
+ "micromatch": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "braces": "^2.3.1",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "extglob": "^2.0.4",
+ "fragment-cache": "^0.2.1",
+ "kind-of": "^6.0.2",
+ "nanomatch": "^1.2.9",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.2"
+ }
+ },
+ "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
+ },
+ "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"
+ },
+ "dependencies": {
+ "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"
+ }
+ },
+ "readdirp": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
+ "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.11",
+ "micromatch": "^3.1.10",
+ "readable-stream": "^2.0.2"
+ }
+ },
+ "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-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"
+ }
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ },
+ "upath": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz",
+ "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==",
+ "dev": true
+ },
+ "yargs": {
+ "version": "6.6.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz",
+ "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=",
+ "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": "^4.2.0"
+ }
+ },
+ "yargs-parser": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz",
+ "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=",
+ "dev": true,
+ "requires": {
+ "camelcase": "^3.0.0"
+ }
+ }
+ }
+ },
+ "webpack-notifier": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/webpack-notifier/-/webpack-notifier-1.6.0.tgz",
+ "integrity": "sha1-/6yOVf+MRpdSuMG7sBGhbxCYbgI=",
+ "dev": true,
+ "requires": {
+ "node-notifier": "^5.1.2",
+ "object-assign": "^4.1.0",
+ "strip-ansi": "^3.0.1"
+ }
+ },
+ "webpack-sources": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.2.0.tgz",
+ "integrity": "sha512-9BZwxR85dNsjWz3blyxdOhTgtnQvv3OEs5xofI0wPYTwu5kaWxS08UuD1oI7WLBLpRO+ylf0ofnXLXWmGb2WMw==",
+ "dev": true,
+ "requires": {
+ "source-list-map": "^2.0.0",
+ "source-map": "~0.6.1"
+ }
+ },
+ "websocket-driver": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz",
+ "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=",
+ "dev": true,
+ "requires": {
+ "http-parser-js": ">=0.4.0",
+ "websocket-extensions": ">=0.1.1"
+ }
+ },
+ "websocket-extensions": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz",
+ "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==",
+ "dev": true
+ },
+ "webworkify": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/webworkify/-/webworkify-1.5.0.tgz",
+ "integrity": "sha512-AMcUeyXAhbACL8S2hqqdqOLqvJ8ylmIbNwUIqQujRSouf4+eUFaXbG6F1Rbu+srlJMmxQWsiU7mOJi0nMBfM1g=="
+ },
+ "wgs84": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/wgs84/-/wgs84-0.0.0.tgz",
+ "integrity": "sha1-NP3FVZF7blfPKigu0ENxDASc3HY="
+ },
+ "whet.extend": {
+ "version": "0.9.9",
+ "resolved": "https://registry.npmjs.org/whet.extend/-/whet.extend-0.9.9.tgz",
+ "integrity": "sha1-+HfVv2SMl+WqVC+twW1qJZucEaE=",
+ "dev": true
+ },
+ "which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "which-module": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
+ "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=",
+ "dev": true
+ },
+ "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": "2.0.0",
+ "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.0.tgz",
+ "integrity": "sha1-AUKk6KJD+IgsAjOqDgKBqnYVInM=",
+ "dev": true,
+ "requires": {
+ "string-width": "^2.1.1"
+ }
+ },
+ "window-size": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
+ "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=",
+ "dev": true
+ },
+ "wordwrap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus="
+ },
+ "wrap-ansi": {
+ "version": "2.1.0",
+ "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+ "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+ "dev": true,
+ "requires": {
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1"
+ },
+ "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"
+ }
+ },
+ "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"
+ }
+ }
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+ },
+ "write": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz",
+ "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=",
+ "dev": true,
+ "requires": {
+ "mkdirp": "^0.5.1"
+ }
+ },
+ "write-file-atomic": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz",
+ "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.11",
+ "imurmurhash": "^0.1.4",
+ "signal-exit": "^3.0.2"
+ }
+ },
+ "ws": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.2.tgz",
+ "integrity": "sha1-iiRPoFJAHgjJiGz0SoUYnh/UBn8=",
+ "dev": true,
+ "requires": {
+ "options": ">=0.0.5",
+ "ultron": "1.0.x"
+ }
+ },
+ "wtf-8": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wtf-8/-/wtf-8-1.0.0.tgz",
+ "integrity": "sha1-OS2LotDxw00e4tYw8V0O+2jhBIo=",
+ "dev": true
+ },
+ "xdg-basedir": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz",
+ "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=",
+ "dev": true
+ },
+ "xhr": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.4.0.tgz",
+ "integrity": "sha1-4W5mpF+GmGHu76tBbV7/ci3ECZM=",
+ "requires": {
+ "global": "~4.3.0",
+ "is-function": "^1.0.1",
+ "parse-headers": "^2.0.0",
+ "xtend": "^4.0.0"
+ }
+ },
+ "xmlhttprequest-ssl": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz",
+ "integrity": "sha1-GFqIjATspGw+QHDZn3tJ3jUomS0=",
+ "dev": true
+ },
+ "xtend": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
+ "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
+ },
+ "y18n": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
+ "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
+ "dev": true
+ },
+ "yallist": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+ "dev": true
+ },
+ "yargs": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.1.tgz",
+ "integrity": "sha512-huO4Fr1f9PmiJJdll5kwoS2e4GqzGSsMT3PPMpOwoVkOK8ckqAewMTZyA6LXVQWflleb/Z8oPBEvNsMft0XE+g==",
+ "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.0-security.0"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+ "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
+ "dev": true
+ },
+ "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"
+ }
+ },
+ "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"
+ }
+ },
+ "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"
+ }
+ },
+ "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"
+ }
+ },
+ "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-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"
+ }
+ }
+ }
+ },
+ "yargs-parser": {
+ "version": "5.0.0-security.0",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0-security.0.tgz",
+ "integrity": "sha512-T69y4Ps64LNesYxeYGYPvfoMTt/7y1XtfpIslUeK4um+9Hu7hlGoRtaDLvdXb7+/tfq4opVa2HRY5xGip022rQ==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^3.0.0",
+ "object.assign": "^4.1.0"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+ "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
+ "dev": true
+ }
+ }
+ },
+ "yarn": {
+ "version": "0.27.5",
+ "resolved": "https://registry.npmjs.org/yarn/-/yarn-0.27.5.tgz",
+ "integrity": "sha1-Bv5n2AQIApk/nx4ZI9Zxy/nq1dE=",
+ "optional": true,
+ "requires": {
+ "babel-runtime": "^6.0.0",
+ "bytes": "^2.4.0",
+ "camelcase": "^4.0.0",
+ "chalk": "^1.1.1",
+ "cmd-shim": "^2.0.1",
+ "commander": "^2.9.0",
+ "death": "^1.0.0",
+ "debug": "^2.2.0",
+ "detect-indent": "^5.0.0",
+ "glob": "^7.1.1",
+ "gunzip-maybe": "^1.4.0",
+ "ini": "^1.3.4",
+ "inquirer": "^3.0.1",
+ "invariant": "^2.2.0",
+ "is-builtin-module": "^1.0.0",
+ "is-ci": "^1.0.10",
+ "leven": "^2.0.0",
+ "loud-rejection": "^1.2.0",
+ "micromatch": "^2.3.11",
+ "mkdirp": "^0.5.1",
+ "node-emoji": "^1.0.4",
+ "object-path": "^0.11.2",
+ "proper-lockfile": "^2.0.0",
+ "read": "^1.0.7",
+ "request": "^2.81.0",
+ "request-capture-har": "^1.2.2",
+ "rimraf": "^2.5.0",
+ "semver": "^5.1.0",
+ "strip-bom": "^3.0.0",
+ "tar-fs": "^1.15.1",
+ "tar-stream": "^1.5.2",
+ "uuid": "^3.0.1",
+ "v8-compile-cache": "^1.1.0",
+ "validate-npm-package-license": "^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==",
+ "optional": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ }
+ }
+ },
+ "yauzl": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz",
+ "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=",
+ "dev": true,
+ "requires": {
+ "fd-slicer": "~1.0.1"
+ }
+ },
+ "yeast": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
+ "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=",
+ "dev": true
+ },
+ "zxcvbn": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/zxcvbn/-/zxcvbn-4.4.2.tgz",
+ "integrity": "sha1-KOwXzwl0PtyrBW3dixsGJizHPDA="
+ }
+ }
+}
diff --git a/Phraseanet-production-client/package.json b/Phraseanet-production-client/package.json
new file mode 100644
index 0000000000..77f31f04cc
--- /dev/null
+++ b/Phraseanet-production-client/package.json
@@ -0,0 +1,168 @@
+{
+ "name": "phraseanet-production-client",
+ "version": "0.34.272-d",
+ "description": "Phraseanet frontend dependencies",
+ "scripts": {
+ "clean": "rimraf dist",
+ "dev": "npm run clean && set NODE_ENV=devlopment && npx webpack --config ./config/webpack/webpack.development.config.js --progress --profile --colors",
+ "production": "npm run clean && set NODE_ENV=production && npx webpack --config ./config/webpack/webpack.production.config.js --progress --profile --colors",
+ "dist": "npm run clean && set NODE_ENV=production && npx webpack --config ./config/webpack/webpack.production.config.js --progress --profile --colors && npx webpack --config ./config/webpack/webpack.production.minified.config.js --progress --profile --colors",
+ "test": "npm run test:browser",
+ "test:server": "mocha --opts config/mocha.opts",
+ "test:browser": "./node_modules/.bin/karma start --single-run",
+ "watch:server": "npm run test:server -- --watch",
+ "watch:browser": "./node_modules/.bin/karma start --auto-watch --no-single-run",
+ "eslint:source": "eslint ./src/**/*.js",
+ "eslint:fix": "eslint --fix ./src/**/*.js",
+ "eslint:common": "eslint ./test/**/*.common.js",
+ "eslint:server": "eslint ./test/**/*.server.js",
+ "eslint:browser": "eslint ./test/**/*.browser.js",
+ "karma:firefox": "./node_modules/.bin/karma start --browsers=Firefox",
+ "karma:chrome": "./node_modules/.bin/karma start --browsers=Chrome",
+ "karma:ie": "./node_modules/.bin/karma start --browsers=IE",
+ "karma:all": "./node_modules/.bin/karma start --browsers=PhantomJS,Chrome,Firefox",
+ "packages": "npm list --depth=0",
+ "package:purge": "rm -rf node_modules",
+ "package:reinstall": "npm run package:purge && npm install",
+ "package:check": "./node_modules/.bin/ncu",
+ "package:upgrade": "./node_modules/.bin/ncu -u",
+ "package:prod": "./node_modules/.bin/ncu -u",
+ "package:dev": "./node_modules/.bin/ncu -p -u",
+ "asset-server": "node config/webpack/webpack.hot.assets.config",
+ "publish-patch": "git add -A && npm run dist && git commit && git push -u origin 4.1 && git push --tags && npm version patch && npm publish",
+ "publish-minor": "git add -A && npm run dist && git commit && git push -u origin 4.1 && git push --tags && npm version minor && npm publish",
+ "postpublish": "git push origin 4.1 --follow-tags"
+ },
+ "pre-commit": [
+ "test"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/alchemy-fr/Phraseanet-production-client.git"
+ },
+ "keywords": [
+ "phraseanet"
+ ],
+ "files": [
+ "dist",
+ "src"
+ ],
+ "devDependencies": {
+ "babel-cli": "^6.24.1",
+ "babel-core": "^6.25.0",
+ "babel-eslint": "^7.2.3",
+ "babel-loader": "^7.1.1",
+ "babel-plugin-syntax-jsx": "^6.18.0",
+ "babel-polyfill": "^6.23.0",
+ "babel-preset-es2015": "^6.24.1",
+ "babel-preset-stage-0": "^6.24.1",
+ "chai": "^3.5.0",
+ "chai-as-promised": "^7.1.1",
+ "coveralls": "^2.13.1",
+ "css-loader": "^0.28.4",
+ "dotenv": "^4.0.0",
+ "eslint": "^4.18.2",
+ "eslint-config-airbnb": "^15.1.0",
+ "eslint-loader": "^1.9.0",
+ "eslint-plugin-import": "^2.7.0",
+ "eslint-plugin-jsx-a11y": "^5.1.1",
+ "eslint-plugin-react": "^7.1.0",
+ "extract-text-webpack-plugin": "^3.0.0",
+ "file-loader": "^0.11.2",
+ "imports-loader": "^0.7.1",
+ "istanbul-instrumenter-loader": "^3.0.0",
+ "karma": "^1.7.0",
+ "karma-chai": "^0.1.0",
+ "karma-chrome-launcher": "^2.2.0",
+ "karma-cli": "^1.0.1",
+ "karma-coverage": "^1.1.1",
+ "karma-firefox-launcher": "^1.0.1",
+ "karma-ie-launcher": "^1.0.0",
+ "karma-mocha": "^1.3.0",
+ "karma-mocha-reporter": "^2.2.3",
+ "karma-phantomjs-launcher": "^1.0.4",
+ "karma-sinon": "^1.0.5",
+ "karma-sinon-chai": "^1.3.1",
+ "karma-sourcemap-loader": "^0.3.7",
+ "karma-spec-reporter": "0.0.31",
+ "karma-webpack": "^2.0.4",
+ "lodash": "^4.17.15",
+ "lolex": "^2.1.2",
+ "mocha": "^3.5.0",
+ "node-sass": "^4.14.0",
+ "nodemon": "^1.11.0",
+ "npm-check-updates": "^2.12.1",
+ "npmlog": "^4.1.2",
+ "optimize-css-assets-webpack-plugin": "^3.0.0",
+ "phantomjs-polyfill": "0.0.2",
+ "phantomjs-prebuilt": "^2.1.16",
+ "postcss-loader": "^2.0.6",
+ "pre-commit": "^1.2.2",
+ "resolve-url-loader": "^2.1.0",
+ "rimraf": "^2.6.1",
+ "sass-loader": "^6.0.6",
+ "sinon": "^2.1.0",
+ "sinon-chai": "^2.12.0",
+ "style-loader": "^0.18.2",
+ "url-loader": "^0.5.9",
+ "webpack": "^3.4.1",
+ "webpack-dev-server": "^2.6.1",
+ "webpack-notifier": "^1.5.0"
+ },
+ "babel": {
+ "ignore": [
+ "packages/babel-cli/src/babel-plugin/templates"
+ ]
+ },
+ "devEngines": {
+ "node": ">=4.1 <6",
+ "npm": ">=3.1 <5"
+ },
+ "author": {
+ "name": "Florian Blouet",
+ "email": "florian.blouet@gmail.com"
+ },
+ "bugs": "https://github.com/alchemy-fr/Phraseanet-production-client/issues",
+ "homepage": "https://github.com/alchemy-fr/Phraseanet-production-client",
+ "license": "MIT",
+ "dependencies": {
+ "@mapbox/mapbox-gl-language": "^0.9.2",
+ "@turf/turf": "^5.1.6",
+ "axios": "^0.19.2",
+ "backbone": "^1.3.3",
+ "blueimp-file-upload": "^9.15.0",
+ "blueimp-load-image": "^2.14.0",
+ "bootstrap-multiselect": "^0.9.13-1",
+ "bootstrap-sass": "^2.3.2",
+ "es6-promise": "^4.1.1",
+ "geonames-server-jquery-plugin": "^0.2.2",
+ "humane-js": "^3.2.2",
+ "i18next": "^8.4.3",
+ "i18next-xhr-backend": "^1.4.2",
+ "jquery": "^3.2.1",
+ "jquery-lazyload": "^1.9.7",
+ "jquery-treeview": "https://github.com/alchemy-fr/jquery-treeview.git",
+ "jquery-ui": "^1.10.4",
+ "jquery-ui-datepicker-with-i18n": "^1.10.4",
+ "jquery.fancytree": "~2.7",
+ "jquery.tree": "0.0.5",
+ "js-cookie": "^2.1.0",
+ "leaflet": "^0.7.7",
+ "leaflet-contextmenu": "^1.0.0",
+ "leaflet-draw": "^0.3.0",
+ "lodash.merge": "^4.6.2",
+ "mapbox": "^1.0.0-beta10",
+ "mapbox-gl": "^1.11.0",
+ "mapbox-gl-circle": "^1.6.5",
+ "mapbox.js": "^2.4.0",
+ "nouislider": "^9.2.0",
+ "pym.js": "^1.3.1",
+ "rx": "^4.1.0",
+ "sprintf-js": "^1.1.1",
+ "underscore": "^1.8.3",
+ "video.js": "^7.5.5",
+ "videojs-flash": "^2.1.0",
+ "videojs-hotkeys": "^0.2.20",
+ "zxcvbn": "^4.4.2"
+ }
+}
diff --git a/Phraseanet-production-client/src/account/bootstrap.js b/Phraseanet-production-client/src/account/bootstrap.js
new file mode 100644
index 0000000000..4dae0cd164
--- /dev/null
+++ b/Phraseanet-production-client/src/account/bootstrap.js
@@ -0,0 +1,74 @@
+import $ from 'jquery';
+import ConfigService from './../components/core/configService';
+import LocaleService from '../components/locale';
+import merge from 'lodash.merge';
+import defaultConfig from './config';
+import Emitter from '../components/core/emitter';
+import account from './../components/account';
+
+$(document).ready(() => {
+// hide or show callback url input whether user choose a web or dektop application
+ $('#form_create input[name=type]').bind('click', function () {
+ if ($(this).val() === 'desktop') {
+ $('#form_create .callback-control-group').hide().find('input').val('');
+ } else {
+ $('#form_create .callback-control-group').show();
+ }
+ });
+});
+
+
+class Bootstrap {
+
+ app;
+ configService;
+ localeService;
+ appServices;
+
+ constructor(userConfig) {
+ const configuration = merge({}, defaultConfig, userConfig);
+
+ this.appEvents = new Emitter();
+ this.configService = new ConfigService(configuration);
+ this.onConfigReady();
+
+ return this;
+ }
+
+ onConfigReady() {
+ this.appServices = {
+ configService: this.configService,
+ localeService: this.localeService,
+ appEvents: this.appEvents
+ };
+
+ /**
+ * add components
+ */
+
+ $(document).ready(() => {
+ let accountService = account(this.appServices);
+
+ accountService.initialize({
+ $container: $('body')
+ });
+
+ switch (this.configService.get('state')) {
+ case 'editAccount':
+ accountService.editAccount();
+ break;
+ case 'editSession':
+ accountService.editSession();
+ break;
+ default:
+ }
+ });
+
+ }
+}
+
+const bootstrap = (userConfig) => {
+ return new Bootstrap(userConfig);
+};
+
+export default bootstrap;
diff --git a/Phraseanet-production-client/src/account/config.js b/Phraseanet-production-client/src/account/config.js
new file mode 100644
index 0000000000..59e318e202
--- /dev/null
+++ b/Phraseanet-production-client/src/account/config.js
@@ -0,0 +1,7 @@
+let defaultConfig = {
+ locale: 'fr',
+ basePath: '/',
+ translations: '/prod/language.json',
+};
+
+export default defaultConfig;
diff --git a/Phraseanet-production-client/src/account/index.js b/Phraseanet-production-client/src/account/index.js
new file mode 100644
index 0000000000..2bfe6aa43e
--- /dev/null
+++ b/Phraseanet-production-client/src/account/index.js
@@ -0,0 +1,10 @@
+import bootstrap from './bootstrap';
+let accountApp = {
+ bootstrap
+};
+
+if (typeof window !== 'undefined') {
+ window.accountApp = accountApp;
+}
+
+module.exports = accountApp;
diff --git a/Phraseanet-production-client/src/authenticate/bootstrap.js b/Phraseanet-production-client/src/authenticate/bootstrap.js
new file mode 100644
index 0000000000..f4a32c5a4e
--- /dev/null
+++ b/Phraseanet-production-client/src/authenticate/bootstrap.js
@@ -0,0 +1,86 @@
+import $ from 'jquery';
+import ConfigService from './../components/core/configService';
+import LocaleService from '../components/locale';
+import merge from 'lodash.merge';
+
+import defaultConfig from './config';
+import Emitter from '../components/core/emitter';
+import authentication from './../components/authentication';
+
+class Bootstrap {
+
+ app;
+ configService;
+ localeService;
+ appServices;
+
+ constructor(userConfig) {
+
+ const configuration = merge({}, defaultConfig, userConfig);
+
+ this.appEvents = new Emitter();
+ this.configService = new ConfigService(configuration);
+ this.localeService = new LocaleService({
+ configService: this.configService
+ });
+
+ this.localeService.fetchTranslations()
+ .then(() => {
+ this.onConfigReady();
+ });
+ return this;
+ }
+
+ onConfigReady() {
+ this.appServices = {
+ configService: this.configService,
+ localeService: this.localeService,
+ appEvents: this.appEvents
+ };
+
+ // export translation for backward compatibility:
+ // window.language = this.localeService.getTranslations();
+
+ /**
+ * add components
+ */
+
+ $(document).ready(() => {
+ let authService = authentication(this.appServices);
+
+ authService.initialize();
+
+ switch (this.configService.get('state')) {
+ case 'login':
+ authService.login();
+ break;
+ case 'forgotPassword':
+ authService.forgotPassword();
+ break;
+ case 'renewPassword':
+ authService.renewPassword();
+ break;
+ case 'register':
+ authService.register();
+ break;
+ case 'registerProvider':
+ authService.registerProvider();
+ break;
+ case 'renewEmail':
+ authService.renewEmail();
+ break;
+ case 'changePassword':
+ authService.changePassword();
+ break;
+ default:
+ }
+ });
+
+ }
+}
+
+const bootstrap = (userConfig) => {
+ return new Bootstrap(userConfig);
+};
+
+export default bootstrap;
diff --git a/Phraseanet-production-client/src/authenticate/config.js b/Phraseanet-production-client/src/authenticate/config.js
new file mode 100644
index 0000000000..a30d04fd0b
--- /dev/null
+++ b/Phraseanet-production-client/src/authenticate/config.js
@@ -0,0 +1,7 @@
+let defaultConfig = {
+ locale: 'fr',
+ basePath: '/',
+ translations: '/login/language.json',
+};
+
+export default defaultConfig;
diff --git a/Phraseanet-production-client/src/authenticate/index.js b/Phraseanet-production-client/src/authenticate/index.js
new file mode 100644
index 0000000000..982e7c62ee
--- /dev/null
+++ b/Phraseanet-production-client/src/authenticate/index.js
@@ -0,0 +1,10 @@
+import bootstrap from './bootstrap';
+let authenticateApp = {
+ bootstrap
+};
+
+if (typeof window !== 'undefined') {
+ window.authenticateApp = authenticateApp;
+}
+
+module.exports = authenticateApp;
diff --git a/Phraseanet-production-client/src/components/account/index.js b/Phraseanet-production-client/src/components/account/index.js
new file mode 100644
index 0000000000..ab5f70ddfa
--- /dev/null
+++ b/Phraseanet-production-client/src/components/account/index.js
@@ -0,0 +1,236 @@
+/*
+ * This file is part of Phraseanet
+ *
+ * (c) 2005-2016 Alchemy
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+import $ from 'jquery';
+import geonames from './../authentication/common/geonames';
+const account = (services) => {
+ const {configService, localeService, appEvents} = services;
+
+ const initialize = (options) => {
+ let {$container} = options;
+ $container.on('click', '.alert .alert-block-close a', function (e) {
+ e.preventDefault();
+ $(this).closest('.alert').alert('close');
+ return false;
+ });
+
+ // revoke third party application access
+ $('a.app-btn').bind('click', function (e) {
+ e.preventDefault();
+ var $this = $(this);
+ $.ajax({
+ type: 'GET',
+ url: $this.attr('href'),
+ dataType: 'json',
+ data: {revoke: $this.hasClass('authorize') ? 0 : 1},
+ success: function (data) {
+ if (data.success) {
+ var li = $this.closest('li');
+
+ var hidden = $('.app-btn.hidden , .status.hidden', li);
+ var notHidden = $('.app-btn:not(.hidden), .status:not(.hidden)', li);
+
+ hidden.removeClass('hidden');
+ notHidden.addClass('hidden');
+ }
+ }
+ });
+ });
+
+ // generate new access token
+ $('a#generate_access').bind('click', function (e) {
+ e.preventDefault();
+ var $this = $(this);
+ $.ajax({
+ type: 'POST',
+ url: $this.attr('href'),
+ dataType: 'json',
+ data: {
+ usr_id: $this.closest('div').attr('id')
+ },
+ success: function (data) {
+ if (data.success) {
+ $('#my_access_token').empty().append(data.token);
+ }
+ }
+ });
+ });
+
+ //modify application callback url
+ $('.modifier_callback').bind('click', function () {
+ var modifierBtn = $(this);
+ var saveBtn = $('a.save_callback');
+ var input = $('.url_callback_input');
+ var inputVal = input.html();
+
+ modifierBtn.hide();
+ saveBtn.show();
+ // wrapp current calback in an input
+ input
+ .empty()
+ .wrapInner(''
+ + ' '
+ );
+
+ $('.url_callback').off();
+
+ // save new callback
+ saveBtn.bind('click', function (e) {
+ e.preventDefault();
+ var callback = $('input[name=oauth_callback]').val();
+ $.ajax({
+ type: 'POST',
+ url: saveBtn.attr('href'),
+ dataType: 'json',
+ data: {callback: callback},
+ success: function (data) {
+ if (data.success) {
+ input.empty().append(callback);
+ } else {
+ input.empty().append(inputVal);
+ }
+
+ modifierBtn.show();
+ saveBtn.hide();
+ }
+ });
+ });
+ });
+
+ //modify application webhook url
+ $('.webhook-modify-btn').bind('click', function () {
+ var modifierBtn = $(this);
+ var saveBtn = $('a.save_webhook');
+ var input = $('.url_webhook_input');
+ var inputVal = input.html();
+
+ modifierBtn.hide();
+ saveBtn.show();
+ // wrapp current calback in an input
+ input
+ .empty()
+ .wrapInner(''
+ + ' '
+ );
+
+ $('.url_webhook').off();
+
+ // save new callback
+ saveBtn.bind('click', function (e) {
+ e.preventDefault();
+ var webhook = $('input[name=oauth_webhook]').val();
+ $.ajax({
+ type: 'POST',
+ url: saveBtn.attr('href'),
+ dataType: 'json',
+ data: {webhook: webhook},
+ success: function (data) {
+ if (data.success) {
+ input.empty().append(webhook);
+ } else {
+ input.empty().append(inputVal);
+ }
+
+ modifierBtn.show();
+ saveBtn.hide();
+ }
+ });
+ });
+ });
+
+ // hide or show callback url input whether user choose a web or dektop application
+ /* $('#form_create input[name=type]').bind('click', function () {
+ if ($(this).val() === 'desktop') {
+ $('#form_create .callback-control-group').hide().find('input').val('');
+ } else {
+ $('#form_create .callback-control-group').show();
+ }
+ });*/
+
+ // authorize password grant type or not
+ $('.grant-type').bind('click', function () {
+ var $this = $(this);
+ $.ajax({
+ type: 'POST',
+ url: $this.attr('value'),
+ dataType: 'json',
+ data: {grant: $this.is(':checked') ? '1' : '0'},
+ success: function (data) {
+ }
+ });
+ });
+
+ // delete an application
+ /* $('a.delete-app').bind('click', function (e) {
+ e.preventDefault();
+ var $this = $(this);
+ var li = $this.closest('li');
+
+ $.ajax({
+ type: 'DELETE',
+ url: $this.attr('href'),
+ dataType: 'json',
+ data: {},
+ success: function (data) {
+ if (data.success) {
+ li.find('.modal').modal('hide');
+ li.remove();
+ }
+ }
+ });
+ });*/
+ };
+
+ const editAccount = () => {
+ $('legend').bind('click', function () {
+ $('.form-info').hide(200);
+ $($(this).data('target')).show();
+ });
+
+ geonames.init($('#form_geonameid'), {
+ server: configService.get('geonameServerUrl'),
+ limit: 40
+ });
+ };
+
+ const editSession = () => {
+ var modal = $('#modal-delete-confirm').modal({
+ show: false
+ });
+
+ $('a.delete-session').bind('click', function (e) {
+ e.preventDefault();
+ modal
+ .data('delete-url', $(this).prop('href'))
+ .modal('toggle');
+
+ return false;
+ });
+
+ $('a.confirm-delete').on('click', function (e) {
+ e.preventDefault();
+ $.ajax({
+ type: 'POST',
+ url: modal.data('delete-url'),
+ dataType: 'json',
+ success: function (data) {
+ if (data.success) {
+ $('#row-' + data.session_id).closest('tr').remove();
+ }
+ modal.modal('toggle');
+ }
+ });
+ });
+ };
+
+ return {initialize, editAccount, editSession}
+};
+export default account;
diff --git a/Phraseanet-production-client/src/components/authentication/changePassword.js b/Phraseanet-production-client/src/components/authentication/changePassword.js
new file mode 100644
index 0000000000..1d0e53496a
--- /dev/null
+++ b/Phraseanet-production-client/src/components/authentication/changePassword.js
@@ -0,0 +1,56 @@
+/*
+ * This file is part of Phraseanet
+ *
+ * (c) 2005-2016 Alchemy
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+import $ from 'jquery';
+import RenewPasswordForm from './common/forms/views/formType/passwordSetter';
+
+const changePassword = (services) => {
+ const {configService, localeService, appEvents} = services;
+ const initialize = () => {
+
+ require.ensure([], () => {
+ services.zxcvbn = require('zxcvbn');
+ new RenewPasswordForm({
+ services,
+ el: $('form[name=passwordChangeForm]'),
+ rules: [
+ {
+ name: 'oldPassword',
+ rules: 'required',
+ message: localeService.t('validation_blank')
+ },
+ {
+ name: 'password[password]',
+ rules: 'required',
+ message: localeService.t('validation_blank')
+ },
+ {
+ name: 'password[password]',
+ rules: 'min_length[5]',
+ message: localeService.t('validation_length_min', {
+ postProcess: 'sprintf',
+ sprintf: ['5']
+ })
+ },
+ {
+ name: 'password[confirm]',
+ rules: 'matches[password[password]]',
+ message: localeService.t('password_match')
+ }
+ ]
+ });
+
+ });
+
+
+ };
+
+ return {initialize};
+};
+export default changePassword;
diff --git a/Phraseanet-production-client/src/components/authentication/common/forms/validator.js b/Phraseanet-production-client/src/components/authentication/common/forms/validator.js
new file mode 100644
index 0000000000..74ca81e3c3
--- /dev/null
+++ b/Phraseanet-production-client/src/components/authentication/common/forms/validator.js
@@ -0,0 +1,278 @@
+/*
+ * This file is part of Phraseanet
+ *
+ * (c) 2005-2016 Alchemy
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+import $ from 'jquery';
+import _ from 'underscore';
+var FormValidator = function (rules, handlers) {
+ // rules setted by user
+ this.rules = rules || [];
+ // custom callbacks
+ this.handlers = handlers || [];
+ // final fields to validate
+ this.fields = [];
+
+ var self = this;
+
+ _.each(this.rules, function (field) {
+ if ('name' in field && 'rules' in field) {
+ self._addField(field);
+ }
+ });
+};
+
+// Validate method, argument is the serialize form
+FormValidator.prototype.validate = function (inputs) {
+ var self = this;
+ // possible errors
+ this.errors = [];
+ // inputs present in form
+ this.inputs = {};
+
+ _.each(_.groupBy(inputs, function (input) {
+ return input.name;
+ }), function (fields, name) {
+ self.inputs[name] = fields;
+ });
+
+ this._validateForm();
+
+ return this;
+};
+
+FormValidator.prototype.getErrors = function () {
+ return this.errors;
+};
+
+FormValidator.prototype.hasErrors = function () {
+ return this.errors.length > 0;
+};
+
+FormValidator.prototype.getRules = function () {
+ return this.rules;
+};
+
+FormValidator.prototype._addField = function (field) {
+ this.fields.push({
+ name: field.name,
+ rules: field.rules,
+ message: field.message || 'An error ocurred on input[name=' + field.name + '], you can edit this message by setting a "message" property in your rule definition object',
+ value: null,
+ type: field.type || 'text'
+ });
+};
+
+FormValidator.prototype._validateForm = function () {
+ var self = this;
+ this.errors = [];
+ _.each(this.fields, function (field) {
+ if (_.has(self.inputs, field.name)) {
+ // values can be multiple
+ var values = [];
+
+ _.each(self.inputs[field.name], function (field) {
+ return values.push(field.value);
+ });
+
+ field.value = values.join(',');
+
+ self._validateField(field);
+ } else if (field.type === 'checkbox' || field.type === 'radio' || field.type === 'select' || field.type === 'multiple') {
+ field.value = '';
+ self._validateField(field);
+ }
+ });
+};
+
+FormValidator.prototype._validateField = function (field) {
+ var self = this;
+ var ruleRegex = /^(.+?)\[(.+)\]$/;
+ var rules = field.rules.split('|');
+
+ // Run through the rules and execute the validation methods as needed
+ _.every(rules, function (method) {
+ var param = null;
+ var failed = false;
+ var parts = ruleRegex.exec(method);
+
+ // If the rule has a parameter (i.e. matches[param]) split it out
+ if (parts) {
+ method = parts[1];
+ param = parts[2];
+ }
+
+ // If the hook is defined, run it to find any validation errors
+ if (typeof self._hooks[method] === 'function') {
+ if (!self._hooks[method].apply(self, [field, param])) {
+ failed = true;
+ }
+ } else if (method.substring(0, 9) === 'callback_') {
+ // Custom method. Execute the handler if it was registered
+ method = method.substring(9, method.length);
+
+ if (typeof self.handlers[method] === 'function') {
+ if (this.handlers[method].apply(self, [field.value, param]) === false) {
+ failed = true;
+ }
+ }
+ }
+
+ // If the hook failed, add a message to the errors array
+ if (failed) {
+ self.errors.push({
+ name: field.name,
+ value: field.value,
+ message: field.message,
+ rule: method
+ });
+ }
+
+ // Breaks loop iteration
+ return failed;
+ });
+};
+
+FormValidator.prototype.Regexp = {
+ numericRegex: /^[0-9]+$/,
+ integerRegex: /^\-?[0-9]+$/,
+ decimalRegex: /^\-?[0-9]*\.?[0-9]+$/,
+ emailRegex: /^[^@]+@[^@]+\.[^@]+$/,
+ alphaRegex: /^[a-z]+$/i,
+ alphaNumericRegex: /^[a-z0-9]+$/i,
+ alphaDashRegex: /^[a-z0-9_\-]+$/i,
+ naturalRegex: /^[0-9]+$/i,
+ naturalNoZeroRegex: /^[1-9][0-9]*$/i,
+ // IP v6 a v4 or hostname, by Mikulas Dite see http://stackoverflow.com/a/9209720/96656
+ ipRegex: /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$|^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$|^(?:(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){6})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:::(?:(?:(?:[0-9a-fA-F]{1,4})):){5})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){4})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,1}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){3})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,2}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:(?:[0-9a-fA-F]{1,4})):){2})(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,3}(?:(?:[0-9a-fA-F]{1,4})))?::(?:(?:[0-9a-fA-F]{1,4})):)(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,4}(?:(?:[0-9a-fA-F]{1,4})))?::)(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,5}(?:(?:[0-9a-fA-F]{1,4})))?::)(?:(?:[0-9a-fA-F]{1,4})))|(?:(?:(?:(?:(?:(?:[0-9a-fA-F]{1,4})):){0,6}(?:(?:[0-9a-fA-F]{1,4})))?::))))$/i,
+ numericDashRegex: /^[\d\-\s]+$/,
+ urlRegex: /^((http|https):\/\/(\w+:{0,1}\w*@)?(\S+)|)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/
+};
+
+// Object containing all of the validation hooks
+FormValidator.prototype._hooks = {
+ required: function (field) {
+ var value = field.value;
+
+ return (value !== null && value !== '');
+ },
+ equal: function (field, defaultName) {
+ return field.value === defaultName;
+ },
+ matches: function (field, matchName) {
+ if (typeof this.inputs[matchName] === 'undefined') {
+ return false;
+ }
+
+ var el = this.inputs[matchName].shift();
+
+ if (el) {
+ return field.value === el.value;
+ }
+
+ return false;
+ },
+ valid_email: function (field) {
+ return this.Regexp.emailRegex.test(field.value);
+ },
+ valid_emails: function (field) {
+ var result = field.value.split(',');
+
+ for (var i = 0; i < result.length; i++) {
+ if (!this.Regexp.emailRegex.test($.trim(result[i]))) {
+ return false;
+ }
+ }
+
+ return true;
+ },
+ min_length: function (field, length) {
+ if (field.type === 'multiple') {
+ return _.filter(field.value.split(','), function (value) {
+ return value !== '';
+ }).length >= parseInt(length, 10)
+ }
+
+ if (!this.Regexp.numericRegex.test(length)) {
+ return false;
+ }
+
+ return (field.value.length >= parseInt(length, 10));
+ },
+ max_length: function (field, length) {
+ if (field.type === 'multiple') {
+ return _.filter(field.value.split(','), function (value) {
+ return value !== '';
+ }).length <= parseInt(length, 10)
+ }
+
+ if (!this.Regexp.numericRegex.test(length)) {
+ return false;
+ }
+
+ return (field.value.length <= parseInt(length, 10));
+ },
+ exact_length: function (field, length) {
+ if (field.type === 'multiple') {
+ return _.filter(field.value.split(','), function (value) {
+ return value !== '';
+ }).length === parseInt(length, 10)
+ }
+
+ if (!this.Regexp.numericRegex.test(length)) {
+ return false;
+ }
+
+ return (field.value.length === parseInt(length, 10));
+ },
+ greater_than: function (field, param) {
+ if (!this.Regexp.decimalRegex.test(field.value)) {
+ return false;
+ }
+
+ return (parseFloat(field.value) > parseFloat(param));
+ },
+ less_than: function (field, param) {
+ if (!this.Regexp.decimalRegex.test(field.value)) {
+ return false;
+ }
+
+ return (parseFloat(field.value) < parseFloat(param));
+ },
+ alpha: function (field) {
+ return (this.Regexp.alphaRegex.test(field.value));
+ },
+ alpha_numeric: function (field) {
+ return (this.Regexp.alphaNumericRegex.test(field.value));
+ },
+ alpha_dash: function (field) {
+ return (this.Regexp.alphaDashRegex.test(field.value));
+ },
+ numeric: function (field) {
+ return (this.Regexp.numericRegex.test(field.value));
+ },
+ integer: function (field) {
+ return (this.Regexp.integerRegex.test(field.value));
+ },
+ decimal: function (field) {
+ return (this.Regexp.decimalRegex.test(field.value));
+ },
+ is_natural: function (field) {
+ return (this.Regexp.naturalRegex.test(field.value));
+ },
+ is_natural_no_zero: function (field) {
+ return (this.Regexp.naturalNoZeroRegex.test(field.value));
+ },
+ valid_ip: function (field) {
+ return (this.Regexp.ipRegex.test(field.value));
+ },
+ valid_url: function (field) {
+ return (this.Regexp.urlRegex.test(field.value));
+ }
+};
+
+export default FormValidator;
diff --git a/Phraseanet-production-client/src/components/authentication/common/forms/views/error.js b/Phraseanet-production-client/src/components/authentication/common/forms/views/error.js
new file mode 100644
index 0000000000..d69566f375
--- /dev/null
+++ b/Phraseanet-production-client/src/components/authentication/common/forms/views/error.js
@@ -0,0 +1,60 @@
+/*
+ * This file is part of Phraseanet
+ *
+ * (c) 2005-2016 Alchemy
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+import $ from 'jquery';
+import _ from 'underscore';
+import Backbone from 'backbone';
+var ErrorView = Backbone.View.extend({
+ tagName: 'div',
+ initialize: function (options) {
+ options = options || {};
+
+ if (options.name === undefined) {
+ throw 'Missing name attribute in error view';
+ }
+
+ if (options.errorTemplate === undefined) {
+ throw 'Missing errorTemplate attribute in error view';
+ }
+
+ this.name = options.name;
+ this.errorTemplate = options.errorTemplate;
+
+ this.errors = options.errors || {};
+ this.onRenderError = options.onRenderError || null;
+ },
+ render: function () {
+ if (this.errors.length > 0) {
+ var template = _.template($(this.errorTemplate).html(), {
+ errors: this.errors
+ });
+
+ this.$el.html(template);
+
+ if (_.isFunction(this.onRenderError)) {
+ this.onRenderError(this.name, this.$el);
+ }
+ } else {
+ this.reset();
+ }
+
+ return this;
+ },
+ renderErrors: function (errors) {
+ this.errors = errors;
+ this.render();
+
+ return this;
+ },
+ reset: function () {
+ this.$el.empty();
+ }
+});
+
+export default ErrorView;
diff --git a/Phraseanet-production-client/src/components/authentication/common/forms/views/form.js b/Phraseanet-production-client/src/components/authentication/common/forms/views/form.js
new file mode 100644
index 0000000000..e608183ec0
--- /dev/null
+++ b/Phraseanet-production-client/src/components/authentication/common/forms/views/form.js
@@ -0,0 +1,89 @@
+/*
+ * This file is part of Phraseanet
+ *
+ * (c) 2005-2016 Alchemy
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+import $ from 'jquery';
+import _ from 'underscore';
+import Backbone from 'backbone';
+import Validator from './../validator';
+import InputView from './input';
+var Form = Backbone.View.extend({
+ events: {
+ submit: '_onSubmit'
+ },
+ initialize: function (options) {
+ options = options || {};
+
+ var self = this;
+
+ if (options.services !== undefined) {
+ this.services = options.services;
+ }
+
+ this.errorTemplate = options.errorTemplate || '#field_errors';
+ this.onRenderError = options.onRenderError || null;
+ // get a new validator defined rules
+ this.validator = new Validator(options.rules || []);
+
+ this.inputViews = {};
+
+ // creates input views for each input
+ _.each(this.$el.serializeArray(), function (input) {
+ self._addInputView(input);
+ });
+ },
+ _onSubmit: function (event) {
+ var self = this;
+
+ // reset previous errors in the view
+ this._resetInputErrors();
+
+ // validate new values
+ this.validator.validate(this.$el.serializeArray());
+
+ if (this.validator.hasErrors()) {
+ // cancel submit
+ event.preventDefault();
+ // group errors by input
+ _.each(_.groupBy(this.validator.getErrors(), function (error) {
+ return error.name;
+ }), function (errors, name) {
+ // show new errors in the views
+ if (name in self.inputViews) {
+ self.inputViews[name].showErrors(errors);
+ } else {
+ // Because serialize array do not serialize non checked input
+ // We must create view for errored input name on the fly
+ var input = {name: name};
+
+ self._addInputView(input);
+ self.inputViews[name].showErrors(errors);
+ }
+ });
+ }
+ },
+ _resetInputErrors: function () {
+ _.each(this.inputViews, function (view) {
+ view.resetErrors();
+ });
+ },
+ _addInputView: function (input) {
+ var name = input.name;
+
+ this.inputViews[name] = new InputView({
+ name: name,
+ el: $('input[name="' + name + '"], select[name="' + name + '"], textarea[name="' + name + '"]', this.$el).first().closest('div'),
+ errorTemplate: this.errorTemplate,
+ onRenderError: this.onRenderError
+ });
+
+ return this;
+ }
+});
+
+export default Form;
diff --git a/Phraseanet-production-client/src/components/authentication/common/forms/views/formType/passwordSetter.js b/Phraseanet-production-client/src/components/authentication/common/forms/views/formType/passwordSetter.js
new file mode 100644
index 0000000000..e7087f2105
--- /dev/null
+++ b/Phraseanet-production-client/src/components/authentication/common/forms/views/formType/passwordSetter.js
@@ -0,0 +1,76 @@
+/*
+ * This file is part of Phraseanet
+ *
+ * (c) 2005-2016 Alchemy
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+import $ from 'jquery';
+import _ from 'underscore';
+import FormView from './../form';
+
+var PasswordSetterForm = FormView.extend({
+ events: function () {
+ return _.extend({}, FormView.prototype.events, {
+ 'keyup input[type=password]': 'onPasswordKeyup'
+ });
+ },
+ onPasswordKeyup: function (event) {
+ var input = $(event.target);
+ var password = input.val();
+ var inputView = this.inputViews[input.attr('name')];
+ var bg = $('.password_strength_bg', inputView.$el);
+ var label = $('.password_strength_label', inputView.$el);
+ var desc = $('.password_strength_desc', inputView.$el);
+ var css = {
+ width: '0%',
+ 'background-color': 'rgb(39, 39, 30)'
+ };
+ var result = '';
+
+ if (password.length > 0) {
+ var passMeter = this.services.zxcvbn(input.val());
+
+ switch (passMeter.score) {
+ case 0:
+ case 1:
+ css = {
+ width: '25%',
+ 'background-color': 'rgb(200, 24, 24)'
+ };
+ result = this.services.localeService.t('weak');
+ break;
+ case 2:
+ css = {
+ width: '50%',
+ 'background-color': 'rgb(255, 172, 29)'
+ };
+ result = this.services.localeService.t('ordinary');
+ break;
+ case 3:
+ css = {
+ width: '75%',
+ 'background-color': 'rgb(166, 192, 96)'
+ };
+ result = this.services.localeService.t('good');
+ break;
+ case 4:
+ css = {
+ width: '100%',
+ 'background-color': 'rgb(39, 179, 15)'
+ };
+ result = this.services.localeService.t('great');
+ break;
+ default:
+ }
+ }
+
+ bg.css(css);
+ label.css({color: css['background-color']});
+ desc.css({color: css['background-color']}).html(result);
+ }
+});
+
+export default PasswordSetterForm;
diff --git a/Phraseanet-production-client/src/components/authentication/common/forms/views/input.js b/Phraseanet-production-client/src/components/authentication/common/forms/views/input.js
new file mode 100644
index 0000000000..ffcc0973ae
--- /dev/null
+++ b/Phraseanet-production-client/src/components/authentication/common/forms/views/input.js
@@ -0,0 +1,49 @@
+/*
+ * This file is part of Phraseanet
+ *
+ * (c) 2005-2016 Alchemy
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+import $ from 'jquery';
+import _ from 'underscore';
+import Backbone from 'backbone';
+import ErrorView from './error';
+import MultiViews from './../../multiviews';
+var InputView = Backbone.View.extend(_.extend({}, MultiViews, {
+ initialize: function (options) {
+ options = options || {};
+ if (options.name === undefined) {
+ throw 'Missing name attribute in input view';
+ }
+
+ if (options.errorTemplate === undefined) {
+ throw 'Missing errorTemplate attribute in input view';
+ }
+
+ this.name = options.name;
+
+ this.errorView = new ErrorView({
+ name: this.name,
+ errorTemplate: options.errorTemplate,
+ onRenderError: options.onRenderError || null
+ });
+ },
+ render: function () {
+ this._assignView({'.error-view': this.errorView});
+ },
+ showErrors: function (errors) {
+ this.render();
+
+ this.errorView.renderErrors(errors);
+
+ return this;
+ },
+ resetErrors: function () {
+ this.errorView.reset();
+ }
+}));
+
+export default InputView;
diff --git a/Phraseanet-production-client/src/components/authentication/common/geonames.js b/Phraseanet-production-client/src/components/authentication/common/geonames.js
new file mode 100644
index 0000000000..9889ff197f
--- /dev/null
+++ b/Phraseanet-production-client/src/components/authentication/common/geonames.js
@@ -0,0 +1,43 @@
+import $ from 'jquery';
+require('jquery-ui');
+require('geonames-server-jquery-plugin/jquery.geonames.js');
+const geonames = {
+
+ init: function ($field, options) {
+ var geocompleter = $field.geocompleter(options);
+
+ // On focus add select-state
+ geocompleter.geocompleter('autocompleter', 'on', 'autocompletefocus', function (event, ui) {
+ $('li', $(event.originalEvent.target)).closest('li').removeClass('selected');
+ $('a.ui-state-active, a.ui-state-hover, a.ui-state-focus', $(event.originalEvent.target)).closest('li').addClass('selected');
+ });
+
+ // On search request add loading-state
+ geocompleter.geocompleter('autocompleter', 'on', 'autocompletesearch', function (event, ui) {
+ $(this).attr('autocomplete', 'false');
+ $(this).addClass('input-loading');
+ $(this).removeClass('input-error');
+ });
+
+ // On response remove loading-state
+ geocompleter.geocompleter('autocompleter', 'on', 'autocompleteresponse', function (event, ui) {
+ $(this).removeClass('input-loading');
+ });
+
+ // On close menu remove loading-state
+ geocompleter.geocompleter('autocompleter', 'on', 'autocompleteclose', function (event, ui) {
+ $(this).removeClass('input-loading');
+ });
+
+ // On request error add error-state
+ geocompleter.geocompleter('autocompleter', 'on', 'geotocompleter.request.error', function (jqXhr, status, error) {
+ $(this).removeClass('input-loading');
+ $(this).addClass('input-error');
+ });
+
+ return geocompleter;
+ }
+
+};
+
+export default geonames;
diff --git a/Phraseanet-production-client/src/components/authentication/common/multiviews.js b/Phraseanet-production-client/src/components/authentication/common/multiviews.js
new file mode 100644
index 0000000000..e3b6010cfa
--- /dev/null
+++ b/Phraseanet-production-client/src/components/authentication/common/multiviews.js
@@ -0,0 +1,26 @@
+/*
+ * This file is part of Phraseanet
+ *
+ * (c) 2005-2016 Alchemy
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+import _ from 'underscore';
+export default {
+ // bind a subview to a DOM element
+ _assignView: function (selector, view) {
+ var selectors;
+ if (_.isObject(selector)) {
+ selectors = selector;
+ } else {
+ selectors = {};
+ selectors[selector] = view;
+ }
+ if (!selectors) return;
+ _.each(selectors, function (view, selector) {
+ view.setElement(this.$(selector)).render();
+ }, this);
+ }
+};
diff --git a/Phraseanet-production-client/src/components/authentication/forgotPassword.js b/Phraseanet-production-client/src/components/authentication/forgotPassword.js
new file mode 100644
index 0000000000..a8d912944d
--- /dev/null
+++ b/Phraseanet-production-client/src/components/authentication/forgotPassword.js
@@ -0,0 +1,36 @@
+/*
+ * This file is part of Phraseanet
+ *
+ * (c) 2005-2016 Alchemy
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+import $ from 'jquery';
+import ForgotPassWordForm from './common/forms/views/form';
+
+const forgotPassword = (services) => {
+ const { configService, localeService, appEvents } = services;
+ const initialize = () => {
+ new ForgotPassWordForm({
+ el: $('form[name=forgottenPasswordForm]'),
+ rules: [
+ {
+ name: 'email',
+ rules: 'required',
+ message: localeService.t('validation_blank')
+ },
+ {
+ name: 'email',
+ rules: 'valid_email',
+ message: localeService.t('validation_email')
+ }
+ ]
+ });
+ };
+
+ return {initialize};
+};
+export default forgotPassword;
+
diff --git a/Phraseanet-production-client/src/components/authentication/index.js b/Phraseanet-production-client/src/components/authentication/index.js
new file mode 100644
index 0000000000..926791ea67
--- /dev/null
+++ b/Phraseanet-production-client/src/components/authentication/index.js
@@ -0,0 +1,87 @@
+/*
+ * This file is part of Phraseanet
+ *
+ * (c) 2005-2016 Alchemy
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+import $ from 'jquery';
+import loginService from './login';
+import forgotPasswordService from './forgotPassword';
+import renewPasswordService from './renewPassword';
+import registerService from './register';
+import registerProviderService from './registerProvider';
+import renewEmailService from './renewEmail';
+import changePasswordService from './changePassword';
+require('bootstrap-multiselect'); // multiselect
+
+const authentication = (services) => {
+ const { configService, localeService, appEvents } = services;
+
+ const initialize = () => {
+ // close alerts
+ $(document).on('click', '.alert .alert-block-close a', function (e) {
+ e.preventDefault();
+ $(this).closest('.alert').alert('close');
+ return false;
+ });
+
+ $('select[multiple="multiple"]').multiselect({
+ buttonWidth: '100%',
+ buttonClass: 'btn btn-inverse',
+ maxHeight: 185,
+ includeSelectAllOption: true,
+ selectAllValue: 'all',
+ selectAllText: localeService.t('all_collections'),
+ buttonText: function (options, select) {
+ if (options.length === 0) {
+ return localeService.t('no_collection_selected') + ' ';
+ } else {
+ return localeService.t(
+ options.length === 1 ? 'one_collection_selected' : 'collections_selected', {
+ postProcess: 'sprintf',
+ sprintf: [options.length]
+ }) + ' ';
+ }
+ }
+ });
+ $('form[name="registerForm"]').on('submit', function () {
+ // must deselect the 'select all' checkbox for server side validation.
+ $('select[multiple="multiple"]').multiselect('deselect', 'all');
+ });
+ };
+
+ const login = () => {
+ // init login form
+ loginService(services).initialize();
+ };
+ const forgotPassword = () => {
+ // init login form
+ forgotPasswordService(services).initialize();
+ };
+ const renewPassword = () => {
+ // init login form
+ renewPasswordService(services).initialize();
+ };
+ const register = () => {
+ // init login form
+ registerService(services).initialize();
+ };
+ const registerProvider = () => {
+ // init login form
+ registerProviderService(services).initialize();
+ };
+ const renewEmail = () => {
+ // init login form
+ renewEmailService(services).initialize();
+ };
+ const changePassword = () => {
+ // init login form
+ changePasswordService(services).initialize();
+ };
+
+ return { initialize, login, forgotPassword, renewPassword, register, registerProvider, renewEmail, changePassword}
+};
+export default authentication;
diff --git a/Phraseanet-production-client/src/components/authentication/login.js b/Phraseanet-production-client/src/components/authentication/login.js
new file mode 100644
index 0000000000..e289b30313
--- /dev/null
+++ b/Phraseanet-production-client/src/components/authentication/login.js
@@ -0,0 +1,37 @@
+/*
+ * This file is part of Phraseanet
+ *
+ * (c) 2005-2016 Alchemy
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+import $ from 'jquery';
+import LoginForm from './common/forms/views/form';
+
+const login = (services) => {
+ const {configService, localeService, appEvents} = services;
+ const initialize = () => {
+
+ new LoginForm({
+ el: $('form[name=loginForm]'),
+ rules: [
+ {
+ name: 'login',
+ rules: 'required',
+ message: localeService.t('validation_blank')
+ },
+ {
+ name: 'password',
+ rules: 'required',
+ message: localeService.t('validation_blank')
+ }
+ ]
+ });
+ };
+
+ return {initialize};
+};
+export default login;
+
diff --git a/Phraseanet-production-client/src/components/authentication/register.js b/Phraseanet-production-client/src/components/authentication/register.js
new file mode 100644
index 0000000000..0cdc205fd1
--- /dev/null
+++ b/Phraseanet-production-client/src/components/authentication/register.js
@@ -0,0 +1,133 @@
+/*
+ * This file is part of Phraseanet
+ *
+ * (c) 2005-2016 Alchemy
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+// launch application
+import $ from 'jquery';
+import _ from 'underscore';
+import RegisterForm from './common/forms/views/formType/passwordSetter';
+import geonames from './common/geonames';
+
+const regiser = (services) => {
+ const {configService, localeService, appEvents} = services;
+ const initialize = () => {
+ var fieldsConfiguration = [];
+
+ $.when.apply($, [
+ $.ajax({
+ url: '/login/registration-fields/',
+ success: function (config) {
+ fieldsConfiguration = config;
+ }
+ })
+ ]).done(function () {
+
+ var rules = [];
+ var defaultRules = [
+ {
+ name: 'email',
+ rules: 'required',
+ message: localeService.t('validation_blank')
+ },
+ {
+ name: 'email',
+ rules: 'valid_email',
+ message: localeService.t('validation_email')
+ },
+ {
+ name: 'password[password]',
+ rules: 'required',
+ message: localeService.t('validation_blank')
+ },
+ {
+ name: 'password[password]',
+ rules: 'min_length[5]',
+ message: localeService.t('validation_length_min', {
+ postProcess: 'sprintf',
+ sprintf: ['5']
+ })
+ },
+ {
+ name: 'password[confirm]',
+ rules: 'matches[password[password]]',
+ message: localeService.t('password_match')
+ },
+ {
+ name: 'accept-tou',
+ rules: 'required',
+ message: localeService.t('accept_tou'),
+ type: 'checkbox'
+ },
+ {
+ name: 'collections[]',
+ rules: 'min_length[1]',
+ message: localeService.t('validation_choice_min', {
+ postProcess: 'sprintf',
+ sprintf: ['1']
+ }),
+ type: 'multiple'
+ }
+ ];
+
+ _.each(fieldsConfiguration, function (field) {
+ if (field.required) {
+ var rule = {
+ name: field.name,
+ rules: 'required',
+ message: localeService.t('validation_blank')
+ };
+
+ defaultRules.push(rule);
+ }
+ });
+
+ _.each(defaultRules, function (rule) {
+ // add rule if element exists
+ if ($('[name="' + rule.name + '"]').length >= 1) {
+ }
+ });
+
+ var $form = $('form[name=registerForm]');
+
+ require.ensure([], () => {
+ services.zxcvbn = require('zxcvbn');
+ new RegisterForm({
+ el: $form,
+ rules: rules,
+ services
+ });
+ });
+
+ var geocompleter = geonames.init($('#geonameid'), {
+ server: $form.data('geonames-server-adress'),
+ limit: 40,
+ 'init-input': false,
+ onInit: function (input, autoinput) {
+ // Set default name to geonameid-completer
+ autoinput.prop('name', 'geonameid-completer');
+ }
+ });
+
+ // Positioning menu below input
+ geocompleter.geocompleter('autocompleter', 'option', 'position', {
+ of: geocompleter.closest('.input-table'),
+ my: 'left top',
+ at: 'left bottom'
+ });
+
+ // On open menu calculate max-width
+ geocompleter.geocompleter('autocompleter', 'on', 'autocompleteopen', function (event, ui) {
+ $(this).autocomplete('widget').css('min-width', geocompleter.closest('.input-table').outerWidth());
+ });
+
+ });
+ };
+
+ return {initialize};
+};
+export default regiser;
diff --git a/Phraseanet-production-client/src/components/authentication/registerProvider.js b/Phraseanet-production-client/src/components/authentication/registerProvider.js
new file mode 100644
index 0000000000..f7de8a800b
--- /dev/null
+++ b/Phraseanet-production-client/src/components/authentication/registerProvider.js
@@ -0,0 +1,105 @@
+/*
+ * This file is part of Phraseanet
+ *
+ * (c) 2005-2016 Alchemy
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+// launch application
+import $ from 'jquery';
+import _ from 'underscore';
+import RegisterForm from './common/forms/views/form';
+
+const registerProvider = (services) => {
+ const {configService, localeService, appEvents} = services;
+ const initialize = () => {
+ var fieldsConfiguration = [];
+
+ $.when.apply($, [
+ $.ajax({
+ url: '/login/registration-fields/',
+ success: function (config) {
+ fieldsConfiguration = config;
+ }
+ })
+ ]).done(function () {
+
+ var rules = [];
+ var defaultRules = [
+ {
+ name: 'email',
+ rules: 'required',
+ message: localeService.t('validation_blank')
+ },
+ {
+ name: 'email',
+ rules: 'valid_email',
+ message: localeService.t('validation_email')
+ },
+ {
+ name: 'password',
+ rules: 'required',
+ message: localeService.t('validation_blank')
+ },
+ {
+ name: 'password',
+ rules: 'min_length[5]',
+ message: localeService.t('validation_length_min', {
+ postProcess: 'sprintf',
+ sprintf: ['5']
+ })
+ },
+ {
+ name: 'passwordConfirm',
+ rules: 'matches[password]',
+ message: localeService.t('password_match')
+ },
+ {
+ name: 'accept-tou',
+ rules: 'required',
+ message: localeService.t('accept_tou'),
+ type: 'checkbox'
+ },
+ {
+ name: 'collections[]',
+ rules: 'min_length[1]',
+ message: localeService.t('validation_choice_min', {
+ postProcess: 'sprintf',
+ sprintf: ['1']
+ }),
+ type: 'multiple'
+ }
+ ];
+
+ _.each(fieldsConfiguration, function (field) {
+ if (field.required) {
+ var rule = {
+ name: field.name,
+ rules: 'required',
+ message: localeService.t('validation_blank')
+ };
+
+ defaultRules.push(rule);
+ }
+ });
+
+ _.each(defaultRules, function (rule) {
+ // add rule if element exists
+ if ($('[name="' + rule.name + '"]').length >= 1) {
+ rules.push(rule);
+ }
+ });
+
+ new RegisterForm({
+ el: $('form[name=registerForm]'),
+ rules: rules
+ });
+
+ });
+ };
+
+ return {initialize};
+};
+export default registerProvider;
diff --git a/Phraseanet-production-client/src/components/authentication/renewEmail.js b/Phraseanet-production-client/src/components/authentication/renewEmail.js
new file mode 100644
index 0000000000..2ba2b519f3
--- /dev/null
+++ b/Phraseanet-production-client/src/components/authentication/renewEmail.js
@@ -0,0 +1,50 @@
+/*
+ * This file is part of Phraseanet
+ *
+ * (c) 2005-2016 Alchemy
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+import $ from 'jquery';
+import RenewEmailForm from './common/forms/views/form';
+
+const renewEmail = (services) => {
+ const {configService, localeService, appEvents} = services;
+ const initialize = () => {
+ new RenewEmailForm({
+ el: $('form[name=changeEmail]'),
+ errorTemplate: '#field_errors_block',
+ onRenderError: function (name, $el) {
+ $el.closest('.control-group').addClass('error');
+ },
+ rules: [
+ {
+ name: 'form_password',
+ rules: 'required',
+ message: localeService.t('validation_blank')
+ },
+ {
+ name: 'form_email',
+ rules: 'required',
+ message: localeService.t('validation_blank')
+ },
+ {
+ name: 'form_email',
+ rules: 'email',
+ message: localeService.t('validation_email')
+ },
+ {
+ name: 'form_email_confirm',
+ rules: 'matches[form_email]',
+ message: localeService.t('email_match')
+ }
+ ]
+ });
+ };
+
+
+ return {initialize};
+};
+export default renewEmail;
diff --git a/Phraseanet-production-client/src/components/authentication/renewPassword.js b/Phraseanet-production-client/src/components/authentication/renewPassword.js
new file mode 100644
index 0000000000..a4bce35925
--- /dev/null
+++ b/Phraseanet-production-client/src/components/authentication/renewPassword.js
@@ -0,0 +1,48 @@
+/*
+ * This file is part of Phraseanet
+ *
+ * (c) 2005-2016 Alchemy
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+import $ from 'jquery';
+import RenewPasswordForm from './common/forms/views/formType/passwordSetter';
+
+const renewPassword = (services) => {
+ const {configService, localeService, appEvents} = services;
+ const initialize = () => {
+
+ require.ensure([], () => {
+ services.zxcvbn = require('zxcvbn');
+ new RenewPasswordForm({
+ services,
+ el: $('form[name=passwordRenewForm]'),
+ rules: [
+ {
+ name: 'password[password]',
+ rules: 'required',
+ message: localeService.t('validation_blank')
+ },
+ {
+ name: 'password[password]',
+ rules: 'min_length[5]',
+ message: localeService.t('validation_length_min', {
+ postProcess: 'sprintf',
+ sprintf: ['5']
+ })
+ },
+ {
+ name: 'password[confirm]',
+ rules: 'matches[password[password]]',
+ message: localeService.t('password_match')
+ }
+ ]
+ });
+ });
+ };
+
+ return {initialize};
+};
+export default renewPassword;
diff --git a/Phraseanet-production-client/src/components/basket/archive.js b/Phraseanet-production-client/src/components/basket/archive.js
new file mode 100644
index 0000000000..20b889264f
--- /dev/null
+++ b/Phraseanet-production-client/src/components/basket/archive.js
@@ -0,0 +1,55 @@
+import $ from 'jquery';
+
+const archiveBasket = (services) => {
+ const { configService, localeService, appEvents } = services;
+ const url = configService.get('baseUrl');
+ let $container = null;
+ const initialize = () => {
+ $container = $('body');
+ $container.on('click', '.basket-archive-action', function (event) {
+ event.preventDefault();
+ let $el = $(event.currentTarget);
+ doArchive($el.data('basket-id'));
+ });
+ };
+
+ function doArchive(basketId) {
+ $.ajax({
+ type: 'POST',
+ url: `${url}prod/baskets/${basketId}/archive/?archive=1`,
+ dataType: 'json',
+ beforeSend: function () {
+
+ },
+ success: function (data) {
+ if (data.success) {
+ const basket = $('#SSTT_' + basketId);
+ const next = basket.next();
+
+ if (next.data('ui-droppable')) {
+ next.droppable('destroy');
+ }
+
+ next.slideUp().remove();
+
+ if (basket.data('ui-droppable')) {
+ basket.droppable('destroy');
+ }
+
+ basket.slideUp().remove();
+
+ if ($('#baskets .SSTT').length === 0) {
+ appEvents.emit('workzone.refresh');
+ }
+ } else {
+ alert(data.message);
+ }
+ return;
+ }
+ });
+ }
+
+ return {initialize};
+};
+
+export default archiveBasket;
diff --git a/Phraseanet-production-client/src/components/basket/browse.js b/Phraseanet-production-client/src/components/basket/browse.js
new file mode 100644
index 0000000000..2f71bd532f
--- /dev/null
+++ b/Phraseanet-production-client/src/components/basket/browse.js
@@ -0,0 +1,276 @@
+import $ from 'jquery';
+import dialog from './../../phraseanet-common/components/dialog';
+require('./../../phraseanet-common/components/tooltip');
+import merge from 'lodash.merge';
+const humane = require('humane-js');
+
+const basketBrowse = (services) => {
+ const { configService, localeService, appEvents } = services;
+ const url = configService.get('baseUrl');
+
+ const initialize = () => {
+ $('body').on('click', '.basket-browse-action', (event) => {
+ event.preventDefault();
+ const $el = $(event.currentTarget);
+ let dialogOptions = {};
+
+ if ($el.attr('title') !== undefined) {
+ dialogOptions.title = $el.attr('title');
+ dialogOptions.width = 920;
+ }
+
+ openModal(dialogOptions);
+ });
+
+ };
+
+ const openModal = (options = {}) => {
+
+ let dialogOptions = merge({
+ size: 'Medium',
+ loading: false
+ }, options);
+ const $dialog = dialog.create(services, dialogOptions);
+
+ return $.get(`${url}prod/WorkZone/Browse/`, function (data) {
+ $dialog.setContent(data);
+ _onDialogReady();
+ return;
+ });
+ };
+
+ const _onDialogReady = () => {
+ const $container = $('#BasketBrowser');
+ let results = null;
+
+ function loadResults(datas, url) {
+ let $results = $('.results', $container);
+ results = $.ajax({
+ type: 'GET',
+ url: url,
+ dataType: 'html',
+ data: datas,
+ beforeSend: function () {
+ if (results && results.abort && typeof results.abort === 'function') {
+ results.abort();
+ }
+ $results.addClass('loading').empty();
+ },
+ error: function () {
+ $results.removeClass('loading');
+ },
+ timeout: function () {
+ $results.removeClass('loading');
+ },
+ success: function (data) {
+ $results.removeClass('loading').append(data);
+ activateLinks($results);
+ active_archiver($results);
+
+ return;
+ }
+
+ });
+ }
+
+
+ function loadBasket(url) {
+ results = $.ajax({
+ type: 'GET',
+ url,
+ dataType: 'html',
+ beforeSend: function () {
+ if (results && results.abort && typeof results.abort === 'function') {
+ results.abort();
+ }
+ $('.Browser', $container).hide();
+ $('.Basket', $container).addClass('loading').empty().show();
+ },
+ error: function () {
+ $('.Browser', $container).show();
+ $('.Basket', $container).removeClass('loading').hide();
+ },
+ timeout: function () {
+ $('.Browser', $container).show();
+ $('.Basket', $container).removeClass('loading').hide();
+ },
+ success: function (data) {
+ $('.Basket', $container).removeClass('loading').append(data);
+
+ $('.Basket a.back', $container).bind('click', function () {
+ $('.Basket', $container).hide();
+ $('.Browser', $container).show();
+
+ return false;
+ });
+ active_archiver($('.Basket', $container));
+
+ return;
+ }
+
+ });
+ }
+
+ function activateLinks($scope) {
+ let confirmBox = {};
+ let buttons = {};
+
+ $('a.result', $scope).bind('click', function (event) {
+ event.preventDefault();
+ var $this = $(this);
+
+ loadResults({}, $this.attr('href'));
+
+ return false;
+ });
+
+ $('.result_page').bind('click', function (event) {
+ event.preventDefault();
+ var $this = $(this);
+
+ loadResults({}, $this.attr('href'));
+
+ return false;
+ });
+
+ $('a.basket_link', $scope).bind('click', function (event) {
+ event.preventDefault();
+ var $this = $(this);
+
+ loadBasket($this.attr('href'));
+
+ return false;
+ });
+
+ $('a.delete-basket', $scope).bind('click', function (event) {
+ event.preventDefault();
+ var $this = $(this);
+ var buttons = {};
+
+ buttons[localeService.t('valider')] = function () {
+ $.ajax({
+ type: 'POST',
+ dataType: 'json',
+ url: $this.attr('href'),
+ data: {},
+ success: function (datas) {
+ if (datas.success) {
+ confirmBox.close();
+ $('form[name="BasketBrowser"]', $container).trigger('submit');
+ appEvents.emit('workzone.refresh');
+ } else {
+ confirmBox.close();
+ var alertBox = dialog.create(services, {
+ size: 'Alert',
+ closeOnEscape: true,
+ closeButton: true
+ }, 2);
+
+ alertBox.setContent(datas.message);
+ }
+ },
+ error: function () {
+ confirmBox.close();
+ var alertBox = dialog.create(services, {
+ size: 'Alert',
+ closeOnEscape: true,
+ closeButton: true
+ }, 2);
+
+ alertBox.setContent("{{'Something wrong happened, please retry or contact an admin.'|trans|e('js') }}");
+ }
+ });
+ };
+
+ confirmBox = dialog.create(services, {
+ size: 'Alert',
+ closeOnEscape: true,
+ cancelButton: true,
+ buttons: buttons
+ }, 2);
+
+ confirmBox.setContent("{{'You are about to delete this basket. Would you like to continue ?'|trans|e('js') }}");
+
+ return false;
+ });
+ }
+
+ function active_archiver($scope) {
+ $('a.UserTips', $scope).bind('click', function () {
+
+ return false;
+ }).tooltip();
+
+ $('.infoTips, .previewTips', $scope).tooltip();
+
+ $('a.archive_toggler', $scope).bind('click', function (event) {
+ event.preventDefault();
+ const $this = $(this);
+ const parent = $this.parent();
+
+ $.ajax({
+ type: 'POST',
+ url: $this.attr('href'),
+ dataType: 'json',
+ beforeSend: function () {
+ $('.loader', parent).show();
+ $('.archive_toggler:visible', parent).addClass('last_act').hide();
+ },
+ error: function () {
+ $('.loader', parent).hide();
+ $('.last_act', parent).removeClass('last_act').show();
+ },
+ timeout: function () {
+ $('.loader', parent).hide();
+ $('.last_act', parent).removeClass('last_act').show();
+ },
+ success: function (data) {
+ $('.loader', parent).hide();
+ $('.last_act', parent).removeClass('last_act');
+ if (!data.success) {
+ humane.error(data.message);
+
+ return;
+ }
+ if (data.archive === true) {
+ $('.unarchiver', parent).show();
+ $('.archiver', parent).hide();
+ $($this).closest('.result').removeClass('unarchived');
+ } else {
+ $('.unarchiver', parent).hide();
+ $('.archiver', parent).show();
+ $($this).closest('.result').addClass('unarchived');
+ }
+
+ appEvents.emit('workzone.refresh');
+
+ return;
+ }
+
+ });
+
+ return false;
+ });
+ }
+
+ $('form[name="BasketBrowser"]', $container).bind('submit', function () {
+
+ let $this = $(this);
+
+ loadResults($this.serializeArray(), $this.attr('action'));
+
+ return false;
+ }).trigger('submit').find('label').bind('click', function () {
+ const input = $(this).prev('input');
+ let inputs = $('input[name="' + $(this).prev('input').attr('name') + '"]', $container);
+ inputs.prop('checked', false).next('label').removeClass('selected');
+
+ input.prop('checked', true).next('label').addClass('selected');
+ $('form[name="BasketBrowser"]', $container).trigger('submit');
+ });
+ };
+
+ return {initialize};
+};
+
+export default basketBrowse;
diff --git a/Phraseanet-production-client/src/components/basket/create.js b/Phraseanet-production-client/src/components/basket/create.js
new file mode 100644
index 0000000000..f32d125b58
--- /dev/null
+++ b/Phraseanet-production-client/src/components/basket/create.js
@@ -0,0 +1,101 @@
+/**
+ * triggered via workzone > Basket > context menu
+ */
+import $ from 'jquery';
+import dialog from './../../phraseanet-common/components/dialog';
+import merge from 'lodash.merge';
+const basketCreate = (services) => {
+ const { configService, localeService, appEvents } = services;
+ const url = configService.get('baseUrl');
+ let searchSelectionSerialized = '';
+ appEvents.listenAll({
+ 'broadcast.searchResultSelection': (selection) => {
+ searchSelectionSerialized = selection.serialized;
+ }
+ });
+
+ const initialize = () => {
+ $('body').on('click', '.basket-create-action', (event) => {
+ event.preventDefault();
+ const $el = $(event.currentTarget);
+ let dialogOptions = {};
+
+ if ($el.attr('title') !== undefined) {
+ dialogOptions.title = $el.attr('title');
+ }
+
+ openModal(dialogOptions);
+ });
+ };
+
+ const openModal = (options = {}) => {
+
+ let dialogOptions = merge({
+ size: 'Small',
+ loading: false
+ }, options);
+ const $dialog = dialog.create(services, dialogOptions);
+
+ return $.get(`${url}prod/baskets/create/`, function (data) {
+ $dialog.setContent(data);
+ _onDialogReady();
+ return;
+ });
+ };
+
+ const _onDialogReady = () => {
+ // recordBridge(services).initialize();
+ var $dialog = dialog.get(1);
+ var $dialogBox = $dialog.getDomElement();
+
+ $('input[name="lst"]', $dialogBox).val(searchSelectionSerialized);
+
+ var buttons = $dialog.getOption('buttons');
+
+ buttons[localeService.t('create')] = function () {
+ $('form', $dialogBox).trigger('submit');
+ };
+
+ $dialog.setOption('buttons', buttons);
+
+ $('form', $dialogBox).bind('submit', function (event) {
+
+ var $form = $(this);
+ var $dialog = $dialogBox.closest('.ui-dialog');
+ var buttonPanel = $dialog.find('.ui-dialog-buttonpane');
+
+ // @TODO should be in a service:
+ $.ajax({
+ type: $form.attr('method'),
+ url: $form.attr('action'),
+ data: $form.serializeArray(),
+ dataType: 'json',
+ beforeSend: function () {
+ $(":button:contains('" + localeService.t('create') + "')", buttonPanel)
+ .attr('disabled', true).addClass('ui-state-disabled');
+ },
+ success: function (data) {
+ appEvents.emit('workzone.refresh', {
+ basketId: data.basket.id
+ });
+ dialog.close(1);
+
+ return;
+ },
+ error: function () {
+ $(":button:contains('" + localeService.t('create ') + "')", buttonPanel)
+ .attr('disabled', false).removeClass('ui-state-disabled');
+ },
+ timeout: function () {
+
+ }
+ });
+
+ return false;
+ });
+ };
+
+ return {initialize};
+};
+
+export default basketCreate;
diff --git a/Phraseanet-production-client/src/components/basket/delete.js b/Phraseanet-production-client/src/components/basket/delete.js
new file mode 100644
index 0000000000..7fb31b50a7
--- /dev/null
+++ b/Phraseanet-production-client/src/components/basket/delete.js
@@ -0,0 +1,122 @@
+import $ from 'jquery';
+import dialog from './../../phraseanet-common/components/dialog';
+
+const deleteBasket = (services) => {
+ const { configService, localeService, appEvents } = services;
+ const url = configService.get('baseUrl');
+ let $container = null;
+ const initialize = () => {
+ $container = $('body');
+ $container.on('click', '.basket-delete-action', function (event) {
+ event.preventDefault();
+ let $el = $(event.currentTarget);
+ deleteConfirmation($el, $el.data('context'));
+ });
+ };
+
+ const deleteConfirmation = ($el, type) => {
+ switch (type) {
+ /*case 'IMGT':
+ case 'CHIM':
+
+ var lst = '';
+
+ if (type === 'IMGT') {
+ lst = p4.Results.Selection.serialize();
+ }
+ if (type === 'CHIM') {
+ lst = p4.WorkZone.Selection.serialize();
+ }
+
+ _deleteRecords(lst);
+ break;
+ */
+ case 'SSTT':
+
+ var buttons = {};
+ buttons[localeService.t('valider')] = function (e) {
+ _deleteBasket($el);
+ };
+
+ $('#DIALOG').empty().append(localeService.t('confirmDel')).attr('title', localeService.t('attention')).dialog({
+ autoOpen: false,
+ resizable: false,
+ modal: true,
+ draggable: false
+ }).dialog('open').dialog('option', 'buttons', buttons);
+ $('#tooltip').hide();
+ break;
+ /*case 'STORY':
+ lst = $el.val();
+ _deleteRecords(lst);
+ break;*/
+ default:
+ }
+ };
+
+ const _deleteBasket = (item) => {
+ if ($('#DIALOG').data('ui-dialog')) {
+ $('#DIALOG').dialog('destroy');
+ }
+ // id de chutier
+ var k = $(item).attr('id').split('_').slice(1, 2).pop();
+ $.ajax({
+ type: 'POST',
+ url: `${url}prod/baskets/${k}/delete/`,
+ dataType: 'json',
+ success: function (data) {
+ if (data.success) {
+ var basket = $('#SSTT_' + k);
+ var next = basket.next();
+
+ if (next.data('ui-droppable')) {
+ next.droppable('destroy');
+ }
+
+ next.slideUp().remove();
+
+ if (basket.data('ui-droppable')) {
+ basket.droppable('destroy');
+ }
+
+ basket.slideUp().remove();
+
+ if ($('#baskets .SSTT').length === 0) {
+ appEvents.emit('workzone.refresh');
+ }
+ } else {
+ alert(data.message);
+ }
+ return;
+ }
+ });
+ };
+
+ /*const _deleteRecords = (lst) => {
+ if (lst.split(';').length === 0) {
+ alert(localeService.t('nodocselected'));
+ return false;
+ }
+ let $dialog = dialog.create(services, {
+ size: 'Small',
+ title: localeService.t('deleteRecords')
+ });
+
+
+ $.ajax({
+ type: 'POST',
+ url: '../prod/records/delete/what/',
+ dataType: 'html',
+ data: {lst: lst},
+ success: function (data) {
+ $dialog.setContent(data);
+ }
+ });
+
+ return false;
+ };*/
+
+ return {initialize, deleteConfirmation};
+};
+
+export default deleteBasket;
diff --git a/Phraseanet-production-client/src/components/basket/index.js b/Phraseanet-production-client/src/components/basket/index.js
new file mode 100644
index 0000000000..8518e68228
--- /dev/null
+++ b/Phraseanet-production-client/src/components/basket/index.js
@@ -0,0 +1,40 @@
+import $ from 'jquery';
+import ui from '../ui';
+import notify from '../notify';
+
+const basket = () => {
+
+ const onUpdatedContent = (data) => {
+
+ if (data.changed.length > 0) {
+ let current_open = $('.SSTT.ui-state-active');
+ let main_open = false;
+ for (let i = 0; i !== data.changed.length; i++) {
+ var sstt = $('#SSTT_' + data.changed[i]);
+ if (sstt.size() === 0) {
+ if (main_open === false) {
+ $('#baskets .bloc').animate({top: 30}, function () {
+ $('#baskets .alert_datas_changed:first').show();
+ });
+ main_open = true;
+ }
+ } else {
+ if (!sstt.hasClass('active')) {
+ sstt.addClass('unread');
+ } else {
+ $('.alert_datas_changed', $('#SSTT_content_' + data.changed[i])).show();
+ }
+ }
+ }
+ }
+ };
+
+
+ const subscribeToEvents = {
+ 'notification.refresh': onUpdatedContent
+ };
+
+ return {subscribeToEvents};
+};
+
+export default basket;
diff --git a/Phraseanet-production-client/src/components/basket/reorderContent.js b/Phraseanet-production-client/src/components/basket/reorderContent.js
new file mode 100644
index 0000000000..bc99add63a
--- /dev/null
+++ b/Phraseanet-production-client/src/components/basket/reorderContent.js
@@ -0,0 +1,259 @@
+/**
+ * triggered via workzone > Basket > context menu
+ */
+import $ from 'jquery';
+import * as _ from 'underscore';
+import dialog from './../../phraseanet-common/components/dialog';
+import Selectable from '../utils/selectable';
+import merge from 'lodash.merge';
+const basketReorderContent = (services) => {
+ const { configService, localeService, appEvents } = services;
+ const url = configService.get('baseUrl');
+ let searchSelectionSerialized = '';
+ appEvents.listenAll({
+ 'broadcast.searchResultSelection': (selection) => {
+ searchSelectionSerialized = selection.serialized;
+ }
+ });
+
+ const initialize = () => {
+ $('body').on('click', '.basket-reorder-content-action', (event) => {
+ event.preventDefault();
+ const $el = $(event.currentTarget);
+ let dialogOptions = {};
+
+ if ($el.attr('title') !== undefined) {
+ dialogOptions.title = $el.attr('title');
+ }
+
+ openModal($el.data('basket-id'), dialogOptions);
+ });
+ };
+
+ const openModal = (basketId, options = {}) => {
+
+ let dialogOptions = merge({
+ size: 'Medium',
+ loading: false
+ }, options);
+ const $dialog = dialog.create(services, dialogOptions);
+
+ return $.get(`${url}prod/baskets/${basketId}/reorder/`, function (data) {
+ $dialog.setContent(data);
+ _onDialogReady();
+ return;
+ });
+ };
+
+ const _onDialogReady = () => {
+ var container = $('#reorder_box');
+
+ $('button.autoorder', container).bind('click', function () {
+ autoorder();
+ return false;
+ });
+ $('button.reverseorder', container).bind('click', function () {
+ reverse_order();
+ return false;
+ });
+
+ function autoorder() {
+ var val = $.trim($('#auto_order').val());
+
+ if (val === '') {
+ return;
+ }
+
+ var diapos = [];
+ $('#reorder_box .diapo form').each(function (i, n) {
+ diapos.push({
+ title: $('input[name=title]', n).val(),
+ order: parseInt($('input[name=default]', n).val(), 10),
+ id: $('input[name=id]', n).val(),
+ date_created: new Date($('input[name=date_created]', n).val()),
+ date_updated: new Date($('input[name=date_updated]', n).val()),
+ });
+ });
+
+ var elements = [];
+ var sorterCallback;
+
+ if (val === 'default') {
+ sorterCallback = function (diapo) {
+ return diapo.order;
+ };
+ elements = sorting(sorterCallback, diapos, false);
+ } else if(val === 'date_updated' || val === 'date_created'){
+ sorterCallback = function(diapo) {
+ if(val === 'date_created') {
+ return diapo.date_created;
+ }
+ return diapo.date_updated;
+ };
+ elements = sorting(sorterCallback, diapos, true);
+ } else {
+ sorterCallback = function(diapo) {return diapo.title.toLowerCase();};
+ elements = sorting(sorterCallback, diapos, false);
+ }
+
+ $('#reorder_box .elements').append(elements);
+ }
+
+ function sorting(sorterCallback, diapos, reverse) {
+ var elements = [];
+ if(reverse == true) {
+ _.chain(diapos)
+ .sortBy(sorterCallback)
+ .reverse()
+ .each(function(diapo) {
+ elements.push($('#ORDER_'+ diapo.id));
+ });
+ }else {
+ _.chain(diapos)
+ .sortBy(sorterCallback)
+ .each(function(diapo) {
+ elements.push($('#ORDER_'+ diapo.id));
+ });
+ }
+ return elements;
+ }
+
+ function reverse_order() {
+ var $container = $('#reorder_box .elements');
+ $('#reorder_box .diapo').each(function () {
+ $(this).prependTo($container);
+ });
+ }
+
+ ('.elements div', container).bind('click', function(){
+ $(this).addClass("selected").siblings().removeClass("selected");
+ return false;
+ });
+
+ $('.elements', container).sortable({
+ appendTo: container,
+ placeholder: 'diapo ui-sortable-placeholder',
+ distance: 20,
+ cursorAt: {
+ top: 10,
+ left: -20
+ },
+ items: 'div.diapo',
+ scroll: true,
+ scrollSensitivity: 40,
+ scrollSpeed: 30,
+ start: function (event, ui) {
+ var selected = $('.selected', container);
+
+ selected.each(function (i, n) {
+ $(n).attr('position', i);
+ });
+
+ var n = selected.length - 1;
+
+ $('.selected:visible', container).hide();
+
+ while (n > 0) {
+ $('
').after($('.diapo.ui-sortable-placeholder', container));
+ n--;
+ }
+ },
+ stop: function (event, ui) {
+
+ $('.diapo.ui-sortable-placeholderfollow', container).remove();
+
+ let main_id = $(ui.item[0]).attr('id');
+
+ let selected = $('.selected', container);
+ let sorter = [];
+
+
+ selected.each(function (i, n) {
+
+ var position = parseInt($(n).attr('position'), 10);
+
+ if (position !== '') {
+ sorter[position] = $(n);
+ }
+
+ var id = $(n).attr('id');
+ if (id === main_id) {
+ return;
+ }
+
+ });
+
+ var before = true;
+ var last_moved = $(ui.item[0]);
+ $(sorter).each(function (i, n) {
+ $(n).show().removeAttr('position');
+ if ($(n).attr('id') === main_id) {
+ before = false;
+ } else {
+ if (before) {
+ $(n).before($(ui.item[0]));
+ } else {
+ $(n).after($(last_moved));
+ }
+
+ }
+ last_moved = sorter[i];
+ });
+
+ },
+ change: function () {
+ $('.diapo.ui-sortable-placeholderfollow', container).remove();
+
+ var n = OrderSelection.length() - 1;
+ while (n > 0) {
+ $('
').after($('.diapo.ui-sortable-placeholder', container));
+ n--;
+ }
+ }
+
+ }).disableSelection();
+
+ var OrderSelection = new Selectable(services, $('.elements', container), {
+ selector: '.CHIM'
+ });
+
+ $('form[name="reorder"] .btn').bind('click', function (event) {
+
+ //$this.SetLoader(true);
+ var $form =$(this).closest('form');
+
+ $('.elements form', container).each(function (i, el) {
+ var id = $('input[name="id"]', $(el)).val();
+
+ $('input[name="element[' + id + ']"]', $form).val(i + 1);
+ });
+
+ $.ajax({
+ type: $form.attr('method'),
+ url: $form.attr('action'),
+ data: $form.serializeArray(),
+ dataType: 'json',
+ beforeSend: function () {
+
+ },
+ success: function (data) {
+ if (!data.success) {
+ alert(data.message);
+ }
+ appEvents.emit('workzone.refresh', {
+ basketId: 'current'
+ });
+ dialog.get(1).close();
+
+ return;
+ }
+ });
+
+ return false;
+ });
+ };
+
+ return {initialize};
+};
+
+export default basketReorderContent;
diff --git a/Phraseanet-production-client/src/components/basket/update.js b/Phraseanet-production-client/src/components/basket/update.js
new file mode 100644
index 0000000000..a6d08e2750
--- /dev/null
+++ b/Phraseanet-production-client/src/components/basket/update.js
@@ -0,0 +1,91 @@
+/**
+ * triggered via workzone > Basket > context menu
+ */
+import $ from 'jquery';
+import dialog from './../../phraseanet-common/components/dialog';
+import merge from 'lodash.merge';
+const humane = require('humane-js');
+
+const basketUpdate = (services) => {
+ const { configService, localeService, appEvents } = services;
+ const url = configService.get('baseUrl');
+ let basketId = false;
+ let searchSelectionSerialized = '';
+ appEvents.listenAll({
+ 'broadcast.searchResultSelection': (selection) => {
+ searchSelectionSerialized = selection.serialized;
+ }
+ });
+
+ const initialize = () => {
+ $('body').on('click', '.basket-update-action', (event) => {
+ event.preventDefault();
+ const $el = $(event.currentTarget);
+ let dialogOptions = {};
+
+ if ($el.attr('title') !== undefined) {
+ dialogOptions.title = $el.attr('title');
+ }
+ basketId = $el.data('basket-id');
+ openModal(dialogOptions);
+ });
+ };
+
+ const openModal = (options = {}) => {
+
+ let dialogOptions = merge({
+ size: 'Medium',
+ loading: false
+ }, options);
+ const $dialog = dialog.create(services, dialogOptions);
+
+ return $.get(`${url}prod/baskets/${basketId}/update/`, (data) => {
+ $dialog.setContent(data);
+ _onDialogReady();
+ return;
+ });
+ };
+
+ const _onDialogReady = () => {
+ $('form[name="basket-rename-box"]').on('submit', function (event) {
+ event.preventDefault();
+ onSubmitRenameForm(event);
+ });
+
+ $('#basket-rename-box button').on('click', function (event) {
+ event.preventDefault();
+ onSubmitRenameForm(event);
+ });
+
+ var onSubmitRenameForm = function (event) {
+ var $form = $(event.currentTarget).closest('form');
+ $.ajax({
+ type: $form.attr('method'),
+ url: $form.attr('action'),
+ dataType: 'json',
+ data: $form.serializeArray(),
+ beforeSend: function () {
+
+ },
+ success: function (data) {
+ dialog.get(1).close();
+ if (data.success) {
+ humane.info(data.message);
+ appEvents.emit('workzone.refresh', {
+ basketId: basketId
+ });
+ } else {
+ humane.error(data.message);
+ return false;
+ }
+ }
+ });
+
+ return false;
+ };
+ };
+
+ return {initialize};
+};
+
+export default basketUpdate;
diff --git a/Phraseanet-production-client/src/components/cgu/index.js b/Phraseanet-production-client/src/components/cgu/index.js
new file mode 100644
index 0000000000..8a6b2b9095
--- /dev/null
+++ b/Phraseanet-production-client/src/components/cgu/index.js
@@ -0,0 +1,62 @@
+import $ from 'jquery';
+import * as appCommons from './../../phraseanet-common';
+const humane = require('humane-js');
+const cgu = (services) => {
+ const { configService, localeService, appEvents } = services;
+ const url = configService.get('baseUrl');
+
+ const initialize = (options = {}) => {
+ const { $container } = options;
+ var $this = $('.cgu-dialog:first');
+ $this.dialog({
+ autoOpen: true,
+ closeOnEscape: false,
+ draggable: false,
+ modal: true,
+ resizable: false,
+ width: 800,
+ height: 500,
+ open: function () {
+ $this.parents('.ui-dialog:first').find('.ui-dialog-titlebar-close').remove();
+ $('.cgus-accept', $(this)).bind('click', function () {
+ acceptCgus($('.cgus-accept', $this).attr('id'), $('.cgus-accept', $this).attr('date'));
+ $this.dialog('close').remove();
+ initialize(services, options);
+ });
+ $('.cgus-cancel', $(this)).bind('click', function () {
+ if (confirm(localeService.t('warningDenyCgus'))) {
+ cancelCgus($('.cgus-cancel', $this).attr('id').split('_').pop());
+ }
+ });
+ }
+ });
+ };
+
+ function acceptCgus(name, value) {
+ appCommons.userModule.setPref(name, value);
+ }
+
+ function cancelCgus(id) {
+
+ $.ajax({
+ type: 'POST',
+ url: `${url}prod/TOU/deny/${id}/`,
+ dataType: 'json',
+ success: function (data) {
+ if (data.success) {
+ alert(localeService.t('cgusRelog'));
+ self.location.replace(self.location.href);
+ } else {
+ humane.error(data.message);
+ }
+ }
+ });
+
+ }
+
+ return {
+ initialize
+ };
+};
+
+export default cgu;
diff --git a/Phraseanet-production-client/src/components/core/applicationConfigService.js b/Phraseanet-production-client/src/components/core/applicationConfigService.js
new file mode 100644
index 0000000000..355458ee5e
--- /dev/null
+++ b/Phraseanet-production-client/src/components/core/applicationConfigService.js
@@ -0,0 +1,91 @@
+let instance = null;
+import * as _ from 'underscore';
+
+export default class ApplicationConfigService {
+ configuration;
+
+ constructor(config) {
+ // if( !instance ) {
+ // instance = this;
+ // }
+ this.configuration = config;
+ // return instance;
+ }
+
+ get(configKey) {
+ if (configKey !== undefined) {
+ var foundValue = this._findKeyValue(configKey || this.configuration);
+ switch (typeof foundValue) {
+ case 'string':
+ return foundValue;
+ default:
+ return foundValue ? foundValue : null;
+
+ }
+
+ }
+
+ return this.configuration;
+ }
+
+ set(configKey, value) {
+ if (configKey !== undefined) {
+ if (typeof this.configuration[configKey] === 'object') {
+ // merge
+ this.configuration[configKey] = _.extend({}, this.configuration[configKey], value);
+ } else {
+ this.configuration[configKey] = value;
+ }
+ }
+ }
+
+ // @TODO cast
+ _findKeyValue(configName) {
+ if (!configName) {
+ return undefined;
+ }
+
+ let isStr = _.isString(configName);
+ let name = isStr ? configName : configName.name;
+ let path = configName.indexOf('.') > 0 ? true : false;
+
+ if (path) {
+ return this._search(this.configuration, name);
+
+ }
+ var state = this.configuration[name];
+ if (state && (isStr || (!isStr && state === configName))) {
+ return state;
+ } else if (isStr) {
+ return state;
+ }
+ return undefined;
+ }
+
+ // @TODO cast
+ _search(obj, path) {
+ if (_.isNumber(path)) {
+ path = [path];
+ }
+ if (_.isEmpty(path)) {
+ return obj;
+ }
+ if (_.isEmpty(obj)) {
+ return null;
+ }
+ if (_.isString(path)) {
+ return this._search(obj, path.split('.'));
+ }
+
+ var currentPath = path[0];
+
+ if (path.length === 1) {
+ if (obj[currentPath] === void 0) {
+ return null;
+ }
+ return obj[currentPath];
+ }
+
+ return this._search(obj[currentPath], path.slice(1));
+ }
+}
diff --git a/Phraseanet-production-client/src/components/core/configService.js b/Phraseanet-production-client/src/components/core/configService.js
new file mode 100644
index 0000000000..dec942c4c1
--- /dev/null
+++ b/Phraseanet-production-client/src/components/core/configService.js
@@ -0,0 +1,17 @@
+import ApplicationConfigService from './applicationConfigService';
+
+let instance = null;
+
+class ConfigService extends ApplicationConfigService {
+ constructor(configuration) {
+ super(configuration);
+ if (!instance) {
+
+ instance = this;
+ }
+
+ return instance;
+ }
+}
+
+export default ConfigService;
diff --git a/Phraseanet-production-client/src/components/core/emitter.js b/Phraseanet-production-client/src/components/core/emitter.js
new file mode 100644
index 0000000000..a94a70dc1a
--- /dev/null
+++ b/Phraseanet-production-client/src/components/core/emitter.js
@@ -0,0 +1,56 @@
+import * as Rx from 'rx';
+var hasOwnProp = {}.hasOwnProperty;
+
+function createName(name) {
+ return '$' + name;
+}
+
+let Emitter = function () {
+ this.subjects = {};
+};
+
+Emitter.prototype.emit = function (name, data) {
+ var fnName = createName(name);
+ this.subjects[fnName] || (this.subjects[fnName] = new Rx.Subject());
+ this.subjects[fnName].onNext(data);
+
+ return this.subjects[fnName];
+};
+
+Emitter.prototype.listen = function (name, handler) {
+ var fnName = createName(name);
+ this.subjects[fnName] || (this.subjects[fnName] = new Rx.Subject());
+ return this.subjects[fnName].subscribe(handler);
+};
+Emitter.prototype.listenAll = function (group, name, handler) {
+ for (let prop in group) {
+ var fnName = createName(prop);
+ this.subjects[fnName] || (this.subjects[fnName] = new Rx.Subject());
+ this.subjects[fnName].subscribe(group[prop]);
+ }
+};
+
+Emitter.prototype.disposeOf = function (startWith) {
+ var search = new RegExp('^\\$' + startWith);
+ var subjects = this.subjects;
+ for (let prop in subjects) {
+ if (hasOwnProp.call(subjects, prop)) {
+ if (search.test(prop)) {
+ subjects[prop].dispose();
+ }
+ }
+ }
+
+ this.subjects = {};
+};
+Emitter.prototype.dispose = function () {
+ var subjects = this.subjects;
+ for (let prop in subjects) {
+ if (hasOwnProp.call(subjects, prop)) {
+ subjects[prop].dispose();
+ }
+ }
+
+ this.subjects = {};
+};
+export default Emitter;
diff --git a/Phraseanet-production-client/src/components/geolocalisation/provider.js b/Phraseanet-production-client/src/components/geolocalisation/provider.js
new file mode 100644
index 0000000000..cd31f2dba0
--- /dev/null
+++ b/Phraseanet-production-client/src/components/geolocalisation/provider.js
@@ -0,0 +1,155 @@
+import _ from 'underscore';
+/**
+ * Set a provider
+ *
+ */
+
+const provider = (services) => {
+ const {configService, localeService, eventEmitter} = services;
+ let accessToken;
+ let defaultPosition;
+ let defaultZoom;
+ let markerDefaultZoom;
+ let activeProvider;
+ let fieldPosition;
+ let defaultMapProvider;
+ let transitionOptions = Object.create(null);
+ let mapLayers = [{name: 'streets', value: 'mapbox://styles/mapbox/streets-v9'}];
+ const initialize = () => {
+ let isValid = false;
+ // select geocoding provider:
+ let geocodingProviders = configService.get('geocodingProviders');
+ _.each(geocodingProviders, (provider) => {
+ if (provider.enabled === true) {
+ activeProvider = provider;
+ accessToken = provider['public-key'];
+ let fieldMapping = provider['position-fields'] !== undefined ? provider['position-fields'] : [];
+
+ fieldPosition = {};
+
+ if (fieldMapping.length > 0) {
+ _.each(fieldMapping, (mapping) => {
+ // latitude and longitude are combined in a composite field
+ if (mapping.type === 'latlng') {
+ fieldPosition = {
+ latitude: (poi) => extractFromPosition('lat', poi[mapping.name]),
+ longitude: (poi) => extractFromPosition('lon', poi[mapping.name])
+ };
+ } else if (mapping.type === 'lat') {
+ // if latitude field mapping is provided, fallback:
+ fieldPosition.latitude = (poi) => isNaN(parseFloat(poi[mapping.name], 10)) ? false : parseFloat(poi[mapping.name], 10);
+ } else if (mapping.type === 'lon') {
+ // if longitude field mapping is provided, fallback:
+ fieldPosition.longitude = (poi) => isNaN(parseFloat(poi[mapping.name], 10)) ? false : parseFloat(poi[mapping.name], 10);
+ }
+ });
+ if (fieldPosition.latitude !== undefined && fieldPosition.longitude !== undefined) {
+ isValid = true;
+ }
+ } else {
+ fieldPosition = {
+ latitude: (poi) => getCoordinatesFromTechnicalInfo(poi, 'lat'),
+ longitude: (poi) => getCoordinatesFromTechnicalInfo(poi, 'lng')
+ };
+ isValid = true;
+ }
+
+
+
+
+ // set default values:
+
+
+ var defaultPositionValue = $('#map-position-from-setting').val();
+ if(defaultPositionValue != '') {
+ defaultPositionValue = defaultPositionValue.split('"');
+ var arr = [];
+ arr.push(defaultPositionValue[1]);
+ arr.push(defaultPositionValue[3]);
+ defaultPosition = arr ;
+ } else {
+ defaultPosition = provider['default-position'];
+ }
+
+
+ defaultZoom = $('#map-zoom-from-setting').val()!='' ? $('#map-zoom-from-setting').val() : provider['default-zoom'] || 2;
+ markerDefaultZoom = provider['marker-default-zoom'] || 12;
+ defaultMapProvider = provider['map-provider'] || "mapboxWebGL";
+ if (provider['map-layers'] && provider['map-layers'].length > 0) {
+ //update map layer;
+ mapLayers = provider['map-layers'];
+ }
+ if (provider['transition-mapboxgl'] !== undefined) {
+ var options = provider['transition-mapboxgl'][0] || [];
+ transitionOptions.animate = options['animate'] !== undefined ? options['animate'] : true;
+ transitionOptions.speed = options['speed'] || 1.2;
+ transitionOptions.curve = options['curve'] || 1.42;
+ }
+ }
+ });
+ if (accessToken === undefined) {
+ isValid = false;
+ }
+ return isValid;
+ }
+
+ const getCoordinatesFromTechnicalInfo = (poi, fieldMapping) => {
+ if (poi["technicalInfo"] !== undefined) {
+ if (fieldMapping == 'lat') {
+ return isNaN(parseFloat(poi["technicalInfo"].latitude, 10)) ? false : parseFloat(poi["technicalInfo"].latitude, 10)
+ } else {
+ return isNaN(parseFloat(poi["technicalInfo"].longitude, 10)) ? false : parseFloat(poi["technicalInfo"].longitude, 10)
+ }
+ }
+ return false;
+ }
+
+ /**
+ * extract latitude or longitude from a position
+ * @param name
+ * @param source
+ * @returns {*}
+ */
+ const extractFromPosition = (name, source) => {
+ if (source === undefined || source === null) {
+ return false;
+ }
+
+ let position = source.split(' ');
+
+ if (position.length !== 2) {
+ position = source.split(',');
+ }
+
+ // ok parse lat
+ if (position.length === 2) {
+ if (name === 'lat' || name === 'latitude') {
+ return parseFloat(position[0])
+ }
+ return parseFloat(position[1])
+ } else {
+ // invalid
+ return false;
+ }
+ };
+
+ const getConfiguration = () => {
+ return {
+ defaultPosition,
+ defaultZoom,
+ markerDefaultZoom,
+ fieldPosition,
+ accessToken,
+ defaultMapProvider,
+ mapLayers,
+ provider: activeProvider,
+ transitionOptions
+ }
+ };
+
+ return {
+ initialize, getConfiguration
+ }
+}
+
+export default provider;
diff --git a/Phraseanet-production-client/src/components/geolocalisation/providers/locales/fr.js b/Phraseanet-production-client/src/components/geolocalisation/providers/locales/fr.js
new file mode 100644
index 0000000000..92c6d3174f
--- /dev/null
+++ b/Phraseanet-production-client/src/components/geolocalisation/providers/locales/fr.js
@@ -0,0 +1,97 @@
+const leafletLocaleFr = {
+ draw: {
+ toolbar: {
+ actions: {
+ title: 'Annulez le dessin',
+ text: 'Annuler'
+ },
+ finish: {
+ title: 'Terminer le dessin',
+ text: 'Terminer'
+ },
+ undo: {
+ title: 'Supprimer le dernier point',
+ text: 'Supprimer le dernier point'
+ },
+ buttons: {
+ polyline: 'Dessiner une polyligne',
+ polygon: 'Dessiner un polygone',
+ rectangle: 'Dessiner un rectangle',
+ circle: 'Dessiner un cercle',
+ marker: 'Dessiner un marqueur'
+ }
+ },
+ handlers: {
+ circle: {
+ tooltip: {
+ start: 'Cliquez et déplacez pour dessiner un cercle.'
+ }
+ },
+ marker: {
+ tooltip: {
+ start: 'Cliquez sur la carte pour placer un marqueur.'
+ }
+ },
+ polygon: {
+ tooltip: {
+ start: 'Cliquez pour commencer à dessiner une forme.',
+ cont: 'Cliquez pour continuer à dessiner une forme.',
+ end: 'Cliquez sur le dernier point pour fermer cette forme.'
+ }
+ },
+ polyline: {
+ error: 'Erreur: Les arrêtes de la forme ne doivent pas se croiser!',
+ tooltip: {
+ start: 'Cliquez pour commencer à dessiner d\'une ligne.',
+ cont: 'Cliquez pour continuer à dessiner une ligne.',
+ end: 'Cliquez sur le dernier point pour terminer la ligne.'
+ }
+ },
+ rectangle: {
+ tooltip: {
+ start: 'Cliquez et déplacez pour dessiner un rectangle.'
+ }
+ },
+ simpleshape: {
+ tooltip: {
+ end: 'Relachez la souris pour finir de dessiner.'
+ }
+ }
+ }
+ },
+ edit: {
+ toolbar: {
+ actions: {
+ save: {
+ title: 'Sauvegardez les changements.',
+ text: 'Sauver'
+ },
+ cancel: {
+ title: 'Annulez l\'édition, ignorer tous les changements.',
+ text: 'Annuler'
+ }
+ },
+ buttons: {
+ edit: 'Editer les couches.',
+ editDisabled: 'Pas de couches à éditer.',
+ remove: 'Supprimer les couches.',
+ removeDisabled: 'Pas de couches à supprimer.'
+ }
+ },
+ handlers: {
+ edit: {
+ tooltip: {
+ text: 'Déplacez les ancres, ou le marqueur pour éditer l\'objet.',
+ subtext: 'Cliquez sur Annuler pour revenir sur les changements.'
+ }
+ },
+ remove: {
+ tooltip: {
+ text: 'Cliquez sur l\'objet à enlever'
+ }
+ }
+ }
+ }
+};
+
+export default leafletLocaleFr;
diff --git a/Phraseanet-production-client/src/components/geolocalisation/providers/mapbox.css b/Phraseanet-production-client/src/components/geolocalisation/providers/mapbox.css
new file mode 100644
index 0000000000..bde6e10916
--- /dev/null
+++ b/Phraseanet-production-client/src/components/geolocalisation/providers/mapbox.css
@@ -0,0 +1,279 @@
+.ui-widget-content .leaflet-popup-content {
+ color: #555555;
+}
+
+.mapbox-logo {
+ display: none;
+}
+
+.phrasea-popup .leaflet-popup-content-wrapper {
+ background: #3b3b3b;
+ color: #fff;
+ font-size: 16px;
+ line-height: 24px;
+ border-radius: 3px;
+}
+
+.phrasea-popup .leaflet-popup-content-wrapper a {
+ color: rgba(255, 255, 255, 0.5);
+}
+
+.phrasea-popup .leaflet-popup-tip-container {
+ width: 30px;
+ height: 15px;
+}
+
+.phrasea-popup .leaflet-popup-content p {
+ color: #FFF;
+
+}
+
+.phrasea-popup .leaflet-popup-content p.help {
+ text-align: center;
+ font-style: italic;
+}
+
+.phrasea-popup .leaflet-popup-tip {
+ border-top: 10px solid #3b3b3b;
+}
+
+.updated-position {
+ text-align: center;
+}
+
+.ui-widget-content .leaflet-container {
+ color: #555555;
+}
+
+.ui-widget-content .leaflet-container label {
+ color: #555555;
+ display: block;
+ font-size: 12px;
+ padding: 0 15px;
+}
+
+.ui-widget-content .leaflet-container form {
+ margin: 10px 0 0 0;
+}
+
+.ui-widget-content .leaflet-container input[type="radio"] {
+ margin: -4px 0 0 0;
+ padding: 0;
+}
+
+.leaflet-control-layers-selector {
+ margin-top: 2px;
+ position: relative;
+ top: 1px;
+}
+
+.leaflet-control-mapbox-geocoder .leaflet-control-mapbox-geocoder-form input {
+ box-shadow: none;
+ font-size: 12px;
+}
+
+.ui-widget-content .leaflet-container form {
+ margin-top: 0;
+}
+
+.mapboxgl-popup-content {
+ background: #555555;
+ width: 200px;
+ font-size: 15px;
+}
+
+.mapboxgl-popup-anchor-top .mapboxgl-popup-tip {
+ border-bottom-color: #555555;
+}
+
+.mapboxgl-popup-anchor-top-left .mapboxgl-popup-tip {
+ border-bottom-color: #555555;
+}
+
+.mapboxgl-popup-anchor-top-right .mapboxgl-popup-tip {
+
+ border-bottom-color: #555555;
+}
+.mapboxgl-popup-anchor-bottom .mapboxgl-popup-tip {
+
+ border-top-color: #555555;
+}
+
+.mapboxgl-popup-anchor-bottom-left .mapboxgl-popup-tip {
+
+ border-top-color: #555555;
+}
+
+.mapboxgl-popup-anchor-bottom-right .mapboxgl-popup-tip {
+
+ border-top-color: #555555;
+}
+
+.mapboxgl-popup-anchor-left .mapboxgl-popup-tip {
+
+ border-right-color: #555555;
+}
+
+.mapboxgl-popup-anchor-right .mapboxgl-popup-tip {
+
+ border-left-color: #555555;
+}
+
+.map-selection-container {
+ position: absolute;
+ width: 30px;
+ height: 30px;
+ top: 130px;
+ right: 10px;
+ border-radius: 5px;
+ border: 2px solid #ccc;
+ background-color: #fff;
+ cursor: pointer;
+ box-sizing: border-box;
+}
+
+.map-selection-container:hover {
+ background-color: #eee;
+}
+
+.map-dropdown-content {
+ display: none;
+ min-width: 80px;
+ position: absolute;
+ right: 0;
+ background: #FFF;
+ padding: 10px;
+ border: 1px solid #ccc;
+ -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
+ -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
+}
+
+.map-dropdown-content label {
+ color: #555555;
+ display: block;
+ font-size: 13px;
+}
+
+.map-drop-btn {
+ background: transparent;
+ width: 100%;
+ height: 100%;
+ box-sizing: border-box;
+ border: none;
+ margin: 0;
+ padding: 0;
+}
+
+.map-drop-btn i {
+ padding: 6px;
+ margin: 0;
+}
+
+.circle-control-container {
+ position: absolute;
+ top: 170px;
+ right: 10px;
+}
+
+#map-notice-btn {
+ position: absolute;
+ top: 6px;
+ left: 6px;
+ background: transparent;
+ cursor: pointer;
+ border: none;
+ width: 30px;
+ height: 30px;
+ margin: 0;
+ padding: 0;
+ display: none;
+}
+
+#map-notice-btn:focus {
+ outline: 0;
+}
+
+#notice-box {
+ display: block;
+ position: absolute;
+ top: 6px;
+ left: 6px;
+ width: 305px;
+ border-radius: 6px;
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
+ background-color: #ffffff;
+ border: solid 1px #8f8f8f;
+ padding: 4px 5px 5px 6px;
+}
+
+.notice-header {
+ display: block;
+}
+
+.notice-title {
+ font-family: Roboto;
+ font-size: 15px;
+ font-weight: 500;
+ letter-spacing: 0px;
+ color: #3e3d3d;
+ margin-left: 6px;
+ line-height: 20px;
+ vertical-align: middle;
+ margin-right: 20px;
+}
+
+.notice-desc {
+ display: block;
+ font-family: Roboto;
+ font-size: 12px;
+ line-height: 1.17;
+ letter-spacing: 0px;
+ color: #3e3d3d;
+ margin: 6px 10px 0px 10px;
+}
+
+.notice-close-btn {
+ position: absolute;
+ top: 0px;
+ right: 2px;
+ font-family: Roboto;
+ font-size: 16px;
+ color: #3e3d3d;
+ cursor: pointer;
+ padding: 4px;
+}
+
+.draw-icon {
+ margin-bottom: 5px;
+ padding: 0;
+ position: relative;
+ border-radius: 5px;
+ border: 2px solid #ccc;
+ background-color: #fff;
+ cursor: pointer;
+ box-sizing: border-box;
+ display: block;
+}
+
+.draw-icon:hover {
+ background-color: rgba(0, 0, 0, 0.05);
+}
+
+.draw-icon.selected {
+ background-color: #aaa;
+}
+
+.draw-icon i {
+ font-size: 20px;
+ line-height: 26px;
+}
+
+.map-dropdown-content label input[type="radio"] {
+ margin: 0px 0 0 0;
+ padding: 0;
+}
+
+.map-dropdown-content.show {
+ display: block;
+}
diff --git a/Phraseanet-production-client/src/components/geolocalisation/providers/mapbox.js b/Phraseanet-production-client/src/components/geolocalisation/providers/mapbox.js
new file mode 100644
index 0000000000..281d9b1c9b
--- /dev/null
+++ b/Phraseanet-production-client/src/components/geolocalisation/providers/mapbox.js
@@ -0,0 +1,1036 @@
+/* eslint-disable quotes */
+/* eslint-disable no-undef */
+import $ from 'jquery';
+import _ from 'underscore';
+import markerCollection from './markerCollection';
+import markerGLCollection from './markerGLCollection';
+import {generateRandStr} from '../../utils/utils';
+import provider from '../provider';
+import leafletLocaleFr from './locales/fr';
+import merge from 'lodash.merge';
+require('mapbox.js/theme/style.css');
+require('mapbox-gl/dist/mapbox-gl.css');
+require('./mapbox.css');
+require('leaflet-draw/dist/leaflet.draw.css');
+require('leaflet-contextmenu/dist/leaflet.contextmenu.css');
+const leafletMap = (services) => {
+ const {configService, localeService, eventEmitter} = services;
+ let $container = null;
+ let parentOptions = {};
+ let tabOptions = {};
+ let mapOptions = {};
+ let mapUID;
+ let mapbox;
+ let mapboxgl;
+ let leafletDraw;
+ let featureLayer = null;
+ let map = null;
+ let geocoder = null;
+ let mapboxClient = null;
+ let $tabContent;
+ let tabContainerName = 'leafletTabContainer';
+ let editable;
+ let drawable;
+ let searchable;
+ let drawnItems;
+ let activeProvider = {};
+ let recordConfig = {};
+ let currentZoomLevel = 0;
+ let shouldUpdateZoom = false;
+ let features = null;
+ let geojson = {};
+ let labelLayerId;
+ let mapboxGLDefaultPosition;
+ let shapesWebGl = {};
+ let MapboxCircle;
+ let mapboxCircleCollection = [];
+ let shouldDrawCircle = false;
+ let shouldRemoveCircle = false;
+ let turf = null;
+ let editableCircleOpts = {
+ editable: true,
+ minRadius: 10,
+ fillColor: '#000000',
+ fillOpacity: 0.05,
+ strokeColor: '#0000ff',
+ strokeOpacity: 0.25,
+ strokeWeight: 2,
+ debugEl: document.getElementById('debug')
+ };
+
+ //let markerMapboxGl = {};
+ const initialize = (options) => {
+ let initWith = {$container, parentOptions} = options;
+ tabOptions = options.tabOptions || false;
+ mapOptions = options.mapOptions !== undefined ? _.extend(mapOptions, options.mapOptions) : mapOptions;
+ editable = options.editable || false;
+ drawable = options.drawable || false;
+ searchable = options.searchable || false;
+ drawnItems = options.drawnItems || false;
+ recordConfig = parentOptions.recordConfig || false;
+
+ mapUID = 'leafletMap' + generateRandStr(5);
+
+ let providerConfig = provider(services);
+ let isProviderInitalized = providerConfig.initialize();
+
+ if (isProviderInitalized === true) {
+ activeProvider = providerConfig.getConfiguration();
+
+ if (tabOptions !== false) {
+ // @TODO deepmerge
+ let tabPlist = _.extend({
+ tabProperties: {
+ id: tabContainerName,
+ title: localeService.t('Geolocalisation'),
+ classes: 'descBoxes'
+ },
+ position: 1
+ }, tabOptions);
+ eventEmitter.emit('appendTab', tabPlist);
+ }
+ }
+ onResizeEditor = _.debounce(onResizeEditor, 300);
+ return isProviderInitalized;
+ };
+
+ const onRecordSelectionChanged = (params) => {
+ if (activeProvider.accessToken === undefined) {
+ return;
+ }
+ let {selection} = params;
+
+ if(map != null ) {
+ if (shouldUseMapboxGl() && !map.loaded()) {
+ //refresh marker after 2 sec
+ setTimeout(function () {
+ refreshMarkers(selection);
+ }, 2000);
+ } else {
+ refreshMarkers(selection);
+ }
+ }
+ };
+
+ const onTabAdded = (params) => {
+ if (activeProvider.accessToken === undefined) {
+ return;
+ }
+ let {origParams, selection} = params;
+ if (origParams.tabProperties.id === tabContainerName) {
+ $container = $(`#${tabContainerName}`, parentOptions.$container);
+ appendMapContent({selection});
+ }
+ };
+
+ const appendMapContent = (params) => {
+ let {selection} = params;
+ initializeMap(selection);
+ }
+
+ const initializeMap = (pois) => {
+ // if not access token provided - stop mapbox loading
+ if (activeProvider.accessToken === undefined) {
+ throw new Error('MapBox require an access token');
+ }
+ require.ensure([], () => {
+ // select geocoding provider:
+ mapbox = require('mapbox.js');
+ leafletDraw = require('leaflet-draw');
+ require('leaflet-contextmenu');
+ mapboxgl = require('mapbox-gl');
+ let MapboxClient = require('mapbox');
+ let MapboxLanguage = require('@mapbox/mapbox-gl-language');
+ MapboxCircle = require('mapbox-gl-circle');
+ turf = require('@turf/turf');
+
+ $container.empty().append(``);
+
+ if (editable) {
+ // init add marker context menu only if 1 record is available and has no coords
+ if (pois.length === 1) {
+ let poiIndex = 0;
+ let selectedPoi = pois[poiIndex];
+ let poiCoords = haveValidCoords(selectedPoi);
+ if (poiCoords === false) {
+ mapOptions = merge({
+ contextmenu: true,
+ contextmenuWidth: 140,
+ contextmenuItems: [{
+ text: localeService.t('mapMarkerAdd'),
+ callback: (e) => {
+ addMarkerOnce(e, poiIndex, selectedPoi)
+ }
+ }]
+ }, mapOptions);
+ }
+ }
+ }
+
+ if (!shouldUseMapboxGl()) {
+ L.mapbox.accessToken = activeProvider.accessToken;
+ map = L.mapbox.map(mapUID, 'mapbox.streets', mapOptions);
+ shouldUpdateZoom = false;
+ map.setView(activeProvider.defaultPosition, activeProvider.defaultZoom);
+ if (searchable) {
+ map.addControl(L.mapbox.geocoderControl('mapbox.places'));
+ }
+ var layers = {
+ Streets: L.mapbox.tileLayer('mapbox.streets'),
+ Outdoors: L.mapbox.tileLayer('mapbox.outdoors'),
+ Satellite: L.mapbox.tileLayer('mapbox.satellite')
+ };
+
+ layers.Streets.addTo(map);
+ L.control.layers(layers).addTo(map);
+ geocoder = L.mapbox.geocoder('mapbox.places');
+
+ if (drawable) {
+ addDrawableLayers();
+ }
+ addMarkersLayers();
+ refreshMarkers(pois);
+ } else {
+ mapboxgl.accessToken = activeProvider.accessToken
+ if (mapboxGLDefaultPosition == null) {
+ mapboxGLDefaultPosition = $.extend([], activeProvider.defaultPosition);
+ mapboxGLDefaultPosition.reverse();
+ }
+ map = new mapboxgl.Map({
+ container: mapUID,
+ style: activeProvider.mapLayers[0].value,
+ center: mapboxGLDefaultPosition, // format different lng/lat
+ zoom: activeProvider.defaultZoom
+ });
+
+ if (!isIE()) {
+ //use mapboxlanguage if not IE11. Waiting for PR to be merged here https://github.com/mapbox/mapbox-gl-language/pulls
+ var language = new MapboxLanguage({defaultLanguage: $('html').attr('lang') || 'en'});
+ map.addControl(language);
+ }
+
+ //markerMapboxGl = new mapboxgl.Marker();
+
+ shouldUpdateZoom = false;
+
+ mapboxClient = new MapboxClient(mapboxgl.accessToken);
+
+ if (drawable) {
+ // disable map rotation using right click + drag
+ map.dragRotate.disable();
+ // disable map rotation using touch rotation gesture
+ map.touchZoomRotate.disableRotation();
+ map.addControl(new mapboxgl.NavigationControl({
+ showCompass: false
+ }));
+
+ $('.map_search_dialog .ui-dialog-titlebar-close').on('click', function (event) {
+ event.preventDefault();
+ $('#EDIT_query').val('');
+ //eventEmitter.emit('shapeRemoved', {shapes: {}, drawnItems: {}});
+ eventEmitter.emit('updateCircleGeo', {shapes: [], drawnItems: []});
+ eventEmitter.emit('updateSearchValue');
+ removeCircleIfExist();
+ removeNoticeControl();
+ });
+
+ $('.submit-geo-search-action').on('click', function (event) {
+ removeCircleIfExist();
+ removeNoticeControl();
+ });
+
+ addCircleDrawControl();
+ addNoticeControl();
+ addCircleGeoDrawing(drawnItems);
+
+ } else {
+ map.addControl(new mapboxgl.NavigationControl());
+ }
+
+ map.on('style.load', function () {
+ // Triggered when `setStyle` is called.
+ if (map.getStyle().name == "Mapbox Streets" || map.getStyle().name == "Mapbox Light") {
+ add3DBuildingsLayersGL();
+ }
+
+ if (geojson.hasOwnProperty('features')) addMarkersLayersGL(geojson);
+
+ });
+
+ map.on('load', function () {
+
+ var layers = map.getStyle().layers;
+
+ for (var i = 0; i < layers.length; i++) {
+ if (layers[i].type === 'symbol' && layers[i].layout['text-field']) {
+ labelLayerId = layers[i].id;
+ break;
+ }
+ }
+
+ geojson = {
+ type: 'FeatureCollection',
+ features: []
+ };
+
+ if (activeProvider.mapLayers.length > 1) {
+ addMapLayerControl(activeProvider.mapLayers);
+ }
+
+ if (!drawable) {
+ addMarkersLayersGL(geojson);
+ refreshMarkers(pois);
+ } else {
+ map.flyTo({
+ center: mapboxGLDefaultPosition, zoom: activeProvider.defaultZoom,
+ ...activeProvider.transitionOptions
+ });
+ //if bounds exist, move to bounds
+ // if (!_.isEmpty(drawnItems)) {
+ // map.fitBounds(drawnItems[0].originalBounds);
+ // } else {
+ // map.flyTo({
+ // center: mapboxGLDefaultPosition, zoom: activeProvider.defaultZoom,
+ // ...activeProvider.transitionOptions
+ // });
+ // }
+
+ //map.on('moveend', calculateBounds).on('zoomend', calculateBounds);
+ }
+ });
+ }
+
+
+ currentZoomLevel = activeProvider.markerDefaultZoom;
+
+ map.on('zoomend', function () {
+ if (shouldUpdateZoom) {
+ currentZoomLevel = map.getZoom();
+ }
+ $('#map-zoom-to-setting').val(map.getZoom());
+ });
+
+ map.on('dragend', function () {
+ var LngLat = map.getCenter();
+ var arr= [];
+ arr.push(String(LngLat['lat']));
+ arr.push(String(LngLat['lng']));
+ $('#map-position-to-setting').val('["'+LngLat['lat']+'","'+LngLat['lng'] +'"]');
+ });
+
+ map.on('remove', function () {
+ console.log('remove');
+ });
+
+ });
+ };
+
+ const removeCircleIfExist = () => {
+ if (mapboxCircleCollection.length > 0) {
+ _.each(mapboxCircleCollection, function (circleObj) {
+ circleObj.remove();
+ });
+ }
+ }
+
+ const boundsTo5percentRadius = (bounds) => {
+ // noinspection JSUnresolvedVariable
+ // noinspection JSCheckFunctionSignatures
+ return Math.round(
+ turf.distance(bounds.getSouthWest().toArray(), bounds.getNorthEast().toArray(), {units: 'meters'}) * .05);
+ }
+
+ const calculateBounds = () => {
+ //get visible bounds of map
+ var bounds = map.getBounds();
+ var refactoredBoundsCoordinates = refactoredBounds(bounds);
+ shapesWebGl['0'] = {
+ type: 'rectangle',
+ latlng: refactoredBoundsCoordinates,
+ bounds: getMappedFieldsCollection(refactoredBoundsCoordinates),
+ originalBounds: bounds
+ };
+ eventEmitter.emit('shapeCreated', {shapes: shapesWebGl, drawnItems: shapesWebGl});
+ }
+
+ const refactoredBounds = (bounds) => {
+ if (bounds !== undefined) {
+ var LngLat = [];
+ var sw = bounds._sw;
+ var nw = {lng: bounds._sw.lng, lat: bounds._ne.lat};
+ var ne = bounds._ne;
+ var se = {lng: bounds._ne.lng, lat: bounds._sw.lat};
+ var LngLat = [sw, nw, ne, se];
+ return LngLat;
+ }
+ }
+
+ const addNoticeControl = () => {
+ let controlContainerList = $('.mapboxgl-control-container');
+ let $noticeButton = $(' ');
+ controlContainerList.append($noticeButton);
+
+ let $noticeBox = $('' + localeService.t("description notice") + ' ');
+ controlContainerList.append($noticeBox);
+
+ $noticeButton.on('click', function (event) {
+ $noticeBox.show();
+ $noticeButton.hide();
+ });
+
+ $('.notice-close-btn').on('click', function (event) {
+ $noticeBox.hide();
+ $noticeButton.show();
+ });
+ }
+
+ const removeNoticeControl = () => {
+ let controlContainerList = $('.mapboxgl-control-container');
+ if (controlContainerList.find('#notice-box').length > 0) {
+ $('#notice-box').remove();
+ }
+ }
+
+ const addCircleDrawControl = () => {
+ // let controlContainerList = $('.mapboxgl-control-container');
+ // let $circleControlContainer = $('
');
+ // controlContainerList.append($circleControlContainer);
+ // let $toggleDrawCircleButton = $(' ');
+ // let $toggleRemoveCircleButton = $(' ');
+ // $circleControlContainer.empty().append($toggleDrawCircleButton).append($toggleRemoveCircleButton);
+ //
+ // $toggleDrawCircleButton.on('click', function (event) {
+ // $(this).toggleClass('selected');
+ // shouldDrawCircle = !shouldDrawCircle;
+ // if (shouldDrawCircle) {
+ // if ($('#map-circle-remove-btn').hasClass('selected')) {
+ // $('#map-circle-remove-btn').removeClass('selected');
+ // shouldRemoveCircle = !shouldRemoveCircle;
+ // }
+ // }
+ // });
+ //
+ // $toggleRemoveCircleButton.on('click', function (event) {
+ // $(this).toggleClass('selected');
+ // shouldRemoveCircle = !shouldRemoveCircle;
+ // if (shouldRemoveCircle) {
+ // if ($('#map-circle-draw-btn').hasClass('selected')) {
+ // $('#map-circle-draw-btn').removeClass('selected');
+ // shouldDrawCircle = !shouldDrawCircle;
+ // }
+ // }
+ // });
+ //
+ // map.on('click', function (e) {
+ // if (shouldDrawCircle) {
+ // addCircle(e.lonLat, boundsTo5percentRadius(map.getBounds()));
+ // }
+ // });
+
+ map.on('contextmenu', function (e) {
+ addCircle(e.lngLat, boundsTo5percentRadius(map.getBounds()));
+ });
+ }
+
+ const addCircleGeoDrawing = (drawnItems) => {
+ _.map(drawnItems, function (items) {
+ var lngLat = {};
+ lngLat['lng'] = items.center.lng;
+ lngLat['lat'] = items.center.lat;
+ addCircle(lngLat, items.radius);
+ });
+ }
+
+ const addCircle = (lngLat, radius) => {
+ var myCircle = new MapboxCircle(lngLat, radius, editableCircleOpts)
+ .once('click', function (mapMouseEvent) {
+ var instanceId = myCircle.__instanceId;
+ myCircle.remove();
+ mapboxCircleCollection = _.reject(mapboxCircleCollection, function (circleObj) {
+ return circleObj.__instanceId === instanceId;
+ });
+ eventEmitter.emit('updateCircleGeo', {
+ shapes: mapboxCircleCollection,
+ drawnItems: mapboxCircleCollection
+ });
+ })
+ .on('centerchanged', function (circleObj) {
+ eventEmitter.emit('updateCircleGeo', {
+ shapes: mapboxCircleCollection,
+ drawnItems: mapboxCircleCollection
+ });
+ })
+ .on('radiuschanged', function (circleObj) {
+ eventEmitter.emit('updateCircleGeo', {
+ shapes: mapboxCircleCollection,
+ drawnItems: mapboxCircleCollection
+ });
+ })
+ .addTo(map);
+
+ mapboxCircleCollection.push(myCircle);
+ eventEmitter.emit('updateCircleGeo', {shapes: mapboxCircleCollection, drawnItems: mapboxCircleCollection});
+ }
+
+ const addMapLayerControl = (layerArray) => {
+ let controlContainerList = $('.mapboxgl-control-container');
+
+ _.each(controlContainerList, (controlContainer) => {
+ if ($(controlContainer).find('.map-selection-container').length > 0) {
+ $(controlContainer).find('.map-selection-container').remove();
+ }
+
+ let mapSelectionContainer =
+ $('');
+
+ var $mapSelectionDropDown = mapSelectionContainer.find('#mapSelectionDropDown');
+
+ $(controlContainer).append(mapSelectionContainer);
+
+ $(controlContainer).on('click', 'button', function (event) {
+ $mapSelectionDropDown.get(0).classList.toggle("show");
+ });
+
+
+ var map_list_div = document.createElement('div');
+ _.each(layerArray, (layer, index) => {
+ var div_layer = document.createElement('div');
+ //add checked attr for first element
+ var isChecked = index == 0 ? "checked=checked" : "";
+ $(div_layer).append(`
+ ${layer.name} `);
+ $(map_list_div).append(div_layer);
+ });
+
+ $mapSelectionDropDown.empty().append(map_list_div);
+ $(controlContainer).on('click', 'input[name="mapradio"]', function (event) {
+ switchLayer($(event.target));
+ });
+
+
+ $('body').on('click', function (event) {
+ if ($(event.target).is('button.map-drop-btn') ||
+ $(event.target).is('button.map-drop-btn i')) {
+ return;
+ } else {
+ var dropdowns = $mapSelectionDropDown;
+ var i;
+ for (i = 0; i < dropdowns.length; i++) {
+ var openDropdown = dropdowns[i];
+ if (openDropdown.classList.contains('show')) {
+ openDropdown.classList.remove('show');
+ }
+ }
+ }
+ });
+ });
+
+ }
+
+ const switchLayer = ($elem) => {
+ map.setStyle($elem.val());
+ }
+
+ const addDrawableLayers = () => {
+
+ if (localeService.getLocale() === 'fr') {
+ L.drawLocal = leafletLocaleFr;
+ }
+ // should restore drawn items?
+ // user.getPreferences
+ let drawingGroup;
+ drawingGroup = new L.FeatureGroup();
+
+ map.addLayer(drawingGroup);
+
+ // Initialise the draw control and pass it the FeatureGroup of editable layers
+ let drawControl = new L.Control.Draw({
+ draw: {
+ circle: false,
+ polyline: false,
+ polygon: false,
+ marker: false,
+ position: 'topleft',
+ rectangle: {
+ //title: 'Draw a sexy polygon!',
+ allowIntersection: false,
+ drawError: {
+ color: '#b00b00',
+ timeout: 1000
+ },
+ shapeOptions: {
+ color: '#0c4554'
+ },
+ showArea: true
+ }
+ },
+ edit: {
+ featureGroup: drawingGroup
+ }
+ });
+ let shapesDrawned = {};
+ map.addControl(drawControl);
+
+ map.on('draw:created', (event) => {
+ let type = event.layerType;
+ let layer = event.layer;
+ let layerId = drawingGroup.getLayerId(layer);
+
+ shapesDrawned[layerId] = {
+ type: type,
+ options: layer.options,
+ latlng: layer.getLatLngs(),
+ bounds: getMappedFieldsCollection(layer.getLatLngs())
+ };
+ drawingGroup.addLayer(layer);
+ eventEmitter.emit('shapeCreated', {shapes: shapesDrawned, drawnItems: shapesDrawned});
+ });
+
+ map.on('draw:edited', (event) => {
+ let layers = event.layers;
+
+ layers.eachLayer(function (layer) {
+ let layerId = drawingGroup.getLayerId(layer);
+ // get type from drawed shape:
+ let currentType = shapesDrawned[layerId].type;
+ shapesDrawned[layerId] = merge(shapesDrawned[layerId], {
+ options: layer.options,
+ latlng: layer.getLatLngs(),
+ bounds: getMappedFieldsCollection(layer.getLatLngs())
+ })
+ });
+ eventEmitter.emit('shapeEdited', {shapes: shapesDrawned, drawnItems: shapesDrawned});
+ });
+
+ map.on('draw:deleted', (event) => {
+ let layers = event.layers;
+ layers.eachLayer(function (layer) {
+ let layerId = drawingGroup.getLayerId(layer);
+ delete shapesDrawned[layerId];
+ });
+ eventEmitter.emit('shapeRemoved', {shapes: shapesDrawned, drawnItems: shapesDrawned});
+ });
+
+ // draw serialized items:
+ applyDrawings(drawnItems, drawingGroup);
+ };
+
+ /***
+ * Draw serialized shapes
+ * @param shapesDrawned
+ * @param drawingGroup
+ */
+ const applyDrawings = (shapesDrawned, drawingGroup) => {
+ for (let shapeIndex in shapesDrawned) {
+ if (shapesDrawned.hasOwnProperty(shapeIndex)) {
+ let shape = shapesDrawned[shapeIndex];
+
+ let newShape = L.rectangle(shape.latlng, shape.options);
+ let newShapeType = '';
+ switch (shape.type) {
+ case 'rectangle':
+ newShape = L.rectangle(shape.latlng, shape.options);
+ newShapeType = L.Draw.Rectangle.TYPE;
+ break;
+ default:
+ newShape = L.rectangle(shape.latlng, shape.options);
+ newShapeType = L.Draw.Rectangle.TYPE;
+ }
+ // start editor for new shape:
+ newShape.editing.enable();
+ drawingGroup.addLayer(newShape);
+ // fire created event manually:
+ map.fire('draw:created', {layer: newShape, layerType: newShapeType});
+ newShape.editing.disable();
+ }
+ }
+ }
+ const addMarkerOnce = (e, poiIndex, poi) => {
+ // inject coords into poi's fields:
+ let mappedCoords = getMappedFields(e.latlng);
+ let pois = [merge(poi, mappedCoords)];
+ refreshMarkers(pois).then(() => {
+ // broadcast event:
+ let wrappedMappedFields = {};
+ // values needs to be wrapped in a array:
+ for (let fieldIndex in mappedCoords) {
+ if (mappedCoords.hasOwnProperty(fieldIndex)) {
+ wrappedMappedFields[fieldIndex] = [mappedCoords[fieldIndex]]
+ }
+ }
+
+ let presets = {
+ fields: wrappedMappedFields //presetFields
+ };
+ map.contextmenu.disable();
+ eventEmitter.emit('recordEditor.addPresetValuesFromDataSource', {data: presets, recordIndex: poiIndex});
+ });
+ }
+
+ const add3DBuildingsLayersGL = () => {
+ map.addLayer({
+ 'id': '3d-buildings',
+ 'source': 'composite',
+ 'source-layer': 'building',
+ 'filter': ['==', 'extrude', 'true'],
+ 'type': 'fill-extrusion',
+ 'minzoom': 15,
+ 'paint': {
+ 'fill-extrusion-color': '#aaa',
+
+ // use an 'interpolate' expression to add a smooth transition effect to the
+ // buildings as the user zooms in
+ 'fill-extrusion-height': [
+ "interpolate", ["linear"], ["zoom"],
+ 15, 0,
+ 15.05, ["get", "height"]
+ ],
+ 'fill-extrusion-base': [
+ "interpolate", ["linear"], ["zoom"],
+ 15, 0,
+ 15.05, ["get", "min_height"]
+ ],
+ 'fill-extrusion-opacity': .6
+ }
+ }, labelLayerId);
+ }
+
+ const addMarkersLayersGL = (geojson) => {
+
+ map.addSource('data', {
+ type: 'geojson',
+ data: geojson
+ });
+
+ map.addLayer({
+ id: 'points',
+ source: 'data',
+ type: 'symbol',
+ layout: {
+ "icon-image": "star-15",
+ "icon-size": 1.5
+ },
+ });
+ }
+
+ const addMarkersLayers = () => {
+ if (featureLayer !== null) {
+ featureLayer.clearLayers();
+ } else {
+ featureLayer = L.mapbox.featureLayer([], {
+ pointToLayer: function (feature, latlng) {
+ if (feature.properties.radius !== undefined) {
+ // L.circleMarker() draws a circle with fixed radius in pixels.
+ // To draw a circle overlay with a radius in meters, use L.circle()
+ return L.circleMarker(latlng, {radius: feature.properties.radius || 10});
+ } else {
+ let marker = require('mapbox.js/src/marker.js'); //L.marker(feature);
+ return marker.style(feature, latlng, {accessToken: activeProvider.accessToken});
+ }
+ }
+ }).addTo(map);
+ }
+ };
+
+ const refreshMarkers = (pois) => {
+
+ return buildGeoJson(pois).then((geoJsonPoiCollection) => {
+ if(map != null) {
+ if (shouldUseMapboxGl()) {
+ geojson = {
+ type: 'FeatureCollection',
+ features: geoJsonPoiCollection
+ };
+
+ map.getSource('data').setData(geojson);
+
+ let markerGlColl = markerGLCollection(services);
+ markerGlColl.initialize({map, geojson, editable});
+
+ if (geojson.features.length > 0) {
+ shouldUpdateZoom = true;
+ // var popup = new mapboxgl.Popup()
+ // .setText(geojson.features[0].properties.title);
+ //markerMapboxGl.setLngLat(geojson.features[0].geometry.coordinates).setPopup(popup).addTo(map);
+ map.flyTo({
+ center: geojson.features[0].geometry.coordinates, zoom: currentZoomLevel,
+ ...activeProvider.transitionOptions
+ });
+ var position = {};
+ position.lng = geojson.features[0].geometry.coordinates[0];
+ position.lat = geojson.features[0].geometry.coordinates[1];
+ updateMarkerPosition(geojson.features[0].properties.recordIndex, position);
+
+ } else {
+ shouldUpdateZoom = false;
+ //markerMapboxGl.setLngLat(activeProvider.defaultPosition).addTo(map);
+ map.flyTo({
+ center: mapboxGLDefaultPosition, zoom: activeProvider.defaultZoom,
+ ...activeProvider.transitionOptions
+ });
+ }
+ } else {
+ addMarkersLayers();
+
+ let markerColl = markerCollection(services);
+ markerColl.initialize({map, featureLayer, geoJsonPoiCollection, editable});
+
+ if (featureLayer.getLayers().length > 0) {
+ shouldUpdateZoom = true;
+ map.fitBounds(featureLayer.getBounds(), {maxZoom: currentZoomLevel});
+ var position = {};
+ position.lng = featureLayer.getGeoJSON()[0].geometry.coordinates[0];
+ position.lat = featureLayer.getGeoJSON()[0].geometry.coordinates[1];
+ updateMarkerPosition(featureLayer.getGeoJSON()[0].properties.recordIndex, position);
+ console.log('ato');
+ } else {
+ // set default position
+ shouldUpdateZoom = false;
+ map.setView(activeProvider.defaultPosition, activeProvider.defaultZoom);
+ }
+ }
+ }
+ })
+
+ };
+ /**
+ * build geoJson features return as a promise
+ * @param pois
+ * @returns {*}
+ */
+ const buildGeoJson = (pois) => {
+ let geoJsonPoiCollection = [];
+ let asyncQueries = [];
+ let geoJsonPromise = $.Deferred();
+
+ for (let poiIndex in pois) {
+ let poi = pois[poiIndex];
+ let poiCoords = extractCoords(poi);
+ let poiTitle = poi.FileName || poi.Filename || poi.Title || poi.NomDeFichier;
+ if (poiCoords[0] !== false && poiCoords[1] !== false) {
+ geoJsonPoiCollection.push({
+ type: 'Feature',
+ geometry: {
+ type: 'Point',
+ coordinates: poiCoords
+ },
+ properties: {
+ recordIndex: poiIndex,
+ 'marker-color': '0c4554',
+ 'marker-zoom': currentZoomLevel,
+ title: `${poiTitle}`
+ }
+ });
+ } else {
+ // coords are not available, fallback on city/province/country if available
+
+ let query = '';
+ query += poi.City !== undefined && poi.City !== null ? poi.City : '';
+ query += poi.Country !== undefined && poi.Country !== null ? `, ${poi.Country} ` : '';
+
+ if (query !== '') {
+ if (shouldUseMapboxGl()) {
+ getDataForMapboxGl(asyncQueries, query, poiIndex, poiTitle, geoJsonPoiCollection);
+ } else {
+ getDataForMapbox(asyncQueries, query, poiIndex, poiTitle, geoJsonPoiCollection);
+ }
+ }
+ }
+ }
+
+ if (asyncQueries.length > 0) {
+ $.when.apply(null, asyncQueries).done(function () {
+ geoJsonPromise.resolve(geoJsonPoiCollection)
+ });
+ } else {
+ geoJsonPromise.resolve(geoJsonPoiCollection)
+ }
+ return geoJsonPromise.promise();
+ };
+
+ const getDataForMapboxGl = (asyncQueries, query, poiIndex, poiTitle, geoJsonPoiCollection) => {
+ let geoPromise = $.Deferred();
+ mapboxClient.geocodeForward(query, (err, data) => {
+ // take the first feature if exists
+ if (data !== undefined) {
+ if (data.features.length > 0) {
+ let bestResult = data.features[0];
+ bestResult.properties.recordIndex = poiIndex;
+ bestResult.properties['marker-zoom'] = currentZoomLevel;
+ bestResult.properties['marker-color'] = "0c4554";
+ bestResult.properties.title = `${poiTitle}`;
+ geoJsonPoiCollection.push(bestResult);
+ }
+ }
+ geoPromise.resolve(geoJsonPoiCollection)
+ });
+ asyncQueries.push(geoPromise);
+ }
+
+ const getDataForMapbox = (asyncQueries, query, poiIndex, poiTitle, geoJsonPoiCollection) => {
+ let geoPromise = $.Deferred();
+ geocoder.query(query, (err, data) => {
+ // take the first feature if exists
+ if (data.results !== undefined) {
+ if (data.results.features.length > 0) {
+
+ /*let circleArea = {
+ type: 'Feature',
+ geometry: {
+ type: 'Point',
+ coordinates: data.results.features[0].center //[[ data.bounds ]]
+ },
+ properties: {
+ title: `${poi.FileName}`
+ }
+ };
+ circleArea.properties['marker-zoom'] = 5;
+ circleArea.properties.radius = 50;
+ geoJsonPoiCollection.push(circleArea);*/
+
+ let bestResult = data.results.features[0];
+ bestResult.properties.recordIndex = poiIndex;
+ bestResult.properties['marker-zoom'] = currentZoomLevel;
+ bestResult.properties.title = `${poiTitle}`;
+ geoJsonPoiCollection.push(bestResult);
+ }
+ }
+ geoPromise.resolve(geoJsonPoiCollection)
+ });
+ asyncQueries.push(geoPromise);
+ }
+
+ const extractCoords = (poi) => {
+ if (poi !== undefined) {
+ return [activeProvider.fieldPosition.longitude(poi), activeProvider.fieldPosition.latitude(poi)];
+ }
+ return [false, false];
+ };
+
+ const haveValidCoords = (poi) => {
+ if (poi !== undefined) {
+ return activeProvider.fieldPosition.longitude(poi) && activeProvider.fieldPosition.latitude(poi)
+ }
+ return false;
+ };
+
+ let onResizeEditor = () => {
+ if (activeProvider.accessToken === undefined) {
+ return;
+ }
+ if (map !== null) {
+ if (shouldUseMapboxGl()) {
+ map.resize();
+ if (geojson.hasOwnProperty('features') && geojson.features.length > 0) {
+ shouldUpdateZoom = true;
+ //markerMapboxGl.setLngLat(geojson.features[0].geometry.coordinates).addTo(map);
+ map.flyTo({
+ center: geojson.features[0].geometry.coordinates, zoom: currentZoomLevel,
+ ...activeProvider.transitionOptions
+ });
+ } else {
+ shouldUpdateZoom = false;
+ //markerMapboxGl.setLngLat(activeProvider.defaultPosition).addTo(map);
+ map.flyTo({
+ center: mapboxGLDefaultPosition, zoom: activeProvider.defaultZoom,
+ ...activeProvider.transitionOptions
+ });
+ }
+ } else {
+ map.invalidateSize();
+ if (featureLayer.getLayers().length > 0) {
+ shouldUpdateZoom = true;
+ map.fitBounds(featureLayer.getBounds(), {maxZoom: currentZoomLevel});
+ } else {
+ // set default position
+ shouldUpdateZoom = false;
+ map.setView(activeProvider.defaultPosition, activeProvider.defaultZoom);
+ }
+ }
+
+ }
+ };
+
+ const onMarkerChange = (params) => {
+ let {marker, position} = params;
+
+ if (editable) {
+ updateMarkerPosition(marker.feature.properties.recordIndex, position);
+ }
+ };
+
+ const updateMarkerPosition = (recordIndex, position) => {
+ let mappedFields = getMappedFields(position);
+ let wrappedMappedFields = {};
+ // values needs to be wrapped in a array:
+ for (let mappedFieldIndex in mappedFields) {
+ if (mappedFields.hasOwnProperty(mappedFieldIndex)) {
+ wrappedMappedFields[mappedFieldIndex] = [mappedFields[mappedFieldIndex]]
+ }
+ }
+
+ let presets = {
+ fields: wrappedMappedFields //presetFields
+ };
+
+ eventEmitter.emit('recordEditor.addPresetValuesFromDataSource', {data: presets, recordIndex});
+}
+ const getMappedFields = (position) => {
+ let fieldMapping = activeProvider.provider['position-fields'] !== undefined ? activeProvider.provider['position-fields'] : [];
+ let mappedFields = {};
+ if (fieldMapping.length > 0) {
+
+ _.each(fieldMapping, (mapping) => {
+ // latitude and longitude are combined in a composite field
+ if (mapping.type === 'latlng') {
+ mappedFields[mapping.name] = `${position.lat} ${position.lng}`;
+ } else if (mapping.type === 'lat') {
+ mappedFields[mapping.name] = `${position.lat}`;
+ } else if (mapping.type === 'lon') {
+ mappedFields[mapping.name] = `${position.lng}`;
+ }
+ });
+ } else {
+ mappedFields["meta.Latitude"] = `${position.lat}`;
+ mappedFields["meta.Longitude"] = `${position.lng}`;
+ }
+ return mappedFields;
+ }
+
+ const getMappedFieldsCollection = (positions) => {
+ let mappedPositions = [];
+ for (let positionIndex in positions) {
+ if (positions.hasOwnProperty(positionIndex)) {
+ mappedPositions.push(getMappedFields(positions[positionIndex]))
+ }
+ }
+ return mappedPositions;
+ }
+
+ const shouldUseMapboxGl = () => {
+ if (activeProvider.defaultMapProvider === "mapboxWebGL" && mapboxgl !== undefined && mapboxgl.supported()) {
+ return true;
+ }
+ return false;
+ }
+
+ const isIE = () => {
+ let ua = navigator.userAgent;
+ /* MSIE used to detect old browsers and Trident used to newer ones*/
+ var is_ie = ua.indexOf("MSIE ") > -1 || ua.indexOf("Trident/") > -1;
+
+ return is_ie;
+ }
+
+ eventEmitter.listenAll({
+ 'recordSelection.changed': onRecordSelectionChanged,
+ 'appendTab.complete': onTabAdded,
+ /* eslint-disable quote-props */
+ 'markerChange': onMarkerChange,
+ 'tabChange': onResizeEditor,
+ });
+ return {initialize, appendMapContent}
+};
+
+export default leafletMap;
diff --git a/Phraseanet-production-client/src/components/geolocalisation/providers/markerCollection.js b/Phraseanet-production-client/src/components/geolocalisation/providers/markerCollection.js
new file mode 100644
index 0000000000..027468be7f
--- /dev/null
+++ b/Phraseanet-production-client/src/components/geolocalisation/providers/markerCollection.js
@@ -0,0 +1,122 @@
+import $ from 'jquery';
+
+const markerCollection = (services) => {
+ const {configService, localeService, eventEmitter} = services;
+ let markerCollection = {};
+ let cachedGeoJson;
+ let featureLayer;
+ let map;
+ let geoJsonPoiCollection;
+ let editable;
+
+ const initialize = (params) => {
+ let initWith = {map, featureLayer, geoJsonPoiCollection} = params;
+ editable = params.editable || false;
+ setCollection(geoJsonPoiCollection)
+ };
+
+ const setCollection = (geoJsonPoiCollection) => {
+ featureLayer.setGeoJSON(geoJsonPoiCollection);
+ cachedGeoJson = featureLayer.getGeoJSON();
+ featureLayer.eachLayer(function (layer) {
+ setMarkerPopup(layer);
+ });
+
+ };
+
+ const triggerRefresh = () => {
+ setCollection(cachedGeoJson);
+ cachedGeoJson = featureLayer.getGeoJSON();
+ };
+
+ const setMarkerPopup = (marker) => {
+ switch (marker.feature.geometry.type) {
+ case 'Polygon':
+ break;
+ case 'Point':
+ setPoint(marker);
+ break;
+ default:
+ }
+ };
+
+ const setPoint = (marker) => {
+ markerCollection[marker._leaflet_id] = marker;
+ let $content = $('
');
+
+ let template = `${marker.feature.properties.title}
`;
+
+ if (editable === true && marker.dragging !== undefined) {
+ template += `
+
+ ${localeService.t('mapMarkerEdit')}
+
+
+
${localeService.t('mapMarkerMoveLabel')}
+
+
+ ${localeService.t('mapMarkerEditCancel')}
+ ${localeService.t('mapMarkerEditSubmit')}
+
+
`;
+ }
+
+ $content.append(template);
+
+ $content.find('.edit-mode').hide();
+
+ $content.on('click', '.edit-position', (event) => {
+ let $el = $(event.currentTarget);
+ let marker = getMarker($el.data('marker-id'));
+ marker._originalPosition = marker.getLatLng().wrap();
+ marker.dragging.enable();
+ $content.find('.view-mode').hide();
+ $content.find('.edit-mode').show();
+ $content.find('.help').show();
+ });
+
+ $content.on('click', '.submit-position', (event) => {
+ let $el = $(event.currentTarget);
+ let marker = getMarker($el.data('marker-id'));
+
+ marker.dragging.disable();
+ $content.find('.view-mode').show();
+ $content.find('.help').hide();
+ $content.find('.edit-mode').hide();
+ marker._originalPosition = marker.getLatLng().wrap();
+ eventEmitter.emit('markerChange', {marker, position: marker.getLatLng().wrap()});
+ });
+
+
+ $content.on('click', '.cancel-position', (event) => {
+ let $el = $(event.currentTarget);
+ let marker = getMarker($el.data('marker-id'));
+ marker.dragging.disable();
+ $content.find('.view-mode').show();
+
+ marker.setLatLng(marker._originalPosition);
+ triggerRefresh();
+ });
+
+ marker.bindPopup($content.get(0));
+
+ marker.on('dragend', () => {
+ let position = marker.getLatLng().wrap();
+ $content.find('.updated-position').html(`${position.lat} ${position.lng}`);
+ $content.find('.edit-mode').show();
+ marker.bindPopup($content.get(0));
+ marker.openPopup();
+ })
+
+ }
+
+ const getMarker = (markerId) => {
+ return markerCollection[markerId];
+ }
+
+ return {
+ initialize, setCollection
+ }
+}
+
+export default markerCollection;
diff --git a/Phraseanet-production-client/src/components/geolocalisation/providers/markerGLCollection.js b/Phraseanet-production-client/src/components/geolocalisation/providers/markerGLCollection.js
new file mode 100644
index 0000000000..30d02fa689
--- /dev/null
+++ b/Phraseanet-production-client/src/components/geolocalisation/providers/markerGLCollection.js
@@ -0,0 +1,231 @@
+import $ from 'jquery';
+let mapboxgl = require('mapbox-gl');
+
+const markerGLCollection = (services) => {
+ const {configService, localeService, eventEmitter} = services;
+ let markerCollection = {};
+ let cachedGeoJson;
+ let map;
+ let geojson;
+ let editable;
+ let isDraggable = false;
+ let isCursorOverPoint = false;
+ let isDragging = false;
+ let popup = {};
+ let popupDialog;
+
+ const initialize = (params) => {
+ let initWith = {map, geojson} = params;
+ editable = params.editable || false;
+ setCollection(geojson)
+ };
+
+ const setCollection = (geojson) => {
+ cachedGeoJson = geojson;
+ geojson.features.forEach(function (marker) {
+ setMarkerPopup(marker);
+ });
+ };
+
+ const setMarkerPopup = (marker) => {
+ switch (marker.geometry.type) {
+ case 'Polygon':
+ break;
+ case 'Point':
+ setPoint(marker);
+ break;
+ default:
+ }
+ };
+
+ const setPoint = (marker) => {
+ let $content = $('
');
+
+ let template = `${marker.properties.title}
`;
+
+ if (editable === true) {
+ template += `
+
+ ${localeService.t('mapMarkerEdit')}
+
+
+
${localeService.t('mapMarkerMoveLabel')}
+
+
+ ${localeService.t('mapMarkerEditCancel')}
+ ${localeService.t('mapMarkerEditSubmit')}
+
+
`;
+ }
+
+ $content.append(template);
+
+ $content.find('.edit-mode').hide();
+ //
+ $content.on('click', '.edit-position', (event) => {
+ let $el = $(event.currentTarget);
+ let marker = getMarker($el.data('marker-id'));
+ marker._originalPosition = marker.lngLat.wrap();
+ $content.find('.view-mode').hide();
+ $content.find('.edit-mode').show();
+ $content.find('.help').show();
+ isDraggable = true;
+
+ map.on('mousedown', mouseDown);
+ });
+
+ $content.on('click', '.submit-position', (event) => {
+ let $el = $(event.currentTarget);
+ let marker = getMarker($el.data('marker-id'));
+
+ isDraggable = false;
+ $content.find('.view-mode').show();
+ $content.find('.help').hide();
+ $content.find('.updated-position').html('');
+ $content.find('.edit-mode').hide();
+
+ var popup = document.getElementsByClassName('mapboxgl-popup');
+ if (popup[0]) popup[0].parentElement.removeChild(popup[0]);
+
+ marker.lngLat = {
+ lng: cachedGeoJson.features[0].geometry.coordinates[0],
+ lat: cachedGeoJson.features[0].geometry.coordinates[1]
+ };
+ marker.feature = marker.features[0];
+ eventEmitter.emit('markerChange', {marker, position: marker.lngLat});
+ });
+
+
+ $content.on('click', '.cancel-position', (event) => {
+ let $el = $(event.currentTarget);
+ let marker = getMarker($el.data('marker-id'));
+ isDraggable = false;
+ $content.find('.view-mode').show();
+ $content.find('.updated-position').html('');
+ $content.find('.edit-mode').hide();
+ $content.find('.help').hide();
+
+ var popup = document.getElementsByClassName('mapboxgl-popup');
+ if (popup[0]) popup[0].parentElement.removeChild(popup[0]);
+
+ cachedGeoJson.features[0].geometry.coordinates = [marker._originalPosition.lng, marker._originalPosition.lat];
+ map.getSource('data').setData(cachedGeoJson);
+ });
+
+ // When the cursor enters a feature in the point layer, prepare for dragging.
+ map.on('mouseenter', 'points', function () {
+ if (!isDraggable) {
+ return;
+ }
+ map.getCanvas().style.cursor = 'move';
+ isCursorOverPoint = true;
+ map.dragPan.disable();
+ });
+
+ map.on('mouseleave', 'points', function () {
+ if (!isDraggable) {
+ return;
+ }
+ map.getCanvas().style.cursor = '';
+ isCursorOverPoint = false;
+ map.dragPan.enable();
+ });
+
+ map.on('click', 'points', function (e) {
+ markerCollection[e.features[0].properties.recordIndex] = e;
+ var coordinates = e.features[0].geometry.coordinates.slice();
+
+ while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
+ coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
+ }
+
+ var popup = document.getElementsByClassName('mapboxgl-popup');
+ // Check if there is already a popup on the map and if so, remove it
+ if (popup[0]) popup[0].parentElement.removeChild(popup[0]);
+
+ popupDialog = new mapboxgl.Popup({closeOnClick: false}).setLngLat(coordinates)
+ .setDOMContent($content.get(0))
+ .addTo(map);
+
+ popupDialog.on('close', function (event) {
+ if (editable) {
+ resetMarkerPosition($content);
+ }
+ });
+ });
+
+ function mouseDown() {
+ if (!isCursorOverPoint) return;
+
+ isDragging = true;
+
+ // Set a cursor indicator
+ map.getCanvas().style.cursor = 'grab';
+
+ // Mouse events
+ map.on('mousemove', onMove);
+ map.once('mouseup', onUp);
+
+ var popup = document.getElementsByClassName('mapboxgl-popup');
+ if (popup[0]) popup[0].parentElement.removeChild(popup[0]);
+ }
+
+ function onMove(e) {
+ if (!isDragging) return;
+ var coords = e.lngLat;
+
+ // Set a UI indicator for dragging.
+ map.getCanvas().style.cursor = 'grabbing';
+
+ // Update the Point feature in `geojson` coordinates
+ // and call setData to the source layer `point` on it.
+ cachedGeoJson.features[0].geometry.coordinates = [coords.lng, coords.lat];
+ map.getSource('data').setData(cachedGeoJson);
+ }
+
+ function onUp(e) {
+ if (!isDragging) return;
+ let position = e.lngLat;
+
+ map.getCanvas().style.cursor = '';
+ isDragging = false;
+
+ // Unbind mouse events
+ map.off('mousemove', onMove);
+ $content.find('.updated-position').html(`${position.lat} ${position.lng}`);
+ popupDialog = new mapboxgl.Popup({closeOnClick: false}).setLngLat(position)
+ .setDOMContent($content.get(0))
+ .addTo(map);
+
+ popupDialog.on('close', function (event) {
+ if (editable) {
+ resetMarkerPosition($content);
+ }
+ });
+ }
+
+ }
+
+ const resetMarkerPosition = ($content) => {
+ let marker = getMarker($content.find('.edit-position').data('marker-id'))
+ $content.find('.view-mode').show();
+ $content.find('.updated-position').html('');
+ $content.find('.edit-mode').hide();
+ $content.find('.help').hide();
+ isDraggable = false;
+ if (marker._originalPosition !== undefined) {
+ cachedGeoJson.features[0].geometry.coordinates = [marker._originalPosition.lng, marker._originalPosition.lat];
+ map.getSource('data').setData(cachedGeoJson);
+ }
+ }
+
+ const getMarker = (markerId) => {
+ return markerCollection[markerId];
+ }
+
+ return {
+ initialize, setCollection
+ }
+}
+
+export default markerGLCollection;
diff --git a/Phraseanet-production-client/src/components/lightbox/download.js b/Phraseanet-production-client/src/components/lightbox/download.js
new file mode 100644
index 0000000000..6c88005555
--- /dev/null
+++ b/Phraseanet-production-client/src/components/lightbox/download.js
@@ -0,0 +1,471 @@
+import $ from 'jquery';
+import dialog from './../../phraseanet-common/components/dialog';
+const humane = require('humane-js');
+
+const download = (services) => {
+ const {configService, localeService, appEvents} = services;
+ const url = configService.get('baseUrl');
+ let $container = null;
+
+ const initialize = (options) => {
+ $container = options.$container;
+ $container.on('click', '.basket_downloader', (event) => {
+ event.preventDefault();
+ _downloadBasket();
+ })
+ };
+ const openModal = (datas) => {
+ $('body').addClass('dialog-open');
+ var $dialog = dialog.create(services, {
+ size: 'Medium',
+ title: localeService.t('export'),
+ });
+
+ $('#DIALOG1').on('dialogclose', function(event) {
+ $('body').removeClass('dialog-open');
+ });
+
+ $.ajax({
+ type: 'POST',
+ data: 'lst=' + datas,
+ url: `${url}prod/export/multi-export/`,
+ success: function (data) {
+ $dialog.setContent(data);
+ _onDownloadReady($dialog, window.exportConfig);
+ }
+ });
+
+ return true;
+ }
+
+ const _onDownloadReady = ($dialog, dataConfig) => {
+ $('.tabs', $dialog.getDomElement()).tabs();
+
+ $('.close_button', $dialog.getDomElement()).bind('click', function () {
+ $dialog.close();
+ });
+
+ var tabs = $('.tabs', $dialog.getDomElement());
+
+ if (dataConfig.haveFtp === true) {
+ $('#ftp_form_selector')
+ .bind('change', function () {
+ $('#ftp .ftp_form').hide();
+ $('#ftp .ftp_form_' + $(this).val()).show();
+ $('.ftp_folder_check', dialog.get(1).getDomElement())
+ .unbind('change')
+ .bind('change', function () {
+ if ($(this).prop('checked')) {
+ $(this).next().prop('disabled', false);
+ } else {
+ $(this).next().prop('disabled', true);
+ }
+ });
+ })
+ .trigger('change');
+ }
+
+ $('a.TOUview').bind('click', function (event) {
+ event.preventDefault();
+ let $el = $(event.currentTarget);
+ var options = {
+ size: 'Medium',
+ closeButton: true,
+ title: dataConfig.msg.termOfUseTitle
+ };
+
+ let termOfuseDialog = dialog.create(services, options, 2);
+
+ $.get($el.attr('href'), function (content) {
+ termOfuseDialog.setContent(content);
+ });
+ });
+
+ $('.close_button').bind('click', function () {
+ $dialog.close();
+ });
+
+ $('#download .download_button').bind('click', function () {
+ if (!check_subdefs($('#download'), dataConfig)) {
+ return false;
+ }
+
+ if (!check_TOU($('#download'), dataConfig)) {
+ return false;
+ }
+
+ var total = 0;
+ var count = 0;
+
+ $('input[name="obj[]"]', $('#download')).each(function () {
+ var total_el = $(
+ '#download input[name=download_' + $(this).val() + ']'
+ );
+ var count_el = $(
+ '#download input[name=count_' + $(this).val() + ']'
+ );
+ if ($(this).prop('checked')) {
+ total += parseInt($(total_el).val(), 10);
+ count += parseInt($(count_el).val(), 10);
+ }
+ });
+
+ if (count > 1 && total / 1024 / 1024 > dataConfig.maxDownload) {
+ if (
+ confirm(
+ `${dataConfig.msg.fileTooLarge} \n ${dataConfig.msg
+ .fileTooLargeAlt}`
+ )
+ ) {
+ $(
+ 'input[name="obj[]"]:checked',
+ $('#download')
+ ).each(function (i, n) {
+ $(
+ 'input[name="obj[]"][value="' + $(n).val() + '"]',
+ $('#sendmail')
+ ).prop('checked', true);
+ });
+ $(document).find('input[name="taglistdestmail"]').tagsinput('add', dataConfig.user.email);
+
+ var tabs = $('.tabs', $dialog.getDomElement());
+ tabs.tabs('option', 'active', 1);
+ }
+
+ return false;
+ }
+ $('#download form').submit();
+ $dialog.close();
+ });
+
+ $('#order .order_button').bind('click', function () {
+ let title = '';
+ if (!check_TOU($('#order'), dataConfig)) {
+ return false;
+ }
+
+ $('#order .order_button_loader').css('visibility', 'visible');
+
+ var options = $('#order form').serialize();
+
+ var $this = $(this);
+ $this.prop('disabled', true).addClass('disabled');
+ $.post(
+ `${url}prod/order/`,
+ options,
+ function (data) {
+ $this.prop('disabled', false).removeClass('disabled');
+
+ $('#order .order_button_loader').css(
+ 'visibility',
+ 'hidden'
+ );
+
+ if (!data.error) {
+ title = dataConfig.msg.success;
+ } else {
+ title = dataConfig.msg.warning;
+ }
+
+ var options = {
+ size: 'Alert',
+ closeButton: true,
+ title: title
+ };
+
+ dialog.create(services, options, 2).setContent(data.msg);
+
+ if (!data.error) {
+ showHumane(data.msg);
+
+ $dialog.close();
+ } else {
+ alert(data.msg);
+ }
+
+ return;
+ },
+ 'json'
+ );
+ });
+
+ $('#ftp .ftp_button').bind('click', function () {
+ if (!check_subdefs($('#ftp'), dataConfig)) {
+ return false;
+ }
+
+ if (!check_TOU($('#ftp'), dataConfig)) {
+ return false;
+ }
+
+ $('#ftp .ftp_button_loader').show();
+
+ $('#ftp .ftp_form:hidden').remove();
+
+ var $this = $(this);
+
+ var options_addr = $('#ftp_form_stock form:visible').serialize();
+ var options_join = $('#ftp_joined').serialize();
+
+ $this.prop('disabled', true);
+ $.post(
+ `${url}prod/export/ftp/`,
+ options_addr + '&' + options_join,
+ function (data) {
+ $this.prop('disabled', false);
+ $('#ftp .ftp_button_loader').hide();
+
+ if (data.success) {
+ showHumane(data.message);
+ $dialog.close();
+ } else {
+ var alert = dialog.create(
+ services,
+ {
+ size: 'Alert',
+ closeOnEscape: true,
+ closeButton: true,
+ title: dataConfig.msg.warning
+ },
+ 2
+ );
+
+ alert.setContent(data.message);
+ }
+ return;
+ },
+ 'json'
+ );
+ });
+
+ $('#ftp .tryftp_button').bind('click', function () {
+ $('#ftp .tryftp_button_loader').css('visibility', 'visible');
+ var $this = $(this);
+ $this.prop('disabled', true);
+ var options_addr = $('#ftp_form_stock form:visible').serialize();
+
+ $.post(
+ `${url}prod/export/ftp/test/`,
+ // no need to include 'ftp_joined' checkboxes to test ftp
+ options_addr,
+ function (data) {
+ $('#ftp .tryftp_button_loader').css('visibility', 'hidden');
+
+ var options = {
+ size: 'Alert',
+ closeButton: true,
+ title: data.success
+ ? dataConfig.msg.success
+ : dataConfig.msg.warning
+ };
+
+ dialog
+ .create(services, options, 3)
+ .setContent(data.message);
+
+ $this.prop('disabled', false);
+
+ return;
+ }
+ );
+ });
+
+ function showHumane(data) {
+ $('body').append('Email sending request submitted
');
+ $('body').find('.humane-libnotify-info').html(data);
+ setTimeout(hideHumane, 3000);
+ }
+ function hideHumane() {
+ $('body').find('.humane').remove();
+ }
+ $('#sendmail .sendmail_button').bind('click', function () {
+ if(!validEmail($('input[name="taglistdestmail"]', $('#sendmail')).val(), dataConfig)) {
+ return false;
+ }
+
+ if (!check_subdefs($('#sendmail'), dataConfig)) {
+ return false;
+ }
+
+ if (!check_TOU($('#sendmail'), dataConfig)) {
+ return false;
+ }
+
+ if ($('iframe[name=""]').length === 0) {
+ $('body').append(
+ ''
+ );
+ }
+
+ $('#sendmail form').submit();
+ showHumane($('#export-send-mail-notif').val());
+ $dialog.close();
+
+ });
+
+ $('.datepicker', $dialog.getDomElement()).datepicker({
+ changeYear: true,
+ changeMonth: true,
+ dateFormat: 'yy-mm-dd'
+ });
+
+ $(
+ 'a.undisposable_link',
+ $dialog.getDomElement()
+ ).bind('click', function () {
+ $(this).parent().parent().find('.undisposable').slideToggle();
+ return false;
+ });
+
+ $(
+ 'input[name="obj[]"]',
+ $('#download, #sendmail, #ftp')
+ ).bind('change', function () {
+ var $form = $(this).closest('form');
+
+ if ($('input.caption[name="obj[]"]:checked', $form).length > 0) {
+ $('div.businessfields', $form).show();
+ } else {
+ $('div.businessfields', $form).hide();
+ }
+ });
+ };
+
+ function validateEmail(email) {
+ var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
+ return re.test(email);
+ }
+
+ function validEmail(emailList, dataConfig) {
+ //split emailList by ; , or whitespace and filter empty element
+ let emails = emailList.split(/[ ,;]+/).filter(Boolean);
+ let alert;
+ for(let i=0; i < emails.length; i++) {
+ if (!validateEmail(emails[i])) {
+
+ alert = dialog.create(
+ services,
+ {
+ size: 'Alert',
+ closeOnEscape: true,
+ closeButton: true,
+ title: dataConfig.msg.warning
+ },
+ 2
+ );
+
+ alert.setContent(dataConfig.msg.invalidEmail);
+ return false;
+ }
+ }
+ return true;
+ }
+
+
+ function check_TOU(container, dataConfig) {
+ let checkbox = $('input[name="TOU_accept"]', $(container));
+ let go = checkbox.length === 0 || checkbox.prop('checked');
+ let alert;
+ if (!go) {
+ alert = dialog.create(
+ services,
+ {
+ size: 'Small',
+ closeOnEscape: true,
+ closeButton: true,
+ title: dataConfig.msg.warning
+ },
+ 2
+ );
+
+ alert.setContent(dataConfig.msg.termOfUseAgree);
+
+ return false;
+ }
+ return true;
+ }
+
+ function check_subdefs(container, dataConfig) {
+ let go = false;
+ let required = false;
+ let alert;
+
+ $('input[name="obj[]"]', $(container)).each(function () {
+ if ($(this).prop('checked')) {
+ go = true;
+ }
+ });
+
+ $('input.required, textarea.required', container).each(function (i, n) {
+ if ($.trim($(n).val()) === '') {
+ required = true;
+ $(n).addClass('error');
+ } else {
+ $(n).removeClass('error');
+ }
+ });
+
+ if (required) {
+ alert = dialog.create(
+ services,
+ {
+ size: 'Alert',
+ closeOnEscape: true,
+ closeButton: true,
+ title: dataConfig.msg.warning
+ },
+ 2
+ );
+
+ alert.setContent(dataConfig.msg.requiredFields);
+
+ return false;
+ }
+ if (!go) {
+ alert = dialog.create(
+ services,
+ {
+ size: 'Alert',
+ closeOnEscape: true,
+ closeButton: true,
+ title: dataConfig.msg.warning
+ },
+ 2
+ );
+
+ alert.setContent(dataConfig.msg.missingSubdef);
+
+ return false;
+ }
+
+ return true;
+ }
+
+ function _downloadBasket() {
+ var ids = $.map($('#sc_container .download_form').toArray(), function (el, i) {
+ return $('input[name="basrec"]', $(el)).val();
+ });
+ openModal(ids.join(';'));
+ }
+
+ /*function download(value) {
+ var $dialog = dialog.create({title: localeService.t('export')});
+
+ $.post('/prod/export/multi-export/', 'lst=' + value, function (data) {
+
+ $dialog.setContent(data);
+
+ $('.tabs', $dialog.getDomElement()).tabs();
+
+ $('.close_button', $dialog.getDomElement()).bind('click', function () {
+ $dialog.close();
+ });
+
+ return false;
+ });
+ }*/
+
+ return {initialize, openModal}
+}
+
+export default download;
diff --git a/Phraseanet-production-client/src/components/lightbox/index.js b/Phraseanet-production-client/src/components/lightbox/index.js
new file mode 100644
index 0000000000..bf5392bd95
--- /dev/null
+++ b/Phraseanet-production-client/src/components/lightbox/index.js
@@ -0,0 +1,1160 @@
+import $ from 'jquery';
+require('jquery-ui');
+const humane = require('humane-js');
+import utils from './../../phraseanet-common/components/utils';
+import download from './download';
+import pym from 'pym.js';
+
+
+const lightbox = services => {
+ const { configService, localeService, appEvents } = services;
+ const downloadService = download(services);
+ var _releasable = false;
+ var _bodySize = {
+ x: 0,
+ y: 0
+ };
+ let $mainContainer = null;
+ let activeThumbnailFrame = false;
+
+ const initialize = () => {
+
+ $mainContainer = $('#mainContainer');
+ _bodySize.y = $mainContainer.height();
+ _bodySize.x = $mainContainer.width();
+
+ $(this).data('slideshow', false);
+ $(this).data('slideshow_ctime', false);
+
+ $(window).bind('beforeunload', function () {
+ if (_releasable !== false) {
+ if (confirm(_releasable)) {
+ $('#basket_options .confirm_report').trigger('click');
+ }
+ }
+ });
+
+ _display_basket();
+
+ //load iframe if type is document
+ let $embedFrame = $('.lightbox_container', $('#record_main')).find(
+ '#phraseanet-embed-frame'
+ );
+ let customId = 'phraseanet-embed-lightbox-frame';
+ $embedFrame.attr('id', customId);
+ let src = $embedFrame.attr('data-src');
+ if ($embedFrame.hasClass('documentTips')) {
+ activeThumbnailFrame = new pym.Parent(customId, src);
+ activeThumbnailFrame.iframe.setAttribute('allowfullscreen', '');
+ }
+
+ $(window)
+ .bind('mousedown', function () {
+ $(this).focus();
+ })
+ .trigger('mousedown');
+
+ $('.basket_wrapper')
+ .hover(
+ function () {
+ $(this).addClass('hover');
+ },
+ function () {
+ $(this).removeClass('hover');
+ }
+ )
+ .bind('click', function () {
+ var id = $('input[name=ssel_id]', this).val();
+ document.location = '/lightbox/validate/' + id + '/';
+ return;
+ });
+
+ downloadService.initialize({
+ $container: $mainContainer
+ });
+
+ if ($('.right_column_wrapper_user').length > 0) {
+ $('.right_column_title, #right_column_validation_toggle')
+ .bind('click', function () {
+ if (!$('.right_column_wrapper_caption').is(':visible')) {
+ $('.right_column_wrapper_user')
+ .height($('.right_column_wrapper_user').height())
+ .css('top', 'auto')
+ .animate({
+ height: 0
+ });
+ $('.right_column_wrapper_caption').slideDown();
+ $('#right_column_validation_toggle').show();
+ } else {
+ $('.right_column_wrapper_user').height('auto').animate({
+ top: $('.right_column_title').height()
+ });
+ $('.right_column_wrapper_caption').slideUp();
+ $('#right_column_validation_toggle').hide();
+ }
+ var title = $('.right_column_title');
+ title.hasClass('expanded')
+ ? title.removeClass('expanded')
+ : title.addClass('expanded');
+ })
+ .addClass('clickable');
+ }
+ var sselcont = $('#sc_container .basket_element:first');
+ if (sselcont.length > 0) {
+ _display_basket_element(
+ false,
+ sselcont.attr('id').split('_').pop()
+ );
+ }
+
+ _setSizeable(
+ $(
+ '#record_main .lightbox_container, #record_compare .lightbox_container'
+ )
+ );
+
+ $('#navigation').bind('change', function () {
+ window.location.replace(
+ window.location.protocol +
+ '//' +
+ window.location.host +
+ '/lightbox/validate/' +
+ $(this).val() +
+ '/'
+ );
+ });
+
+ $('#left_scroller').bind('click', function () {
+ _scrollElements(false);
+ });
+
+ $('#right_scroller').bind('click', function () {
+ _scrollElements(true);
+ });
+
+ $(window).bind('resize', function () {
+ _resizeLightbox();
+ });
+ _bind_keyboard();
+
+
+ };
+
+ function _resizeLightbox() {
+ _bodySize.y = $mainContainer.height();
+ _bodySize.x = $mainContainer.width();
+ _displayRecord($('#record_compare').css('visibility') !== 'hidden');
+ }
+
+ function _display_basket() {
+ var sc_wrapper = $('#sc_wrapper');
+ var basket_options = $('#basket_options');
+
+ $('.report')
+ .on('click', function () {
+ _loadReport();
+ return false;
+ })
+ .addClass('clickable');
+
+ $('.confirm_report', basket_options).button().bind('click', function () {
+ _getReseaseStatus($(this));
+ });
+
+ $('#validate-release').click(function () {
+ $("#FeedbackRelease").modal("hide");
+ _setRelease($(this));
+ console.log('validation is done');
+ })
+
+ $('.basket_element', sc_wrapper)
+ .parent()
+ .bind('click', function (event) {
+ _scid_click(event, this);
+ _adjust_visibility(this);
+ return false;
+ });
+
+ $('.agree_button, .disagree_button', sc_wrapper)
+ .bind('click', function (event) {
+ var sselcont_id = $(this)
+ .closest('.basket_element')
+ .attr('id')
+ .split('_')
+ .pop();
+
+ var agreement = $(this).hasClass('agree_button') ? 1 : -1;
+
+ _setAgreement(event, $(this), sselcont_id, agreement);
+ return false;
+ })
+ .addClass('clickable');
+
+ let n = $('.basket_element', sc_wrapper).length;
+ $('#sc_container').width(
+ n * $('.basket_element_wrapper:first', sc_wrapper).outerWidth() + 1
+ );
+
+ $('.previewTips').tooltip();
+ }
+
+ function setReleasable(val) {
+ _releasable = val;
+ }
+
+ function _bind_keyboard() {
+ $(document).bind('keydown', function (event) {
+ var stop = false;
+ $('.notes_wrapper').each(function (i, n) {
+ if (parseInt($(n).css('top'), 10) >= 0) {
+ stop = true;
+ }
+ });
+
+ if (stop) {
+ return true;
+ }
+
+ var cancelKey = false;
+ var el;
+ var id;
+
+ if($('body').hasClass('dialog-open') ==false) {
+ switch (event.keyCode) {
+ case 39:
+ _getNext();
+ cancelKey = true;
+ break;
+ case 37:
+ _getPrev();
+ cancelKey = true;
+ break;
+ case 32:
+ var bool = !$(document).data('slideshow');
+ _slideshow(bool);
+ break;
+ case 38:
+ el = $('#sc_container .basket_element.selected');
+ if (el.length === 1) {
+ id = el.attr('id').split('_').pop();
+ _setAgreement(event, el, id, 1);
+ }
+ break;
+ case 40:
+ el = $('#sc_container .basket_element.selected');
+ if (el.length === 1) {
+ id = el.attr('id').split('_').pop();
+ _setAgreement(event, el, id, -1);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (cancelKey) {
+ event.cancelBubble = true;
+ if (event.stopPropagation) {
+ event.stopPropagation();
+ }
+ return false;
+ }
+ return true;
+ });
+ }
+
+ function _loadReport() {
+ $.ajax({
+ type: 'GET',
+ url: '/lightbox/ajax/LOAD_REPORT/' + $('#navigation').val() + '/',
+ dataType: 'html',
+ success: function (data) {
+ $('#report').empty().append(data);
+ $('#report .reportTips').tooltip({
+ delay: false
+ });
+ $('#report').dialog({
+ width: 600,
+ modal: true,
+ resizable: false,
+ height: Math.round($(window).height() * 0.8)
+ });
+
+ return;
+ }
+ });
+ }
+
+ function _scid_click(event, el) {
+ var compare = utils.is_ctrl_key(event);
+
+ if (compare) {
+ if ($('.basket_element', el).hasClass('selected')) {
+ return;
+ }
+ } else {
+ $('#sc_container .basket_element.selected').removeClass('selected');
+ $('.basket_element', el).addClass('selected');
+ }
+
+ var sselcont_id = $('.basket_element', el).attr('id').split('_').pop();
+ var ssel_id = $('#navigation').val();
+ var url = $(el).attr('href');
+ var container = $('#sc_container');
+
+ var request = container.data('request');
+ if (request && typeof request.abort === 'function') {
+ request.abort();
+ }
+
+ request = _loadBasketElement(url, compare, sselcont_id);
+ container.data('request', request);
+ }
+
+ function _loadBasketElement(url, compare, sselcont_id) {
+ $.ajax({
+ type: 'GET',
+ url: url, //'/lightbox/ajax/LOAD_BASKET_ELEMENT/'+sselcont_id+'/',
+ dataType: 'json',
+ success: function (datas) {
+ var container = false;
+ var data = datas;
+
+ if (compare) {
+ container = $('#record_compare');
+ } else {
+ container = $('#record_main');
+
+ $('#record_infos .lightbox_container')
+ .empty()
+ .append(data.caption);
+
+ $('#basket_infos').empty().append(data.agreement_html);
+ }
+
+ $('.display_id', container).empty().append(data.number);
+
+ $('.title', container)
+ .empty()
+ .append(data.title)
+ .attr('title', data.title);
+
+ var options_container = $('.options', container);
+ options_container.empty().append(data.options_html);
+
+ let customId = 'phraseanet-embed-lightbox-frame';
+ let $template = $(data.preview);
+ $template.attr('id', customId);
+ let src = $template.attr('data-src');
+
+ $('.lightbox_container', container)
+ .empty()
+ .append($template.get(0))
+ .append(data.selector_html)
+ .append(data.note_html);
+
+ if ($('.lightbox_container', container).hasClass('note_editing')) {
+ $('.lightbox_container', container).removeClass('note_editing');
+ }
+
+ if ($template.hasClass('documentTips')) {
+ activeThumbnailFrame = new pym.Parent(customId, src);
+ activeThumbnailFrame.iframe.setAttribute(
+ 'allowfullscreen',
+ ''
+ );
+ }
+
+ // $('.lightbox_container', container).empty()
+ // .append(data.preview + data.selector_html + data.note_html);
+
+ _display_basket_element(compare, sselcont_id);
+ $('.report')
+ .on('click', function () {
+ _loadReport();
+ return false;
+ })
+ .addClass('clickable');
+ return;
+ }
+ });
+ }
+
+ function _display_basket_element(compare, sselcont_id) {
+ var container;
+ if (compare) {
+ container = $('#record_compare');
+ } else {
+ container = $('#record_main');
+ }
+ $('.record_image', container).removeAttr('ondragstart');
+ $('.record_image', container).draggable();
+
+ var options_container = $('.options', container);
+
+ $('.download_button', options_container).bind('click', function () {
+ // $(this).blur();
+ downloadService.openModal(
+ $(this).next('form[name=download_form]').find('input').val()
+ );
+ // _download($(this).next('form[name=download_form]').find('input').val());
+ });
+
+ $('.comment_button').bind('click', function () {
+ // $(this).blur();
+ if ($('.lightbox_container', container).hasClass('note_editing')) {
+ _hideNotes(container);
+ } else {
+ _showNotes(container);
+ }
+ });
+ _activateNotes(container);
+
+ $('.previous_button', options_container).bind('click', function () {
+ // $(this).blur();
+ _getPrev();
+ });
+
+ $('.play_button', options_container).bind('click', function () {
+ // $(this).blur();
+ _slideshow(true);
+ });
+
+ $('.pause_button', options_container).bind('click', function () {
+ // $(this).blur();
+ _slideshow(false);
+ });
+
+ if ($(document).data('slideshow')) {
+ $(
+ '.play_button, .next_button.play, .previous_button.play',
+ options_container
+ ).hide();
+ $(
+ '.pause_button, .next_button.pause, .previous_button.pause',
+ options_container
+ ).show();
+ } else {
+ $(
+ '.play_button, .next_button.play, .previous_button.play',
+ options_container
+ ).show();
+ $(
+ '.pause_button, .next_button.pause, .previous_button.pause',
+ options_container
+ ).hide();
+ }
+
+ $('.next_button', options_container).bind('click', function () {
+ // $(this).blur();
+ _slideshow(false);
+ _getNext();
+ });
+
+ $('.lightbox_container', container).bind('dblclick', function (event) {
+ _displayRecord();
+ });
+
+ $('#record_wrapper .agree_' + sselcont_id + ', .big_box.agree')
+ .bind('click', function (event) {
+ _setAgreement(event, $(this), sselcont_id, 1);
+ })
+ .addClass('clickable');
+
+ $('#record_wrapper .disagree_' + sselcont_id + ', .big_box.disagree')
+ .bind('click', function (event) {
+ _setAgreement(event, $(this), sselcont_id, -1);
+ })
+ .addClass('clickable');
+
+ if (compare === $('#record_wrapper').hasClass('single')) {
+ if (compare) {
+ // $('.agreement_selector').show();
+ // $('#record_wrapper').stop().animate({right:0},100,function(){display_record(compare);});
+ $('#record_wrapper').css({
+ right: 0
+ });
+ _displayRecord(compare);
+ $('#right_column').hide();
+ } else {
+ // $('.agreement_selector').hide();
+ $('#record_wrapper').css({
+ right: 250
+ });
+ _displayRecord(compare);
+ $('#right_column').show();
+ $('#record_compare .lightbox_container').empty();
+ }
+ } else {
+ _displayRecord(compare);
+ }
+ }
+
+ function _getPrev() {
+ var current_wrapper = $('#sc_container .basket_element.selected')
+ .parent()
+ .parent();
+
+ if (current_wrapper.length === 0) {
+ return;
+ }
+
+ _slideshow(false);
+
+ current_wrapper = current_wrapper.prev();
+ if (current_wrapper.length === 0) {
+ current_wrapper = $('#sc_container .basket_element_wrapper:last');
+ }
+
+ $('.basket_element', current_wrapper).parent().trigger('click');
+
+ _adjust_visibility($('.basket_element', current_wrapper).parent());
+ }
+
+ function _getNext() {
+ var current_wrapper = $('#sc_container .basket_element.selected')
+ .parent()
+ .parent();
+
+ if (current_wrapper.length === 0) {
+ return;
+ }
+
+ current_wrapper = current_wrapper.next();
+ if (current_wrapper.length === 0) {
+ current_wrapper = $('#sc_container .basket_element_wrapper:first');
+ }
+
+ $('.basket_element', current_wrapper).parent().trigger('click');
+
+ _adjust_visibility($('.basket_element', current_wrapper).parent());
+
+ if ($(document).data('slideshow')) {
+ var timer = setTimeout(() => _getNext(), 3500);
+ $(document).data('slideshow_ctime', timer);
+ }
+ }
+
+ function _slideshow(boolean_value) {
+ if (boolean_value === $(document).data('slideshow')) {
+ return;
+ }
+
+ if (!boolean_value && $(document).data('slideshow_ctime')) {
+ clearTimeout($(document).data('slideshow_ctime'));
+ $(document).data('slideshow_ctime', false);
+ }
+
+ $(document).data('slideshow', boolean_value);
+
+ var headers = $('#record_wrapper .header');
+
+ if (boolean_value) {
+ $(
+ '.play_button, .next_button.play, .previous_button.play',
+ headers
+ ).hide();
+ $(
+ '.pause_button, .next_button.pause, .previous_button.pause',
+ headers
+ ).show();
+ _getNext();
+ } else {
+ $(
+ '.pause_button, .next_button.pause, .previous_button.pause',
+ headers
+ ).hide();
+ $(
+ '.play_button, .next_button.play, .previous_button.play',
+ headers
+ ).show();
+ }
+ }
+
+ function _adjust_visibility(el) {
+ if (_isViewable(el)) {
+ return;
+ }
+
+ var sc_wrapper = $('#sc_wrapper');
+ var el_parent = $(el).parent();
+
+ var sc_left =
+ el_parent.position().left +
+ el_parent.outerWidth() -
+ sc_wrapper.width() / 2;
+
+ sc_wrapper.stop().animate({
+ scrollLeft: sc_left
+ });
+ }
+
+ function _setAgreement(event, el, sselcont_id, agreeValue) {
+ if (event.stopPropagation) {
+ event.stopPropagation();
+ }
+ event.cancelBubble = true;
+
+ var id = $.ajax({
+ type: 'POST',
+ url: '/lightbox/ajax/SET_ELEMENT_AGREEMENT/' + sselcont_id + '/',
+ dataType: 'json',
+ data: {
+ agreement: agreeValue
+ },
+ success: function (datas) {
+ if (!datas.error) {
+ if (agreeValue === 1) {
+ $('.agree_' + sselcont_id + '').removeClass(
+ 'not_decided'
+ );
+ $('.disagree_' + sselcont_id + '').addClass(
+ 'not_decided'
+ );
+ $('.userchoice.me')
+ .addClass('agree')
+ .removeClass('disagree');
+ } else {
+ $('.agree_' + sselcont_id + '').addClass('not_decided');
+ $('.disagree_' + sselcont_id + '').removeClass(
+ 'not_decided'
+ );
+ $('.userchoice.me')
+ .addClass('disagree')
+ .removeClass('agree');
+ }
+ _releasable = datas.releasable;
+ if (datas.releasable !== false) {
+ if (confirm(datas.releasable)) {
+ $('#basket_options .confirm_report').trigger(
+ 'click'
+ );
+ }
+ }
+ } else {
+ alert(datas.datas);
+ }
+ return;
+ }
+ });
+ }
+
+ function _displayRecord(compare) {
+ var main_container = $('#record_wrapper');
+
+ if (typeof compare === 'undefined') {
+ compare = !main_container.hasClass('single');
+ }
+
+ var main_box = $('#record_main');
+ var compare_box = $('#record_compare');
+
+ var main_record = $('.lightbox_container .record', main_box);
+ var compare_record = $('.lightbox_container .record', compare_box);
+
+ var main_record_width = parseInt(
+ main_record.attr('data-original-width'),
+ 10
+ );
+ var main_record_height = parseInt(
+ main_record.attr('data-original-height'),
+ 10
+ );
+ var compare_record_width = parseInt(
+ compare_record.attr('data-original-width'),
+ 10
+ );
+ var compare_record_height = parseInt(
+ compare_record.attr('data-original-height'),
+ 10
+ );
+
+ var main_container_width = main_container.width();
+ var main_container_innerwidth = main_container.innerWidth();
+ var main_container_height = main_container.height();
+ var main_container_innerheight = main_container.innerHeight();
+ var smooth_image = false;
+ if (compare) {
+ $('.agreement_selector').show();
+ main_container.addClass('comparison');
+
+ var double_portrait_width = main_container_innerwidth / 2;
+ var double_portrait_height =
+ main_container_innerheight -
+ $('.header', main_box).outerHeight();
+
+ var double_paysage_width = main_container_innerwidth;
+ var double_paysage_height =
+ main_container_innerheight / 2 -
+ $('.header', main_box).outerHeight();
+
+ var main_display_portrait = _calculateDisplay(
+ double_portrait_width,
+ double_portrait_height,
+ main_record_width,
+ main_record_height
+ );
+ var main_display_paysage = _calculateDisplay(
+ double_paysage_width,
+ double_paysage_height,
+ main_record_width,
+ main_record_height
+ );
+
+ var compare_display_portrait = _calculateDisplay(
+ double_portrait_width,
+ double_portrait_height,
+ compare_record_width,
+ compare_record_height
+ );
+ var compare_display_paysage = _calculateDisplay(
+ double_paysage_width,
+ double_paysage_height,
+ compare_record_width,
+ compare_record_height
+ );
+
+ var surface_main_portrait =
+ main_display_portrait.width * main_display_portrait.height;
+ var surface_main_paysage =
+ main_display_paysage.width * main_display_paysage.height;
+ var surface_compare_portrait =
+ compare_display_portrait.width *
+ compare_display_portrait.height;
+ var surface_compare_paysage =
+ compare_display_paysage.width * compare_display_paysage.height;
+
+ var double_portrait_surface =
+ (surface_main_portrait + surface_compare_portrait) / 2;
+ var double_paysage_surface =
+ (surface_main_paysage + surface_compare_paysage) / 2;
+
+ var m_width_image;
+ var m_height_image;
+ var c_width_image;
+ var c_height_image;
+ var dim_container;
+
+ if (double_portrait_surface > double_paysage_surface) {
+ if (!main_container.hasClass('portrait')) {
+ smooth_image = true;
+
+ _smoothTransform(main_box, '50%', '100%', function () {
+ _setContainerStatus('portrait');
+ });
+
+ compare_box.css('visibility', 'hidden');
+
+ _smoothTransform(compare_box, '50%', '100%', function () {
+ compare_box
+ .css('display', 'none')
+ .css('visibility', 'visible')
+ .fadeIn();
+ });
+ }
+ m_width_image = main_display_portrait.width;
+ m_height_image = main_display_portrait.height;
+ c_width_image = compare_display_portrait.width;
+ c_height_image = compare_display_portrait.height;
+ dim_container = {
+ width: double_portrait_width,
+ height: double_portrait_height
+ };
+ } else {
+ if (!main_container.hasClass('paysage')) {
+ smooth_image = true;
+
+ _smoothTransform(main_box, '100%', '50%', function () {
+ _setContainerStatus('paysage');
+ });
+
+ compare_box.css('visibility', 'hidden');
+
+ _smoothTransform(compare_box, '100%', '50%', function () {
+ compare_box
+ .css('display', 'none')
+ .css('visibility', 'visible')
+ .fadeIn();
+ });
+ }
+ m_width_image = main_display_paysage.width;
+ m_height_image = main_display_paysage.height;
+ c_width_image = compare_display_paysage.width;
+ c_height_image = compare_display_paysage.height;
+ dim_container = {
+ width: double_paysage_width,
+ height: double_paysage_height
+ };
+ }
+
+ var image_callback = _setImagePosition(
+ false,
+ compare_record,
+ c_width_image,
+ c_height_image,
+ dim_container,
+ function () {}
+ );
+ _setImagePosition(
+ smooth_image,
+ main_record,
+ m_width_image,
+ m_height_image,
+ dim_container,
+ image_callback
+ );
+ } else {
+ $('.agreement_selector').hide();
+ main_container.removeClass('comparison');
+
+ if (compare_box.is(':visible')) {
+ compare_box
+ .hide()
+ .css('visibility', 'hidden')
+ .css('display', 'block');
+ }
+
+ var main_display = _calculateDisplay(
+ main_container_innerwidth,
+ main_container_innerheight -
+ $('.header', main_box).outerHeight(),
+ main_record_width,
+ main_record_height
+ );
+
+ if (!main_container.hasClass('single')) {
+ main_box.width('100%').height('100%');
+
+ _setContainerStatus('single');
+ }
+ _setImagePosition(
+ smooth_image,
+ main_record,
+ main_display.width,
+ main_display.height,
+ {
+ width: main_container_width,
+ height:
+ main_container_height -
+ $('.header', main_box).outerHeight()
+ }
+ );
+ }
+ }
+
+ function _calculateDisplay(
+ display_width,
+ display_height,
+ width,
+ height,
+ margin
+ ) {
+ if (typeof margin === 'undefined') {
+ margin = 10;
+ }
+
+ var display_ratio = display_width / display_height;
+ var ratio = width / height;
+ var w;
+ var h;
+ // landscape
+ if (ratio > display_ratio) {
+ w = display_width - 2 * margin;
+ if (w > width) {
+ w = width;
+ }
+ h = w / ratio;
+ } else {
+ h = display_height - 2 * margin;
+ if (h > height) {
+ h = height;
+ }
+ w = ratio * h;
+ }
+
+ return {
+ width: w,
+ height: h
+ };
+ }
+
+ function _setSizeable(container) {
+ $(container).bind('mousewheel', function (event, delta) {
+ if ($(this).hasClass('note_editing')) {
+ return;
+ }
+
+ var record = $('.record_image', this);
+
+ if (record.length === 0) {
+ return;
+ }
+
+ var o_top = parseInt(record.css('top'), 10);
+ var o_left = parseInt(record.css('left'), 10);
+
+ var o_width;
+ var o_height;
+ var width;
+ var height;
+
+ if (delta > 0) {
+ if (record.width() > 29788 || record.height() >= 29788) {
+ return;
+ }
+ o_width = record.width();
+ o_height = record.height();
+ width = Math.round(o_width * 1.1);
+ height = Math.round(o_height * 1.1);
+ } else {
+ if (record.width() < 30 || record.height() < 30) {
+ return;
+ }
+ o_width = record.width();
+ o_height = record.height();
+ width = Math.round(o_width / 1.05);
+ height = Math.round(o_height / 1.05);
+ }
+
+ var top = Math.round(
+ height / o_height * (o_top - $(this).height() / 2) +
+ $(this).height() / 2
+ );
+ var left = Math.round(
+ width / o_width * (o_left - $(this).width() / 2) +
+ $(this).width() / 2
+ );
+
+ record.width(width).height(height).css({
+ top: top,
+ left: left
+ });
+ });
+ }
+
+ function _setImagePosition(
+ smooth,
+ image,
+ width,
+ height,
+ container,
+ callback
+ ) {
+ var dimensions = {};
+
+ if (typeof container !== 'undefined') {
+ var c_width = container.width;
+ var c_height = container.height;
+
+ dimensions.top = parseInt((c_height - height) / 2, 10);
+ dimensions.left = parseInt((c_width - width) / 2, 10);
+ }
+ if (typeof callback === 'undefined') {
+ callback = function () {};
+ }
+
+ dimensions.width = width;
+ dimensions.height = height;
+
+ if (smooth) {
+ $(image).stop().animate(dimensions, 500, callback);
+ } else {
+ $(image).css(dimensions);
+ callback();
+ }
+ }
+
+ function _scrollElements(boolean_value) {
+ var sc_wrapper = $('#sc_wrapper');
+ var value;
+ if (boolean_value) {
+ value = sc_wrapper.scrollLeft() + 400;
+ } else {
+ value = sc_wrapper.scrollLeft() - 400;
+ }
+
+ sc_wrapper.stop().animate({
+ scrollLeft: value
+ });
+ return;
+ }
+
+ function _smoothTransform(box, width, height, callback) {
+ if (typeof callback === 'undefined') {
+ callback = function () {};
+ }
+
+ $(box).stop().animate(
+ {
+ width: width,
+ height: height
+ },
+ 500,
+ callback
+ );
+ }
+
+ function _setContainerStatus(status) {
+ $('#record_wrapper')
+ .removeClass('paysage portrait single')
+ .addClass(status);
+ }
+
+ function _isViewable(el) {
+ var sc_wrapper = $('#sc_wrapper');
+ var sc_container = $('#sc_container');
+
+ var el_width = $(el).parent().width();
+ var el_position = $(el).parent().offset();
+ var sc_scroll_left = sc_wrapper.scrollLeft();
+
+ var boundRight = sc_wrapper.width();
+ var boundLeft = 0;
+ var placeRight = el_position.left + el_width + sc_scroll_left;
+ var placeLeft = el_position.left - sc_scroll_left;
+
+ if (placeRight <= boundRight && placeLeft >= boundLeft) {
+ return true;
+ }
+ return false;
+ }
+
+ function _saveNote(container, button) {
+ var sselcont_id = $(button).attr('id').split('_').pop();
+ var note = $('.notes_wrapper textarea', container).val();
+
+ $.ajax({
+ type: 'POST',
+ url: '/lightbox/ajax/SET_NOTE/' + sselcont_id + '/',
+ dataType: 'json',
+ data: {
+ note: note
+ },
+ success: function (datas) {
+ _hideNotes(container);
+ $('.notes_wrapper', container).remove();
+ $('.lightbox_container', container).append(datas.datas);
+ _activateNotes(container);
+ return;
+ }
+ });
+ }
+
+ function _activateNotes(container) {
+ $('.note_closer', container)
+ .button({
+ text: true
+ })
+ .bind('click', function () {
+ $(this).blur();
+ _hideNotes(container);
+ return false;
+ });
+
+ $('.note_saver', container)
+ .button({
+ text: true
+ })
+ .bind('click', function () {
+ $(this).blur();
+ _saveNote(container, this);
+ return false;
+ });
+ }
+
+ function _showNotes(container) {
+ $('.notes_wrapper', container).animate({
+ top: 0
+ });
+ $('.lightbox_container', container).addClass('note_editing');
+ }
+
+ function _hideNotes(container) {
+ $('.notes_wrapper', container).animate({
+ top: '-100%'
+ });
+ $('.lightbox_container', container).removeClass('note_editing');
+ }
+
+ /*Get status before send validation*/
+ function _getReseaseStatus(el) {
+ $.ajax({
+ url: '/lightbox/ajax/GET_ELEMENTS/' + $('#navigation').val() + '/',
+ dataType: 'json',
+ error: function (data) {
+ $('.loader', el).css({
+ visibility: 'hidden'
+ });
+ },
+ timeout: function (data) {
+ $('.loader', el).css({
+ visibility: 'hidden'
+ });
+ },
+ success: function (data) {
+ $('.loader', el).css({
+ visibility: 'hidden'
+ });
+ if (data.datas) {
+ if (data.datas) {
+ if (data.datas.counts.nul == 0) {
+ _setRelease($(this));
+ }
+ else {
+ console.log(data.datas.counts);
+ $("#FeedbackRelease .record_accepted").html(data.datas.counts.yes);
+ $("#FeedbackRelease .record_refused").html(data.datas.counts.no);
+ $("#FeedbackRelease .record_null").html(data.datas.counts.nul);
+ $("#FeedbackRelease").modal("show");
+ }
+ } }
+ if (!data.error) {
+ _releasable = false;
+ }
+
+ return;
+ }
+ });
+ }
+
+ function _setRelease(el) {
+ $('.loader', el).css({
+ visibility: 'visible'
+ });
+ $.ajax({
+ type: 'POST',
+ url: '/lightbox/ajax/SET_RELEASE/' + $('#navigation').val() + '/',
+ dataType: 'json',
+ error: function (data) {
+ $('.loader', el).css({
+ visibility: 'hidden'
+ });
+ },
+ timeout: function (data) {
+ $('.loader', el).css({
+ visibility: 'hidden'
+ });
+ },
+ success: function (data) {
+ $('.loader', el).css({
+ visibility: 'hidden'
+ });
+ if (data.datas) {
+ alert(data.datas);
+ }
+ if (!data.error) {
+ _releasable = false;
+ }
+
+ return;
+ }
+ });
+ }
+
+ return {
+ initialize,
+ setReleasable
+ };
+};
+
+export default lightbox;
diff --git a/Phraseanet-production-client/src/components/lightbox/note.js b/Phraseanet-production-client/src/components/lightbox/note.js
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/Phraseanet-production-client/src/components/list/listEditor.js b/Phraseanet-production-client/src/components/list/listEditor.js
new file mode 100644
index 0000000000..1761264879
--- /dev/null
+++ b/Phraseanet-production-client/src/components/list/listEditor.js
@@ -0,0 +1,77 @@
+import $ from 'jquery';
+
+const listEditor = (services, options) => {
+ const { configService, localeService, appEvents } = services;
+ const { $container, listManagerInstance } = options;
+ const $editor = $('#list-editor-search-results');
+ const $form = $('#ListManager .editor').find('form[name="list-editor-search"]');
+
+ $('a.next, a.prev', $editor).bind('click', function (event) {
+ event.preventDefault();
+ const page = $(this).attr('value');
+
+ $('input[name="page"]', $form).val(page);
+ $form.trigger('submit');
+ });
+
+ $('input[name="page"]', $form).val('');
+
+ $('th.sortable', $editor).bind('click', function () {
+
+ let $this = $(this);
+
+ let sort = $('input', $this).val();
+ let ord = 'asc';
+
+ if ((sort === $('input[name="srt"]', $form).val()) && ($('input[name="ord"]', $form).val() === 'asc')) {
+ ord = 'desc';
+ }
+
+ $('input[name="srt"]', $form).val(sort);
+ $('input[name="ord"]', $form).val(ord);
+
+ $form.trigger('submit');
+ })
+ .bind('mouseover', function () {
+ $(this).addClass('hover');
+ })
+ .bind('mouseout', function () {
+ $(this).removeClass('hover');
+ });
+
+ $('tbody tr', $editor).bind('click', function () {
+
+ let $this = $(this);
+ let usr_id = $('input[name="usr_id"]', $this).val();
+
+ let counters = $('#ListManager .counter.current, #ListManager .lists .list.selected .counter');
+
+ if ($this.hasClass('selected')) {
+ $this.removeClass('selected');
+ listManagerInstance.getList().removeUser(usr_id);
+
+ counters.each(function (i, el) {
+ let n = parseInt($(el).text().split(' ')[0], 10);
+ if($(el).hasClass('current'))
+ $(el).text(n - 1 + ' people');
+ else
+ $(el).text(n - 1);
+ });
+ } else {
+ $this.addClass('selected');
+ listManagerInstance.getList().addUser(usr_id);
+
+ counters.each(function (i, el) {
+ let n = parseInt($(el).text(), 10);
+
+ if($(el).hasClass('current'))
+ $(el).text(n + 1 + ' people');
+ else
+ $(el).text(n + 1);
+ });
+ }
+
+ });
+};
+
+export default listEditor;
diff --git a/Phraseanet-production-client/src/components/list/listManager.js b/Phraseanet-production-client/src/components/list/listManager.js
new file mode 100644
index 0000000000..34a9feec18
--- /dev/null
+++ b/Phraseanet-production-client/src/components/list/listManager.js
@@ -0,0 +1,605 @@
+import $ from 'jquery';
+import {Lists, List} from './model/index';
+import listEditor from './listEditor';
+import listShare from './listShare';
+import dialog from './../../phraseanet-common/components/dialog';
+import Selectable from '../utils/selectable';
+import pushAddUser from '../record/recordPush/addUser';
+import * as _ from 'underscore';
+const humane = require('humane-js');
+
+const ListManager = function (services, options) {
+ const { configService, localeService, appEvents } = services;
+ const { containerId } = options;
+ const url = configService.get('baseUrl');
+ let $container;
+ const _this = this;
+
+ this.list = null;
+ this.container = $container = $(containerId);
+ this.userList = new Lists();
+
+ this.removeUserItemsArray = [];
+ this.addUserItemsArray = [];
+ this.removeUserMethod = '';
+ this.addUserMethod = '';
+
+ pushAddUser(services).initialize({$container: this.container});
+
+ $container.on('click', '.back_link', function () {
+ $('#PushBox').show();
+ $('#ListManager').hide();
+ return false;
+ })
+ .on('click', '.push-list-share-action', (event) => {
+ event.preventDefault();
+ let $el = $(event.currentTarget);
+ const listId = $el.data('list-id');
+
+ listShare(services).openModal({
+ listId, modalOptions: {
+ size: '288x500',
+ closeButton: true,
+ title: $el.attr('title')
+ }, modalLevel: 2
+ });
+ return false;
+ })
+ .on('click', 'a.user_adder', function () {
+
+ var $this = $(this);
+
+ $.ajax({
+ type: 'GET',
+ url: $this.attr('href'),
+ dataType: 'html',
+ beforeSend: function () {
+ var options = {
+ size: 'Medium',
+ title: $this.html()
+ };
+ dialog.create(services, options, 2).getDomElement().addClass('loading');
+ },
+ success: function (data) {
+ dialog.get(2).getDomElement().removeClass('loading').empty().append(data);
+ return;
+ },
+ error: function () {
+ dialog.get(2).close();
+ return;
+ },
+ timeout: function () {
+ dialog.get(2).close();
+ return;
+ }
+ });
+
+ return false;
+ })
+ .on('mouseenter', '.list-trash-btn', function (event) {
+ var $el = $(event.currentTarget);
+ $el.find('.image-normal').hide();
+ $el.find('.image-hover').show();
+ })
+ .on('mouseleave', '.list-trash-btn', function (event) {
+ var $el = $(event.currentTarget);
+ $el.find('.image-normal').show();
+ $el.find('.image-hover').hide();
+ })
+ .on('click', '.list-trash-btn', function (event) {
+ var $el = $(event.currentTarget);
+ var list_id = $el.parent().data('list-id');
+ appEvents.emit('push.removeList', {
+ list_id: list_id,
+ container: containerId
+ }
+ );
+
+ });
+
+ var initLeft = () => {
+ $container.on('click', '.push-refresh-list-action', (event) => {
+ event.preventDefault();
+ //$('a.list_refresh', $container).bind('click', (event) => {
+ // /prod/lists/all/
+
+ var selectedList = $('.lists_manager_list.selected').data('list-id');
+
+ var callback = function (datas, selected) {
+ $('.all-lists', $container).removeClass('loading').append(datas);
+
+ if (typeof selected === 'number') {
+ $('.all-lists').find('.lists_manager_list[data-list-id="' + selected + '"]').addClass('selected');
+ }
+ // initLeft();
+ };
+
+ $('.all-lists', $container).empty().addClass('loading');
+
+ this.userList.get(callback, 'html', selectedList);
+
+ });
+
+ $container.on('click', '.push-add-list-action', (event) => {
+ event.preventDefault();
+ var makeDialog = (box) => {
+
+ var buttons = {};
+
+ buttons[localeService.t('valider')] = () => {
+
+ var callbackOK = function () {
+ $('a.list_refresh', $container).trigger('click');
+ dialog.get(2).close();
+ };
+
+ var name = $('input[name="name"]', dialog.get(2).getDomElement()).val();
+
+ if ($.trim(name) === '') {
+ alert($('#push-list-name-empty').val());
+ return;
+ }
+
+ this.userList.create(name, callbackOK);
+ };
+// /prod/lists/list/
+ var options = {
+ cancelButton: true,
+ buttons: buttons,
+ title: $('#push-new-list-title').val(),
+ size: '450x170'
+ };
+
+ const $dialog = dialog.create(services, options, 2);
+ $dialog.getDomElement().closest('.ui-dialog').addClass('dialog_container dialog_add_list')
+ .find('.ui-dialog-buttonset button:first-child .ui-button-text').text($('#btn-add').val());
+ $dialog.setContent(box);
+ };
+
+ var html = _.template($('#list_editor_dialog_add_tpl').html());
+ makeDialog(html);
+
+ return false;
+ });
+
+ /*$('li.list a.list_link', $container).bind('click', function (event) {
+
+ var $this = $(this);
+
+ $this.closest('.lists').find('.list.selected').removeClass('selected');
+ $this.parent('li.list').addClass('selected');
+ return false;
+ });*/
+ $container.on('click', '.list-edit-action', (event) => {
+ event.preventDefault();
+ _this.removeUserItemsArray = [];
+ _this.addUserItemsArray = [];
+ _this.removeUserMethod = '';
+ _this.addUserMethod = '';
+
+ let $el = $(event.currentTarget);
+ const listId = $el.data('list-id');
+ const el_url = $el.attr('href');
+
+ const callbackList = function (list) {
+ for (let i in list.entries) {
+ this.selectUser(list.entries[i].User);
+ }
+ };
+
+ $el.closest('.lists').find('.list').removeClass('selected');
+ $el.parent().addClass('selected');
+
+ $.ajax({
+ type: 'GET',
+ url: `${url}prod/push/edit-list/${listId}/`,
+ dataType: 'html',
+ success: (data) => {
+ this.workOn(listId);
+ $('.editor', $container).removeClass('loading').append(data);
+ this.loadList(el_url, callbackList);
+ initRight();
+ listEditor(services, {
+ $container, listManagerInstance: _this
+ });
+ },
+ beforeSend: function () {
+ $('.editor', $container).empty().addClass('loading');
+ }
+ });
+ });
+ $container.on('click', '.listmanager-delete-list-user-action', (event) => {
+ event.preventDefault();
+ let $el = $(event.currentTarget);
+ const listId = $el.data('list-id');
+ const userId = $el.data('user-id');
+
+
+ var badge = $(this).closest('.badge');
+ // var usr_id = badge.find('input[name="id"]').val();
+ this.getList().removeUser(userId, function (list, data) {
+ badge.remove();
+ });
+ });
+ };
+
+ var initRight = function () {
+ var $container = $('#ListManager .editor');
+ var selection = new Selectable(services, $('.user_content .badges', _this.container), {
+ selector: '.badge'
+ });
+
+ $('form[name="list-editor-search"]', $container).bind('submit', function (event) {
+ event.preventDefault();
+ var $this = $(this);
+ var dest = $('.list-editor-results', $container);
+
+ $.ajax({
+ url: $this.attr('action'),
+ type: $this.attr('method'),
+ dataType: 'html',
+ data: $this.serializeArray(),
+ beforeSend: function () {
+ dest.empty().addClass('loading');
+ },
+ success: function (datas) {
+ dest.empty().removeClass('loading').append(datas);
+ listEditor(services, {
+ $container, listManagerInstance: _this
+ });
+ }
+ });
+ });
+
+ $('form[name="list-editor-search"] select, form[name="list-editor-search"] input[name="ListUser"]', $container).bind('change', function () {
+ $(this).closest('form').trigger('submit');
+ });
+
+ $('.EditToggle', $container).bind('click', function (event) {
+ event.preventDefault();
+ $('.content.readselect, .content.readwrite, .editor_header', $('#ListManager')).toggle();
+ });
+ $('.Refresher', $container).bind('click', function (event) {
+ event.preventDefault();
+ $('#ListManager ul.lists .list.selected a').trigger('click');
+ });
+
+ $('form[name="SaveName"]', $container).bind('submit', function () {
+ var $this = $(this);
+
+ $.ajax({
+ type: $this.attr('method'),
+ url: $this.attr('action'),
+ dataType: 'json',
+ data: $this.serializeArray(),
+ beforeSend: function () {
+
+ },
+ success: function (data) {
+ if (data.success) {
+ humane.info(data.message);
+ $('#ListManager .lists .list_refresh').trigger('click');
+ } else {
+ humane.error(data.message);
+ }
+ return;
+ },
+ error: function () {
+
+ return;
+ },
+ timeout: function () {
+
+ return;
+ }
+ });
+
+ return false;
+ });
+
+ // //button.deleter
+ // $('.listmanager-delete-list-action', $container).bind('click', function (event) {
+
+ // var list_id = $(this).data('list-id');
+
+ // var makeDialog = function (box) {
+
+ // var buttons = {};
+
+ // buttons[localeService.t('valider')] = function () {
+
+ // var callbackOK = function () {
+ // $('#ListManager .all-lists a.list_refresh').trigger('click');
+ // dialog.get(2).close();
+ // };
+
+ // var List = new List(list_id);
+ // List.remove(callbackOK);
+ // };
+
+ // var options = {
+ // cancelButton: true,
+ // buttons: buttons,
+ // size: 'Alert'
+ // };
+
+ // dialog.create(services, options, 2).setContent(box);
+ // };
+
+ // var html = _.template($('#list_editor_dialog_delete_tpl').html());
+
+ // makeDialog(html);
+
+ // return false;
+ // });
+
+ $('input[name="users-search"]', $container).autocomplete({
+ minLength: 2,
+ source: function (request, response) {
+ $.ajax({
+ url: `${url}prod/push/search-user/`,
+ dataType: 'json',
+ data: {
+ query: request.term
+ },
+ success: function (data) {
+ response(data);
+ }
+ });
+ },
+ focus: function (event, ui) {
+ // $('input[name="users-search"]').val(ui.item.label);
+ },
+ select: function (event, ui) {
+ if (ui.item.type === 'USER') {
+ _this.selectUser(ui.item);
+ _this.updateUsersHandler('add', ui.item.usr_id);
+ } else if (ui.item.type === 'LIST') {
+ for (let e in ui.item.entries) {
+ _this.selectUser(ui.item.entries[e].User);
+ _this.updateUsersHandler('add', ui.item.entries[e].User.usr_id);
+ }
+ }
+ $('#saveListFooter').show();
+
+ return false;
+ }
+ })
+ .data('ui-autocomplete')._renderItem = function (ul, item) {
+ var html = '';
+
+ if (item.type === 'USER') {
+ html = _.template($('#list_user_tpl').html())({
+
+ item: item
+ });
+ } else if (item.type === 'LIST') {
+ html = _.template($('#list_list_tpl').html())({
+ item: item
+ });
+ }
+
+ return $(html).data('ui-autocomplete-item', item).appendTo(ul);
+ };
+
+ $('.user_content .badges', _this.container).disableSelection();
+
+ $container.on('click', '.content .options .select-all', function () {
+ selection.selectAll();
+ });
+
+ $container.on('click', '.content .options .unselect-all', function () {
+ selection.empty();
+ });
+
+ $container.on('click', '.content .options .delete-selection', function () {
+ var $elems = $('#ListManager .badges.selectionnable .badge.selected');
+ _.each($elems, function(item) {
+ var $elem = $(item);
+ var $elemID = $elem.find('input[name=id]').val();
+ if($elem.hasClass('selected')
+ && _this.removeUserItemsArray.indexOf($elemID) === -1) {
+ _this.updateUsersHandler('remove', $elemID);
+ }
+ });
+
+ $elems.fadeOut(300, 'swing', function() {
+ $(this).remove();
+ $('#saveListFooter').show();
+ });
+ });
+ $container.on('submit', 'form.list_saver', function (event) {
+ event.preventDefault();
+ var $form = $(event.currentTarget);
+ var name = $('.header h2', $container).text();
+ var users = _this.getUsers();
+
+ if (users.length === 0) {
+ humane.error('No users');
+ return false;
+ }
+ else {
+ if (_this.removeUserMethod === 'remove' && _this.removeUserItemsArray.length > 0) {
+ var $editor = $('#list-editor-search-results');
+
+ _.each(_this.removeUserItemsArray, function (item) {
+
+ $('tbody tr', $editor).each(function(i, el) {
+ var $el = $(el);
+ var $elID = $('input[name="usr_id"]', $el).val();
+ if(item == $elID)
+ $el.removeClass('selected');
+ });
+
+ _this.getList().removeUser(item);
+ });
+
+ var ListCounter = $('#ListManager .counter.current, #ListManager .lists .list.selected .counter');
+
+ ListCounter.each(function (i, el) {
+ var n = parseInt($(el).text(), 10);
+ if($(el).hasClass('current'))
+ $(el).text(n - _this.removeUserItemsArray.length + ' people');
+ else
+ $(el).text(n - _this.removeUserItemsArray.length);
+ });
+
+ $('#saveListFooter').hide();
+ _this.removeUserItemsArray = [];
+ _this.removeUserMethod = '';
+ }
+ else if (_this.addUserMethod === 'add' && _this.addUserItemsArray.length > 0) {
+ var $editor = $('#list-editor-search-results');
+
+ _.each(_this.addUserItemsArray, function (item) {
+
+ $('tbody tr', $editor).each(function(i, el) {
+
+ var $el = $(el);
+ var $elID = $('input[name="usr_id"]', $el).val();
+
+ if(item == $elID)
+ $el.addClass('selected');
+ });
+
+ _this.getList().addUser(item);
+ });
+
+ var ListCounter = $('#ListManager .counter.current, #ListManager .lists .list.selected .counter');
+
+ ListCounter.each(function (i, el) {
+ var n = parseInt($(el).text(), 10);
+
+ if($(el).hasClass('current'))
+ $(el).text(n + _this.addUserItemsArray.length + ' people');
+ else
+ $(el).text(n + _this.addUserItemsArray.length);
+ });
+
+ $('#saveListFooter').hide();
+ _this.addUserItemsArray = [];
+ _this.addUserMethod = '';
+ }
+ }
+
+ });
+
+ $container.on('click', '.badges a.deleter', function (event) {
+ var badge = $(event.currentTarget).closest('.badge');
+ var usr_id = badge.find('input[name="id"]').val();
+ var ListCounter = $('#ListManager .counter.current, #ListManager .lists .list.selected .counter');
+ var $editor = $('#list-editor-search-results');
+
+ var callback = function callback(list, datas) {
+ ListCounter.each(function (i, el) {
+ var n = parseInt($(el).text(), 10);
+
+ if($(el).hasClass('current'))
+ $(el).text(n - 1 + ' people');
+ else
+ $(el).text(n - 1);
+ });
+ badge.fadeOut('300', 'swing', function() {
+ badge.remove();
+ });
+ };
+
+ _this.getList().removeUser(usr_id, callback);
+
+ $('tbody tr', $editor).each(function(i, el) {
+ var $el = $(el);
+ var $elID = $('input[name="usr_id"]', $el).val();
+
+ if(usr_id === $elID)
+ $el.removeClass('selected');
+ });
+
+ return false;
+ });
+ };
+
+ initLeft();
+
+ return this;
+
+};
+
+ListManager.prototype = {
+ selectUser: function (user) {
+ if (typeof user !== 'object') {
+ if (window.console) {
+ console.log('trying to select a user with wrong datas');
+ }
+ }
+ if ($('.badge_' + user.usr_id, this.container).length > 0) {
+ humane.info('User already selected');
+ return;
+ }
+ else {
+ var html = _.template($('#list_manager_badge_tpl').html())({
+ user: user
+ });
+
+ // p4.Feedback.appendBadge(html);
+ // this.getList().addUser(user.usr_id);
+ this.appendBadge(html);
+ }
+ },
+ workOn: function (list_id) {
+ this.list = new List(list_id);
+ },
+ getList: function () {
+ return this.list;
+ },
+ appendBadge: function (datas) {
+ $('#ListManager .badges').append(datas);
+ },
+ createList: function (options) {
+ let { name, collection } = options;
+
+ this.userList.create(name, function (list) {
+ list.addUsers(collection);
+ });
+ },
+ removeList: function (list_id, callback) {
+ this.list = new List(list_id);
+ this.list.remove(callback);
+ },
+ loadList: function (url, callback) {
+ var $this = this;
+ $.ajax({
+ type: 'GET',
+ url: url,
+ dataType: 'json',
+ success: function (data) {
+ if (typeof callback === 'function') {
+ callback.call($this, data);
+ }
+ }
+ });
+ },
+ updateUsers: function (action) {
+ if(action === 'remove') {
+
+ }
+ return removedItems;
+ },
+ getUsers: function () {
+ return $('.user_content .badge', this.container).map(function () {
+ return $('input[name="id"]', $(this)).val();
+ });
+ },
+ updateUsersHandler: function (method, item) {
+ if (method === 'remove') {
+ this.removeUserItemsArray.push(item);
+ this.removeUserMethod = method;
+ }
+ else if (method === 'add') {
+ this.addUserItemsArray.push(item);
+ this.addUserMethod = method;
+ }
+ }
+};
+
+
+export default ListManager;
diff --git a/Phraseanet-production-client/src/components/list/listShare.js b/Phraseanet-production-client/src/components/list/listShare.js
new file mode 100644
index 0000000000..6617a74f7d
--- /dev/null
+++ b/Phraseanet-production-client/src/components/list/listShare.js
@@ -0,0 +1,149 @@
+import $ from 'jquery';
+import dialog from './../../phraseanet-common/components/dialog';
+import * as _ from 'underscore';
+const humane = require('humane-js');
+
+const listShare = (services, options) => {
+ const { configService, localeService, appEvents } = services;
+ const url = configService.get('baseUrl');
+ let $dialog = null;
+
+
+ const initialize = () => {
+ };
+
+
+ const openModal = (options) => {
+ let { listId, modalOptions, modalLevel } = options;
+
+ $dialog = dialog.create(services, modalOptions, modalLevel);
+ $dialog.getDomElement().closest('.ui-dialog').addClass('dialog_container dialog_share_list');
+
+ return $.get(`${url}prod/lists/list/${listId}/share/`, function (data) {
+ $dialog.setContent(data);
+ onModalReady(listId);
+ });
+ };
+
+ const onModalReady = (listId) => {
+ let $container = $('#ListShare');
+ let $completer_form = $('form[name="list_share_user"]', $container);
+ let $owners_form = $('form[name="owners"]', $container);
+ let $autocompleter = $('input[name="user"]', $completer_form);
+ let $dialog = dialog.get(2);
+
+ $completer_form.bind('submit', function () {
+ return false;
+ });
+
+ $('select[name="role"]', $owners_form).bind('change', function (event) {
+ event.preventDefault();
+ let $el = $(event.currentTarget);
+ const userId = $el.data('user-id');
+
+ shareWith(userId, $el.val());
+
+ return false;
+ });
+ $container.on('click', '.listmanager-share-delete-user-action', (event) => {
+ event.preventDefault();
+ let $el = $(event.currentTarget);
+ const userId = $el.data('user-id');
+
+ let $owner = $el.closest('.owner');
+
+ unShareWith(userId, function (data) {
+ $owner.remove();
+ });
+
+ return false;
+ });
+
+
+ function shareWith(userId, role) {
+ role = typeof role === 'undefined' ? 1 : role;
+
+ $.ajax({
+ type: 'POST',
+ url: `${url}prod/lists/list/${listId}/share/${userId}/`,
+ dataType: 'json',
+ data: {role: role},
+ beforeSend: function () {
+ },
+ success: function (data) {
+ if (data.success) {
+ humane.info(data.message);
+ } else {
+ humane.error(data.message);
+ }
+
+ $('.push-list-share-action').trigger('click');
+ $dialog.refresh();
+
+ return;
+ }
+ });
+ }
+
+ function unShareWith(userId, callback) {
+ $.ajax({
+ type: 'POST',
+ url: `${url}prod/lists/list/${listId}/unshare/${userId}/`,
+ dataType: 'json',
+ data: {},
+ beforeSend: function () {
+ },
+ success: function (data) {
+ if (data.success) {
+ humane.info(data.message);
+ callback(data);
+ } else {
+ humane.error(data.message);
+ }
+ $dialog.refresh();
+
+ return;
+ }
+ });
+ }
+
+ $autocompleter.autocomplete({
+ minLength: 2,
+ source: function (request, response) {
+ $.ajax({
+ url: `${url}prod/push/search-user/`,
+ dataType: 'json',
+ data: {
+ query: request.term
+ },
+ success: function (data) {
+ response(data);
+ }
+ });
+ },
+ select: function (event, ui) {
+ if (ui.item.type === 'USER') {
+ shareWith(ui.item.usr_id);
+ }
+
+ return false;
+ }
+ })
+ .data('ui-autocomplete')._renderItem = function (ul, item) {
+ if (item.type === 'USER') {
+ var html = _.template($('#list_user_tpl').html())({
+ item: item
+ });
+
+ return $(html).data('ui-autocomplete-item', item).appendTo(ul);
+ }
+ };
+ };
+
+
+ return {
+ openModal
+ };
+};
+
+export default listShare;
diff --git a/Phraseanet-production-client/src/components/list/model/index.js b/Phraseanet-production-client/src/components/list/model/index.js
new file mode 100644
index 0000000000..5fa3f1aca0
--- /dev/null
+++ b/Phraseanet-production-client/src/components/list/model/index.js
@@ -0,0 +1,199 @@
+import $ from 'jquery';
+const humane = require('humane-js');
+
+var Lists = function () {
+
+};
+
+var List = function (id) {
+
+ if (parseInt(id, 10) <= 0) {
+ throw 'Invalid list id';
+ }
+
+ this.id = id;
+};
+
+Lists.prototype = {
+ create: function (name, callback) {
+
+ $.ajax({
+ type: 'POST',
+ // @TODO - load baseUrl from configService
+ url: '/prod/lists/list/',
+ dataType: 'json',
+ data: {name: name},
+ success: function (data) {
+ if (data.success) {
+ humane.info(data.message);
+
+ if (typeof callback === 'function') {
+ var list = new List(data.list_id);
+ callback(list);
+ }
+ } else {
+ humane.error(data.message);
+ }
+ }
+ });
+
+ },
+ get: function (callback, type, selectedList) {
+
+ type = typeof type === 'undefined' ? 'json' : type;
+
+ $.ajax({
+ type: 'GET',
+ // @TODO - load baseUrl from configService
+ url: '/prod/lists/all/',
+ dataType: type,
+ data: {},
+ success: function (data) {
+ if (type === 'json') {
+ if (data.success) {
+ humane.info(data.message);
+
+ if (typeof callback === 'function') {
+ callback(data.result);
+ }
+ } else {
+ humane.error(data.message);
+ }
+ } else {
+ if (typeof callback === 'function') {
+ callback(data, selectedList);
+ }
+ }
+ }
+ });
+ }
+
+};
+
+List.prototype = {
+ addUsers: function (arrayUsers, callback) {
+
+ if (!arrayUsers instanceof Array) {
+ throw 'addUsers takes array as argument';
+ }
+
+ var $this = this;
+ var data = {usr_ids: $(arrayUsers).toArray()};
+
+ $.ajax({
+ type: 'POST',
+ // @TODO - load baseUrl from configService
+ url: '/prod/lists/list/' + $this.id + '/add/',
+ dataType: 'json',
+ data: data,
+ success: function (data) {
+ if (data.success) {
+ humane.info(data.message);
+
+ if (typeof callback === 'function') {
+ callback($this, data);
+ }
+ } else {
+ humane.error(data.message);
+ }
+ }
+ });
+ },
+ addUser: function (usr_id, callback) {
+ this.addUsers([usr_id], callback);
+ },
+ remove: function (callback) {
+
+ var $this = this;
+
+ $.ajax({
+ type: 'POST',
+ // @TODO - load baseUrl from configService
+ url: '/prod/lists/list/' + this.id + '/delete/',
+ dataType: 'json',
+ data: {},
+ success: function (data) {
+ if (data.success) {
+ humane.info(data.message);
+
+ if (typeof callback === 'function') {
+ callback($this);
+ }
+ } else {
+ humane.error(data.message);
+ }
+ }
+ });
+ },
+ update: function (name, callback) {
+
+ var $this = this;
+
+ $.ajax({
+ type: 'POST',
+ // @TODO - load baseUrl from configService
+ url: '/prod/lists/list/' + this.id + '/update/',
+ dataType: 'json',
+ data: {name: name},
+ success: function (data) {
+ if (data.success) {
+ humane.info(data.message);
+
+ if (typeof callback === 'function') {
+ callback($this);
+ }
+ } else {
+ humane.error(data.message);
+ }
+ }
+ });
+ },
+ removeUser: function (usr_id, callback) {
+
+ var $this = this;
+
+ $.ajax({
+ type: 'POST',
+ // @TODO - load baseUrl from configService
+ url: '/prod/lists/list/' + this.id + '/remove/' + usr_id + '/',
+ dataType: 'json',
+ data: {},
+ success: function (data) {
+ if (data.success) {
+ humane.info(data.message);
+
+ if (typeof callback === 'function') {
+ callback($this, data);
+ }
+ } else {
+ humane.error(data.message);
+ }
+ }
+ });
+ },
+ get: function (callback) {
+
+ var $this = this;
+
+ $.ajax({
+ type: 'GET',
+ // @TODO - load baseUrl from configService
+ url: '/prod/lists/list/' + this.id + '/',
+ dataType: 'json',
+ data: {},
+ success: function (data) {
+ if (data.success) {
+ humane.info(data.message);
+
+ if (typeof callback === 'function') {
+ callback($this, data);
+ }
+ } else {
+ humane.error(data.message);
+ }
+ }
+ });
+ }
+};
+
+export {Lists, List};
diff --git a/Phraseanet-production-client/src/components/locale/index.js b/Phraseanet-production-client/src/components/locale/index.js
new file mode 100644
index 0000000000..cc4707160e
--- /dev/null
+++ b/Phraseanet-production-client/src/components/locale/index.js
@@ -0,0 +1,73 @@
+import i18next from 'i18next';
+import Backend from 'i18next-xhr-backend';
+import $ from 'jquery';
+import * as Rx from 'rx';
+
+let instance = null;
+class LocaleService {
+ constructor(options) {
+ if (!options) {
+ options = {};
+ }
+
+ // can be instanciated only once
+ if (!instance) {
+ instance = this;
+ }
+
+ if (options.locale === undefined) {
+ options.locale = 'fr';
+ }
+ this.locale = options.locale;
+ this.isCached = false;
+ this.cachedTranslations = {};
+ this.configService = options.configService;
+ this.path = this.configService.get('translations');
+ return instance;
+ }
+
+ t(key) {
+ if (this.isCached && this.translate !== undefined) {
+ return this.translate(key);
+ } else {
+ throw new Error('locale not loaded');
+ }
+ }
+
+ getLocale() {
+ return this.locale;
+ }
+
+ getTranslations() {
+ return this.cachedTranslations;
+ }
+
+ fetchTranslations(data) {
+ data = data || {};
+ let i18nPromise = $.Deferred();
+ i18next
+ .use(Backend)
+ .init({
+ lng: this.locale,
+ backend: {
+ loadPath: this.path,
+
+ }
+ }, (err, t) => {
+ this.isCached = true;
+ this.translate = t;
+ this.cachedTranslations = i18next.getResourceBundle(this.locale);
+ i18nPromise.resolve(instance);
+ if (data.callback !== undefined) {
+ data.callback();
+ }
+ //resolve(this.i18n);
+ });
+ // });
+ this.i18n = i18nPromise.promise();
+ this.stream = Rx.Observable.fromPromise(this.i18n);
+ return this.i18n;
+ }
+}
+
+export default LocaleService;
diff --git a/Phraseanet-production-client/src/components/mainMenu/index.js b/Phraseanet-production-client/src/components/mainMenu/index.js
new file mode 100644
index 0000000000..4318e19fa8
--- /dev/null
+++ b/Phraseanet-production-client/src/components/mainMenu/index.js
@@ -0,0 +1,49 @@
+import $ from 'jquery';
+require('./../../phraseanet-common/components/vendors/contextMenu');
+
+const mainMenu = (services) => {
+ const { configService, localeService, appEvents } = services;
+ const $container = $('body');
+
+ const initialize = () => {
+ _bindEvents();
+ return true;
+ };
+
+ const _bindEvents = () => {
+ /**
+ * mainMenu > Publication link
+ */
+ $container.on('click', '.state-navigation', function (event) {
+ event.preventDefault();
+ let $el = $(event.currentTarget);
+
+ // @TODO loop through each state args:
+
+ _stateNavigator($el.data('state'));
+ });
+ /**
+ * mainMenu > help context menu
+ */
+
+ /* $('body').on('click', '#help-trigger', function (event) {
+ $('#mainMenu .helpcontextmenu').toggleClass('shown');
+ });*/
+ };
+
+ const _stateNavigator = (...state) => {
+ let [stateName, stateArgs] = state;
+
+ switch (stateName) {
+ case 'publication':
+ appEvents.emit(`${stateName}.activeState`); // fetch
+ break;
+ default:
+ console.log('navigation state error: state "' + stateName + '" not found');
+ }
+
+ };
+ return { initialize };
+};
+
+export default mainMenu;
diff --git a/Phraseanet-production-client/src/components/notify/index.js b/Phraseanet-production-client/src/components/notify/index.js
new file mode 100644
index 0000000000..96065daffc
--- /dev/null
+++ b/Phraseanet-production-client/src/components/notify/index.js
@@ -0,0 +1,98 @@
+import $ from 'jquery';
+// import user from '../user/index.js';
+import notifyLayout from './notifyLayout';
+import notifyService from './notifyService';
+import * as Rx from 'rx';
+import merge from 'lodash.merge';
+const notify = (services) => {
+
+ const { configService, localeService, appEvents } = services;
+ const defaultPollingTime = 10000;
+ const defaultConfig = {
+ url: null,
+ moduleId: null,
+ userId: null,
+ _isValid: false
+ };
+
+ const initialize = () => {
+ notifyLayout(services).initialize();
+ };
+
+ const createNotifier = (state) => {
+ if (state === undefined) {
+ return defaultConfig;
+ }
+ if (state.url === undefined) {
+ return defaultConfig;
+ }
+
+ return merge({}, defaultConfig, {
+ url: state.url,
+ moduleId: state.moduleId,
+ userId: state.userId,
+ _isValid: true
+ });
+ };
+
+ //const appendNotifications = (content) => notifyUiComponent().addNotifications(content);
+
+ const isValid = (notificationInstance) => notificationInstance._isValid || false;
+
+ const poll = (notificationInstance) => {
+
+ let notificationSource = Rx.Observable
+ .fromPromise(notifyService({
+ configService: configService
+ }).getNotification({
+ module: notificationInstance.moduleId,
+ usr: notificationInstance.userId
+ }));
+
+ notificationSource.subscribe(
+ x => onPollSuccess(x, notificationInstance),
+ e => onPollError(e, notificationInstance),
+ () => {}
+ );
+ };
+ const onPollSuccess = (data, notificationInstance) => {
+ // broadcast session refresh event
+ appEvents.emit('session.refresh', data);
+ // broadcast notification refresh event
+ if (data.changed.length > 0) {
+ appEvents.emit('notification.refresh', data);
+ }
+ // append notification content
+ notifyLayout(services).addNotifications(data.notifications);
+
+ let t = 120000;
+ if (data.apps && parseInt(data.apps, 10) > 1) {
+ t = Math.round((Math.sqrt(parseInt(data.apps, 10) - 1) * 1.3 * 60000));
+ }
+
+ window.setTimeout(poll, t, notificationInstance);
+
+ return true;
+ };
+
+ const onPollError = (data, notificationInstance) => {
+ if (data.status === 'disconnected' || data.status === 'session') {
+ appEvents.emit('user.disconnected', data);
+ return false;
+ }
+ window.setTimeout(poll, defaultPollingTime, notificationInstance);
+ };
+
+
+ return {
+ initialize,
+ /*appendNotifications: (content) => {
+ notifyLayout().addNotifications(content)
+ },*/
+ createNotifier,
+ isValid,
+ poll
+ };
+};
+
+export default notify;
diff --git a/Phraseanet-production-client/src/components/notify/notifyLayout.js b/Phraseanet-production-client/src/components/notify/notifyLayout.js
new file mode 100644
index 0000000000..3014258a97
--- /dev/null
+++ b/Phraseanet-production-client/src/components/notify/notifyLayout.js
@@ -0,0 +1,245 @@
+import $ from 'jquery';
+import dialog from './../../phraseanet-common/components/dialog';
+// import user from '../user/index.js';
+
+
+const notifyLayout = (services) => {
+ const { configService, localeService, appEvents } = services;
+ const $notificationBoxContainer = $('#notification_box');
+ const $notificationTrigger = $('.notification_trigger');
+ let $notificationDialog = $('#notifications-dialog');
+ const initialize = () => {
+ $notificationTrigger.on('mousedown', (event) => {
+ event.stopPropagation();
+ const $target = $(event.currentTarget);
+ if ($target.hasClass('open')) {
+ $notificationBoxContainer.hide();
+ $target.removeClass('open');
+ clear_notifications();
+ } else {
+ $notificationBoxContainer.show();
+
+ setBoxHeight();
+
+ $target.addClass('open');
+ read_notifications();
+ }
+ });
+
+ $(document).on('mousedown', () => {
+ if ($notificationTrigger.hasClass('open')) {
+ $notificationTrigger.trigger('click');
+ }
+
+ if ($notificationTrigger.hasClass('open')) {
+ $notificationBoxContainer.hide();
+ $notificationTrigger.removeClass('open');
+ clear_notifications();
+ }
+ });
+
+ $notificationBoxContainer
+ .on('mousedown', (event) => {
+ event.stopPropagation();
+ })
+ .on('mouseover', '.notification', (event) => {
+ $(event.currentTarget).addClass('hover');
+ })
+ .on('mouseout', '.notification', (event) => {
+ $(event.currentTarget).removeClass('hover');
+ })
+ .on('click', '.notification__print-action', (event) => {
+ event.preventDefault();
+ const $el = $(event.currentTarget);
+ const page = $el.data('page');
+ print_notifications(page);
+ });
+
+ $(window).bind('resize', function () {
+ setBoxPosition();
+ });
+ setBoxPosition();
+
+ };
+
+ const addNotifications = (notificationContent) => {
+ // var box = $('#notification_box');
+ $notificationBoxContainer.empty().append(notificationContent);
+
+ if ($notificationBoxContainer.is(':visible')) {
+ setBoxHeight();
+ }
+
+ if ($('.notification.unread', $notificationBoxContainer).length > 0) {
+ $('.counter', $notificationTrigger)
+ .empty()
+ .append($('.notification.unread', $notificationBoxContainer).length);
+ $('.counter', $notificationTrigger).css('visibility', 'visible');
+
+ } else {
+ $('.notification_trigger .counter').css('visibility', 'hidden').empty();
+ }
+ };
+
+
+ const setBoxHeight = () => {
+ //var box = $('#notification_box');
+ var not = $('.notification', $notificationBoxContainer);
+ var n = not.length;
+ var not_t = $('.notification_title', $notificationBoxContainer);
+ var n_t = not_t.length;
+
+ var h = not.outerHeight() * n + not_t.outerHeight() * n_t;
+ h = h > 350 ? 350 : h;
+
+ $notificationBoxContainer.stop().animate({height: h});
+ };
+
+ const setBoxPosition = () => {
+ if ($notificationTrigger.length > 0) {
+ var leftOffset = Math.round($notificationTrigger.offset().left);
+ if(leftOffset == 0) {
+ $notificationBoxContainer.css({
+ left: 20
+ });
+ }else {
+ $notificationBoxContainer.css({
+ left: Math.round($notificationTrigger.offset().left - 1)
+ });
+ }
+ }
+ };
+
+ const print_notifications = (page) => {
+
+ page = parseInt(page, 10);
+ var buttons = {};
+
+ buttons[localeService.t('fermer')] = function () {
+ $notificationDialog.dialog('close');
+ };
+
+ if ($notificationDialog.length === 0) {
+ $('body').append('
');
+ $notificationDialog = $('#notifications-dialog');
+ }
+
+ $notificationDialog
+ .dialog({
+ title: $('#notification-title').val(),
+ autoOpen: false,
+ closeOnEscape: true,
+ resizable: false,
+ draggable: false,
+ modal: true,
+ width: 500,
+ height: 400,
+ overlay: {
+ backgroundColor: '#000',
+ opacity: 0.7
+ },
+ close: function (event, ui) {
+ $notificationDialog.dialog('destroy').remove();
+ }
+ }).dialog('option', 'buttons', buttons).dialog('open').on('click','.notification_next .notification__print-action', function (event) {
+ event.preventDefault();
+ var $el = $(event.currentTarget);
+ var page = $el.data('page');
+ print_notifications(page);
+ });
+
+
+ $.ajax({
+ type: 'GET',
+ url: '/user/notifications/',
+ dataType: 'json',
+ data: {
+ page: page
+ },
+ error: function (data) {
+ $notificationDialog.removeClass('loading');
+ },
+ timeout: function (data) {
+ $notificationDialog.removeClass('loading');
+ },
+ success: function (data) {
+ $notificationDialog.removeClass('loading');
+
+
+ if (page === 0) {
+ $notificationDialog.empty();
+ } else {
+ $('.notification_next', $notificationDialog).remove();
+ }
+
+ let i = 0;
+ for (i in data.notifications) {
+ var id = 'notif_date_' + i;
+ var date_cont = $('#' + id);
+ if (date_cont.length === 0) {
+ $notificationDialog.append('' + data.notifications[i].display + '
');
+ date_cont = $('#' + id);
+ }
+
+ let j = 0;
+ for (j in data.notifications[i].notifications) {
+ var loc_dat = data.notifications[i].notifications[j];
+ var html = '' +
+ '
' +
+ loc_dat.icon +
+ ' ' +
+ '' +
+ loc_dat.text + ' ' + loc_dat.time + '
' +
+ '
' +
+ '
';
+ date_cont.append(html);
+ }
+ }
+
+ var next_ln = $.trim(data.next);
+
+ if (next_ln !== '') {
+ $notificationDialog.append('' + next_ln + '
');
+ }
+ }
+ });
+
+ };
+
+ const read_notifications = () => {
+ var notifications = [];
+
+ $('#notification_box .unread').each(function () {
+ notifications.push($(this).attr('id').split('_').pop());
+ });
+
+ $.ajax({
+ type: 'POST',
+ url: '/user/notifications/read/',
+ data: {
+ notifications: notifications.join('_')
+ },
+ success: function (data) {
+ $('.notification_trigger .counter').css('visibility', 'hidden').empty();
+ }
+ });
+ };
+
+ const clear_notifications = () => {
+ var unread = $('#notification_box .unread');
+
+ if (unread.length === 0) {
+ return;
+ }
+
+ unread.removeClass('unread');
+ $('.notification_trigger .counter').css('visibility', 'hidden').empty();
+ };
+
+ return {
+ initialize,
+ addNotifications
+ };
+};
+
+export default notifyLayout;
diff --git a/Phraseanet-production-client/src/components/notify/notifyService.js b/Phraseanet-production-client/src/components/notify/notifyService.js
new file mode 100644
index 0000000000..f807ddfce7
--- /dev/null
+++ b/Phraseanet-production-client/src/components/notify/notifyService.js
@@ -0,0 +1,46 @@
+import {Observable} from 'rx';
+// import {ajax} from 'jquery';
+import $ from 'jquery';
+let notifyService = (services) => {
+ const {configService} = services;
+ const url = configService.get('baseUrl');
+ const notificationEndPoint = 'session/notifications/';
+ let initialize = () => {
+ };
+
+ let getNotification = (data) => {
+ /*return ajax({
+ type: 'POST',
+ url: `${notificationEndPoint}`,
+ data: data,
+ dataType: 'json'
+ }).promise();*/
+ let notificationPromise = $.Deferred();
+
+ $.ajax({
+ type: 'POST',
+ url: `${url}${notificationEndPoint}`,
+ data: data,
+ dataType: 'json'
+ }).done((data) => {
+ data.status = data.status || false;
+ if (data.status === 'ok') {
+ notificationPromise.resolve(data);
+ } else {
+ notificationPromise.reject(data);
+ }
+ })
+ .fail((data) => {
+ notificationPromise.reject(data);
+ });
+ return notificationPromise.promise();
+ };
+
+ let stream = Observable.fromPromise(getNotification);
+ return {
+ initialize,
+ getNotification,
+ stream
+ };
+};
+export default notifyService;
diff --git a/Phraseanet-production-client/src/components/order/index.js b/Phraseanet-production-client/src/components/order/index.js
new file mode 100644
index 0000000000..86b312e8c1
--- /dev/null
+++ b/Phraseanet-production-client/src/components/order/index.js
@@ -0,0 +1,257 @@
+import $ from 'jquery';
+import orderItem from './orderItem';
+import dialog from './../../phraseanet-common/components/dialog';
+
+const order = services => {
+ const { configService, localeService, appEvents } = services;
+ const url = configService.get('baseUrl');
+
+ const initialize = (options = {}) => {
+ const { $container } = options;
+ $container.on('click', '.order-open-action', function (event) {
+ event.preventDefault();
+ orderModal(event);
+ });
+ $container.on('click', '.order-notif', function (event) {
+ event.preventDefault();
+ $('#notification_box').hide();
+ orderModal(event, this);
+ });
+
+ };
+
+ const orderModal = (event, id) => {
+ var $dialog = dialog.create(services, {
+ size: 'Full',
+ title: $(event).attr('title')
+ });
+
+ $.ajax({
+ type: 'GET',
+ url: `${url}prod/order/`,
+ success: function (data) {
+ $dialog.setContent(data);
+ _onOrderReady($dialog);
+ if ($(id).length) {
+ $('#order_manager').css('opacity',0).hide(function () {
+ console.log($(id).data("id"));
+ $('#order_' + $(id).data("id")).trigger('click');
+ });
+ }
+ }
+ });
+
+ return true;
+ };
+
+ const _onOrderReady = $dialog => {
+ let filterDateSelected = false;
+ let perPage = window.orderData.perPage;
+ let date = window.orderData.date;
+ let dateSelection = window.orderData.dateSelection;
+ let dateSelectionText = window.orderData.dateSelectionText;
+ let info = window.orderData.info;
+ let tabSelection = window.orderData.tabSelection;
+
+ const FilterTodo = {
+ TODO: 'pending',
+ PROCESSED: 'processed'
+ };
+ const FilterDate = {
+ NO_FILTER: 'no_filter',
+ CURRENT_WEEK: 'current_week',
+ PAST_WEEK: 'past_week',
+ PAST_MONTH: 'past_month',
+ BEFORE: 'before',
+ AFTER: 'after'
+ };
+
+ /******** functions *********/
+ const setDateInPicker = date => {
+ if (date !== '') {
+ $('#datepicker').val(date);
+ }
+ };
+
+ const setDateSelection = element => {
+ var selection = $(element).attr('name');
+ dateSelection = FilterDate[selection];
+ setSelectionText(dateSelection);
+ clearAll();
+ $(element).addClass('active');
+ };
+
+ const setSelectionText = dateSelection => {
+ if (dateSelection === undefined) {
+ return;
+ }
+ $('.reset-btn').hide();
+ if (dateSelection !== FilterDate.NO_FILTER) {
+ if (
+ dateSelection === FilterDate.BEFORE ||
+ dateSelection === FilterDate.AFTER
+ ) {
+ dateSelectionText =
+ $(
+ `#filter_box tbody tr td button[name=${dateSelection.toUpperCase()}]`
+ ).html() +
+ ' ' +
+ $('#datepicker').val();
+ var obj = {};
+ obj.date = $('#datepicker').val();
+ obj.type = dateSelection;
+ info.limit = obj;
+ } else {
+ dateSelectionText = $(
+ `#filter_box tbody tr td button[name=${dateSelection.toUpperCase()}]`
+ ).html();
+ info.limit = null;
+ }
+ $('#filter-text').text(dateSelectionText);
+ $('.reset-btn').show();
+ } else {
+ $('#filter-text').text(window.orderData.noFilterText);
+ info.limit = null;
+ }
+ info.todo = tabSelection;
+ info.start = dateSelection;
+ };
+
+ const clearAll = () => {
+ $('#filter_box tbody tr td').children('button').each(function () {
+ $(this).removeClass('active');
+ });
+ };
+
+ const performRequest = () => {
+ $.ajax({
+ type: 'GET',
+ url: '../prod/order/',
+ data: info,
+ success: function (data) {
+ $dialog.setContent(data);
+ _onOrderReady($dialog);
+ }
+ });
+ };
+
+ const toggleFilterDate = () => {
+ if (!filterDateSelected) {
+ filterDateSelected = true;
+ $('#filter-date').addClass('active');
+ $('#filter_box').css('display', 'block');
+ } else {
+ filterDateSelected = false;
+ $('#filter-date').removeClass('active');
+ $('#filter_box').css('display', 'none');
+ }
+ };
+
+ $('#datepicker').datepicker({
+ beforeShow: () => {
+ setTimeout(() => {
+ $('.ui-datepicker').css('z-index', 999999);
+ }, 0);
+ },
+ changeYear: true,
+ changeMonth: true,
+ dateFormat: 'yy/mm/dd',
+ onSelect: value => {
+ date = value;
+ setSelectionText(dateSelection);
+ }
+ });
+
+ $('.reset-btn', $dialog.getDomElement()).bind('click', function (e) {
+ info.start = FilterDate.NO_FILTER;
+ setSelectionText(FilterDate.NO_FILTER);
+ $('#date-form').trigger('submit');
+ });
+
+ $('#ORDERPREVIEW').tabs({
+ activate: function (event, ui) {
+ if (ui.newPanel.selector === '#PROCESSED-ORDER') {
+ $('.pager-processed').show();
+ $('.pager-todo').hide();
+ tabSelection = FilterTodo.PROCESSED;
+ } else {
+ $('.pager-processed').hide();
+ $('.pager-todo').show();
+ tabSelection = FilterTodo.TODO;
+ }
+ }
+ });
+
+ $('#ORDERPREVIEW').tabs(
+ 'option',
+ 'active',
+ tabSelection === FilterTodo.PROCESSED ? 1 : 0
+ );
+ $('.pager-processed').hide();
+
+ $('a.self-ajax', $dialog.getDomElement()).bind('click', function (e) {
+ e.preventDefault();
+ var url = $(this).attr('href');
+ dialog.load(url);
+ });
+
+ $(
+ '#date-form .toggle-button-text',
+ $dialog.getDomElement()
+ ).bind('click', function (e) {
+ setDateSelection(this);
+ //trigger request immediately for this week, past week, past month
+ if (
+ $(this).attr('name') !== 'BEFORE' &&
+ $(this).attr('name') !== 'AFTER'
+ ) {
+ $('#date-form').trigger('submit');
+ }
+ });
+
+ $('.pager li', $dialog.getDomElement()).bind('click', function (e) {
+ info.todo = tabSelection;
+ info.start = dateSelection;
+ info['per-page'] = perPage;
+ info.page = $(this).find('a').attr('data-page');
+
+ performRequest();
+ });
+
+ $('tr.order_row', $dialog.getDomElement())
+ .bind('click', function (event) {
+ event.preventDefault();
+ let orderId = $(this).attr('id').split('_').pop();
+
+ orderItem(services).openModal(orderId);
+ })
+ .addClass('clickable');
+
+ $('#filter-date a').click(function () {
+ toggleFilterDate();
+ });
+
+ $('#date-form').submit(function (e) {
+ e.preventDefault();
+ performRequest();
+ toggleFilterDate();
+ });
+
+ setDateInPicker(date);
+ setSelectionText(dateSelection);
+
+ if (dateSelection !== FilterDate.NO_FILTER) {
+ let element = $(
+ `#filter_box tbody tr td button[name='${dateSelection.toUpperCase()}]`
+ );
+ setDateSelection(element);
+ }
+ };
+
+ return {
+ initialize,
+ orderModal
+ };
+};
+
+export default order;
diff --git a/Phraseanet-production-client/src/components/order/orderItem.js b/Phraseanet-production-client/src/components/order/orderItem.js
new file mode 100644
index 0000000000..978e71a496
--- /dev/null
+++ b/Phraseanet-production-client/src/components/order/orderItem.js
@@ -0,0 +1,938 @@
+import $ from 'jquery';
+import dialog from './../../phraseanet-common/components/dialog';
+import * as appCommons from './../../phraseanet-common';
+import order from './index';
+import _ from 'underscore';
+import pym from 'pym.js';
+
+const orderItem = services => {
+ const { configService, localeService, appEvents } = services;
+ const url = configService.get('baseUrl');
+ const openModal = orderId => {
+ let $dialog = dialog.create(services, {
+ size: 'Full'
+ });
+
+ $.ajax({
+ type: 'GET',
+ url: `${url}prod/order/${orderId}`,
+ success: function (data) {
+ $dialog.setContent(data);
+ _onOrderItemReady($dialog);
+ }
+ });
+
+ return true;
+ };
+
+ const _onOrderItemReady = $dialog => {
+ let userInfoIsVisible = false;
+ let itemCount = 0;
+ let elementsForValidation = [];
+ let readyForValidation = false;
+ let lastItemChosen = null;
+
+ const ELEMENT_TYPE = {
+ VALIDATED: 'validated',
+ DENIED: 'denied',
+ SELECTABLE: 'selectable',
+ SELECTED: 'selected',
+ WAITINGFORVALIDATION: 'waitingForValidation'
+ };
+
+ let trs = $('.order_list .order_row', $dialog.getDomElement());
+ let lastSelectedRow;
+ if ($('#notification_box').is(':visible')) {
+ $('.notification_trigger').trigger('mousedown');
+ }
+
+ $('.order_launcher', $dialog.getDomElement()).on('click', function (event) {
+ if (readyForValidation) {
+ if (confirm(window.orderItemData.translatedText.message)) {
+ order(services).orderModal(event);
+ }
+ } else {
+ order(services).orderModal(event);
+ }
+ });
+
+ $('#email-btn', $dialog.getDomElement()).on('click', function () {
+ let email = window.orderItemData.userEmail;
+ let subject = window.orderItemData.subject;
+ let body = window.orderItemData.body;
+ if (email !== null) {
+ let link =
+ 'mailto:' +
+ email +
+ '?subject=' +
+ encodeURIComponent(subject) +
+ '&body=' +
+ encodeURIComponent(body);
+ window.location.href = link;
+ }
+ });
+
+ $(
+ 'input[name="select-all"]',
+ $dialog.getDomElement()
+ ).bind('click', function () {
+ let checkboxElement = this;
+ itemCount = 0;
+ let selectable = [];
+ $('.table-order .order_row').each(function () {
+ let el = $(this);
+ if (
+ checkboxElement.checked &&
+ el.hasClass(ELEMENT_TYPE.SELECTABLE)
+ ) {
+ el.addClass(ELEMENT_TYPE.SELECTED);
+ itemCount++;
+ selectable.push(el);
+ } else {
+ el.removeClass(ELEMENT_TYPE.SELECTED);
+ }
+ });
+ //load preview for single item selected
+ if (selectable.length === 1) {
+ loadPreviewAndCaption(selectable[0]);
+ }
+ renderOrderDetailView(itemCount);
+ });
+
+ $(
+ '.order_list .order_row',
+ $dialog.getDomElement()
+ ).bind('click', function (event) {
+ let $this = $(this);
+ lastItemChosen = $this;
+
+ //disable select all checkbox if selected
+ if ($('input[name="select-all"]').is(':checked')) {
+ $('input[name="select-all"]').prop('checked', false);
+ }
+
+ if (appCommons.utilsModule.is_ctrl_key(event)) {
+ if (!$this.hasClass(ELEMENT_TYPE.SELECTABLE)) {
+ return;
+ }
+ if ($this.hasClass(ELEMENT_TYPE.SELECTED)) {
+ $this.removeClass(ELEMENT_TYPE.SELECTED);
+ itemCount--;
+ } else {
+ $this.addClass(ELEMENT_TYPE.SELECTED);
+ itemCount++;
+ }
+ } else if (appCommons.utilsModule.is_shift_key(event)) {
+ if (!$this.hasClass(ELEMENT_TYPE.SELECTABLE)) {
+ return;
+ }
+ let currentIndex = $this.index('.order_list .order_row');
+ let prevIndex = lastSelectedRow.index('.order_list .order_row');
+ $(
+ '.order_list .selectable.selected',
+ $dialog.getDomElement()
+ ).removeClass(ELEMENT_TYPE.SELECTED);
+ itemCount = 0;
+ selectRowsBetweenIndexes([prevIndex, currentIndex]);
+ } else {
+ $(
+ '.order_list .selectable.selected',
+ $dialog.getDomElement()
+ ).removeClass(ELEMENT_TYPE.SELECTED);
+ if ($this.hasClass(ELEMENT_TYPE.SELECTABLE)) {
+ $this.addClass(ELEMENT_TYPE.SELECTED);
+ lastSelectedRow = $this;
+ }
+ itemCount = 1;
+ }
+
+ if (itemCount === 1) {
+ let selected = $(
+ '.order_list .selected',
+ $dialog.getDomElement()
+ );
+ loadPreviewAndCaption(selected);
+ }
+ renderOrderDetailView(itemCount);
+ });
+
+ function selectRowsBetweenIndexes(indexes) {
+ indexes.sort(function (a, b) {
+ return a - b;
+ });
+ for (let i = indexes[0]; i <= indexes[1]; i++) {
+ if ($(trs[i]).hasClass(ELEMENT_TYPE.SELECTABLE)) {
+ $(trs[i]).addClass(ELEMENT_TYPE.SELECTED);
+ itemCount++;
+ }
+ }
+ }
+
+ $(
+ '.captionTips, .captionRolloverTips, .infoTips',
+ $dialog.getDomElement()
+ ).tooltip({
+ delay: 0
+ });
+ $('.previewTips', $dialog.getDomElement()).tooltip({
+ fixable: true
+ });
+
+ $('button.send', $dialog.getDomElement()).bind('click', function () {
+ updateValidation(ELEMENT_TYPE.VALIDATED);
+ //send_documents(order_id);
+ });
+
+ $('button.deny', $dialog.getDomElement()).bind('click', function () {
+ updateValidation(ELEMENT_TYPE.DENIED);
+ //deny_documents(order_id);
+ });
+
+ $('button.reset', $dialog.getDomElement()).bind('click',function(){
+ var itemsToBeReset = [];
+ $('.order_list .order_row.selected.waitingForValidation', $dialog.getDomElement()).each(function(i,n){
+ itemsToBeReset.push($(n));
+ });
+ //if item is not selected, delete item being previewed
+ if(itemsToBeReset.length == 0 && lastItemChosen) {
+ itemsToBeReset.push(lastItemChosen);
+ }
+ resetItemForValidation(itemsToBeReset);
+ toggleValidationButton();
+
+ //$('.order_row.selected').removeClass('to_be_denied');
+ //$('.order_row.selected').removeClass('to_be_validated');
+ });
+
+ $('.force_sender', $dialog.getDomElement()).bind('click', function () {
+ if (confirm(localeService.t('forceSendDocument'))) {
+ //updateValidation('validated');
+ let element_id = [];
+ element_id.push(
+ $(this)
+ .closest('.order_row')
+ .find('input[name=order_element_id]')
+ .val()
+ );
+ let order_id = $('input[name=order_id]').val();
+ do_send_documents(order_id, element_id, true);
+ }
+ });
+
+ $('#userInfo').hover(
+ function () {
+ let offset = $('#userInfo').position();
+ $('#userInfoPreview').css({
+ left: offset.left - $('#userInfoPreview').width() + 48,
+ top: offset.top + $('#userInfo').height() + 8
+ });
+ $('#userInfoPreview').show();
+ },
+ function () {
+ if (!userInfoIsVisible) {
+ $('#userInfoPreview').hide();
+ }
+ }
+ );
+
+ $('#userInfo').click(function () {
+ let offset = $('#userInfo').position();
+ if (!userInfoIsVisible) {
+ userInfoIsVisible = true;
+ $('#userInfoPreview').css({
+ left: offset.left - $('#userInfoPreview').width() + 48,
+ top: offset.top + $('#userInfo').height() + 8
+ });
+ $('#userInfoPreview').show();
+ } else {
+ userInfoIsVisible = false;
+ $('#userInfoPreview').hide();
+ }
+ });
+
+ let minimized_elements = $('.minimize');
+
+ $('.minimize').each(function () {
+ let t = $(this).text();
+ if (t.length < 60) return;
+
+ $(this).html(
+ t.slice(0, 60) +
+ '... ' +
+ window.orderItemData.translatedText.moreText +
+ ' ' +
+ '' +
+ t.slice(60, t.length) +
+ ' ' +
+ window.orderItemData.translatedText.lessText +
+ ' '
+ );
+ });
+
+ $('a.more', minimized_elements).click(function (event) {
+ event.preventDefault();
+ $(this).hide().prev().hide();
+ $(this).next().show();
+ });
+
+ $('a.less', minimized_elements).click(function (event) {
+ event.preventDefault();
+ $(this).parent().hide().prev().show().prev().show();
+ });
+
+ $('button.validate', $dialog.getDomElement()).bind('click', function (
+ event
+ ) {
+ openValidationDialog(this, event);
+ return false;
+ });
+
+ $('.basket-btn').click(function (event) {
+ let titleCreate = window.orderItemData.translatedText.createTitle;
+ let type = $(this).attr('type');
+ var dialog_buttons = {};
+ dialog_buttons[titleCreate] = function () {
+ createBasket($innerDialog);
+ $(this).dialog('close');
+ };
+ let $innerDialog = $('#basket-window')
+ .dialog({
+ open: function (event, ui) {
+ $('.ui-dialog').css('z-index', 100000);
+ $('.ui-widget-overlay').css('z-index', 100000);
+ },
+ closeOnEscape: true,
+ width: 450,
+ height: 300,
+ modal: true,
+ draggable: false,
+ stack: false,
+ title: window.orderItemData.translatedText.dialogTitle,
+ overlay: {
+ backgroundColor: '#000',
+ opacity: 0.7
+ },
+ buttons: dialog_buttons
+ })
+ .dialog('open');
+ populateBasketDialog($innerDialog, type);
+ return false;
+ });
+
+ $('#myDropdown').on('click', function () {
+ if ($('#myDropdown').hasClass('open')) {
+ return;
+ }
+ if (
+ $('.order_list .selected', $dialog.getDomElement()).length > 0
+ ) {
+ $('li[type="selected"]').removeClass('disabled');
+ } else {
+ //no selected item
+ if (!$('li[type="selected"]').hasClass('disabled')) {
+ $('li[type="selected"]').addClass('disabled');
+ }
+ }
+ });
+
+ function createBasket($innerDialog) {
+ let $form = $('form', $innerDialog);
+ let dialog = $innerDialog.closest('.ui-dialog');
+ let buttonPanel = dialog.find('.ui-dialog-buttonpane');
+
+ $.ajax({
+ type: $form.attr('method'),
+ url: $form.attr('action'),
+ data: $form.serializeArray(),
+ dataType: 'json',
+ beforeSend: function () {
+ $(
+ ":button:contains('" + localeService.t('create') + "')",
+ buttonPanel
+ )
+ .attr('disabled', true)
+ .addClass('ui-state-disabled');
+ },
+ success: function (data) {
+ let order_id = $('input[name=order_id]').val();
+ let success = '0';
+ if (data.success) {
+ success = '1';
+ }
+
+ var url =
+ '../prod/order/' +
+ order_id +
+ '/?success=' +
+ success +
+ '&action=basket' +
+ '&message=' +
+ encodeURIComponent(data.message);
+ reloadDialog(url);
+ appEvents.emit('workzone.refresh');
+ }
+ });
+ }
+
+ function populateBasketDialog($innerDialog, type) {
+ let lst = [];
+ let orderDialog = $innerDialog;
+ //set checkbox to true and disable it
+ $('input[name="lst"]', orderDialog).prop('checked', true);
+ $('.checkbox', orderDialog).css('visibility', 'hidden');
+ //set default name
+ let name = window.orderItemData.translatedText.defaultBasketTitle;
+ $('input[name="name"]', orderDialog).val(name);
+ let description = window.orderItemData.description;
+ let elements_ids = [];
+ switch (type) {
+ case 'denied':
+ $(
+ '.order_list .order_row.' + type,
+ $dialog.getDomElement()
+ ).each(function (i, n) {
+ elements_ids.push($(n).attr('elementids'));
+ });
+ break;
+ case 'validated':
+ $(
+ '.order_list .order_row.' + type,
+ $dialog.getDomElement()
+ ).each(function (i, n) {
+ elements_ids.push($(n).attr('elementids'));
+ });
+ break;
+ default:
+ //selected elements;
+ $(
+ '.order_list .order_row.' + type,
+ $dialog.getDomElement()
+ ).each(function (i, n) {
+ elements_ids.push($(n).attr('elementids'));
+ });
+ }
+ $('textarea[name="description"]', orderDialog).val(description);
+ $('input[name="lst"]', orderDialog).val(elements_ids.join('; '));
+ }
+
+ function openValidationDialog(el, event) {
+ let submitTitle = window.orderItemData.translatedText.submit;
+ let resetTitle = window.orderItemData.translatedText.reset;
+ var dialog_buttons = {};
+ dialog_buttons[submitTitle] = function () {
+ //submit documents
+ submitDocuments($(this));
+ };
+ dialog_buttons[resetTitle] = function () {
+ if (confirm(window.orderItemData.translatedText.message)) {
+ resetAllItemForValidation();
+ toggleValidationButton();
+ $(this).dialog('close');
+ }
+ };
+ $('#validation-window')
+ .dialog({
+ open: function (event, ui) {
+ $('.ui-dialog').css('z-index', 100000);
+ $('.ui-widget-overlay').css('z-index', 100000);
+ },
+ closeOnEscape: true,
+ resizable: false,
+ width: 450,
+ height: 500,
+ modal: true,
+ draggable: false,
+ stack: false,
+ title: window.orderItemData.translatedText.validation,
+ buttons: dialog_buttons,
+ overlay: {
+ backgroundColor: '#000',
+ opacity: 0.7
+ }
+ })
+ .dialog('open');
+ createValidationTable();
+ }
+
+ function submitDocuments(dialogElem) {
+ let order_id = $('input[name=order_id]').val();
+ let validatedArrayNoForceIds = _.filter(
+ elementsForValidation,
+ function (elem) {
+ return (
+ elem.newState === ELEMENT_TYPE.VALIDATED &&
+ elem.oldState !== ELEMENT_TYPE.DENIED
+ );
+ }
+ ).map(function (elem) {
+ return elem.elementId;
+ });
+
+ let validatedArrayWithForceIds = _.filter(
+ elementsForValidation,
+ function (elem) {
+ return (
+ elem.newState === ELEMENT_TYPE.VALIDATED &&
+ elem.oldState === ELEMENT_TYPE.DENIED
+ );
+ }
+ ).map(function (elem) {
+ return elem.elementId;
+ });
+
+ let deniedArrayIds = _.filter(elementsForValidation, function (
+ elem
+ ) {
+ return elem.newState === ELEMENT_TYPE.DENIED;
+ }).map(function (elem) {
+ return elem.elementId;
+ });
+
+ if (validatedArrayNoForceIds.length > 0) {
+ do_send_documents(order_id, validatedArrayNoForceIds, false);
+ }
+ if (validatedArrayWithForceIds.length > 0) {
+ do_send_documents(order_id, validatedArrayWithForceIds, true);
+ }
+ if (deniedArrayIds.length > 0) {
+ do_deny_documents(order_id, deniedArrayIds);
+ }
+ dialogElem.dialog('close');
+ }
+
+ function createValidationTable() {
+ $('.validation-content').empty();
+ let validatedArray = _.filter(elementsForValidation, function (
+ elem
+ ) {
+ return elem.newState === ELEMENT_TYPE.VALIDATED;
+ });
+ let deniedArray = _.filter(elementsForValidation, function (elem) {
+ return elem.newState === ELEMENT_TYPE.DENIED;
+ });
+
+ if (validatedArray.length > 0) {
+ let html = '';
+ html +=
+ '' +
+ window.orderItemData.translatedText.youHaveValidated +
+ ' ' +
+ validatedArray.length +
+ ' ' +
+ window.orderItemData.translatedText.item +
+ (validatedArray.length === 1 ? '' : 's') +
+ ' ';
+ html += '';
+ _.each(validatedArray, function (elem) {
+ html += '';
+ html +=
+ '' +
+ elem.elementPreview[0].outerHTML +
+ ' ';
+ html +=
+ '' +
+ elem.elementTitle[0].outerHTML +
+ ' ';
+ html += ' ';
+ });
+ html += '
';
+ $('.validation-content').append(html);
+ }
+
+ if (deniedArray.length > 0) {
+ let html = '';
+ html +=
+ '' +
+ window.orderItemData.translatedText.youHaveDenied +
+ ' ' +
+ deniedArray.length +
+ ' ' +
+ window.orderItemData.translatedText.item +
+ (deniedArray.length === 1 ? '' : 's') +
+ ' ';
+ html += '';
+ _.each(deniedArray, function (elem) {
+ html += '';
+ html +=
+ '' +
+ elem.elementPreview[0].outerHTML +
+ ' ';
+ html +=
+ '' +
+ elem.elementTitle[0].outerHTML +
+ ' ';
+ html += ' ';
+ });
+ html += '
';
+ $('.validation-content').append(html);
+ }
+ }
+
+ function removeItemFromArray(item) {
+ var elementId = item.find('input[name=order_element_id]').val();
+ var found = _.where(elementsForValidation, {elementId: elementId});
+ if(found.length > 0) {
+ item.removeClass(ELEMENT_TYPE.WAITINGFORVALIDATION);
+ //replace content or row with original content
+ item[0].innerHTML = found[0].element[0].innerHTML;
+ //remove from array
+ elementsForValidation = _.without(elementsForValidation, found[0]);
+ }
+ }
+ function resetItemForValidation(itemsToBeReset) {
+ var elementArrayType = [];
+ itemsToBeReset.forEach(function(item){
+ removeItemFromArray(item);
+ updateButtonStatus(item.attr('class').split(/\s+/));
+ elementArrayType.push(item.attr('class').split(/\s+/));
+ });
+ if(elementsForValidation.length == 0) {
+ readyForValidation = false;
+ }
+ updateButtonStatusMultiple(elementArrayType);
+ toggleValidationButton();
+ //disable select all checkbox if selected
+ if($('input[name="select-all"]').is(':checked')){
+ $('input[name="select-all"]').prop('checked', false);
+ }
+ }
+ function resetAllItemForValidation() {
+ //var dialog = p4.Dialog.get(1);
+ $('.order_list .order_row', $dialog.getDomElement()).each(function(i,n){
+ removeItemFromArray($(n));
+ updateButtonStatus($(n).attr('class').split(/\s+/));
+ });
+ readyForValidation = false;
+ renderOrderDetailView(0);
+ }
+
+ function updateValidation(newState) {
+ let count = 0;
+ $('.order_list .order_row', $dialog.getDomElement()).each(function (
+ i,
+ n
+ ) {
+ if (
+ $(n).hasClass(ELEMENT_TYPE.SELECTED) &&
+ !$(n).hasClass(ELEMENT_TYPE.VALIDATED) &&
+ !$(n).hasClass(ELEMENT_TYPE.DENIED) &&
+ !$(n).hasClass(ELEMENT_TYPE.WAITINGFORVALIDATION)
+ ) {
+ createItemForValidation(
+ $(n),
+ ELEMENT_TYPE.SELECTABLE,
+ newState
+ );
+ count++;
+ } else if (
+ $(n).hasClass(ELEMENT_TYPE.SELECTED) &&
+ !$(n).hasClass(ELEMENT_TYPE.VALIDATED) &&
+ !$(n).hasClass(ELEMENT_TYPE.WAITINGFORVALIDATION)
+ ) {
+ createItemForValidation(
+ $(n),
+ ELEMENT_TYPE.DENIED,
+ newState
+ );
+ count++;
+ }
+ $(n).removeClass(ELEMENT_TYPE.SELECTED);
+ });
+
+ //if item is not selected, delete item being previewed
+ if(count == 0 && lastItemChosen) {
+ createItemForValidation(lastItemChosen, ELEMENT_TYPE.SELECTABLE, newState);
+ count++;
+ }
+
+ readyForValidation = true;
+ toggleValidationButton();
+ //disable select all checkbox if selected
+ if ($('input[name="select-all"]').is(':checked')) {
+ $('input[name="select-all"]').prop('checked', false);
+ }
+
+ //multiple items selected
+ if (count > 1) {
+ $('#wrapper-padding').hide();
+ $('.external-order-action').hide();
+ $('#wrapper-multiple').hide();
+ $('#wrapper-no-item').show();
+ }
+ }
+
+ function createItemForValidation(element, oldState, newState) {
+ let order = {};
+ order.elementTitle = element.find('span');
+ order.elementPreview = element.find('.order_wrapper');
+ order.elementId = element
+ .find('input[name=order_element_id]')
+ .val();
+ order.element = element.clone(true);
+ order.oldState = oldState;
+ order.newState = newState;
+ elementsForValidation.push(order);
+
+ //element.removeClass('to_be_denied');
+ //element.removeClass('to_be_validated');
+
+ element.toggleClass(ELEMENT_TYPE.WAITINGFORVALIDATION);
+ //element.addClass('to_be_'+order.newState);
+
+ element.find('td:first-child').empty();
+ element
+ .find('td:first-child')
+ .append(' ');
+ updateButtonStatus(element.attr('class').split(/\s+/));
+ }
+
+ function toggleValidationButton() {
+ if (readyForValidation) {
+ $('button.validate').prop('disabled', false);
+ $('button.validate').css('color', '#7CD21C');
+ } else {
+ $('button.validate').prop('disabled', true);
+ $('button.validate').css('color', '#737373');
+ }
+ }
+
+ function do_send_documents(order_id, elements_ids, force) {
+ let cont = $dialog.getDomElement();
+
+ $('button.deny, button.send', cont).prop('disabled', true);
+ $('.activity_indicator', cont).show();
+
+ $.ajax({
+ type: 'POST',
+ url: '../prod/order/' + order_id + '/send/',
+ dataType: 'json',
+ data: {
+ 'elements[]': elements_ids,
+ force: force ? 1 : 0
+ },
+ success: function (data) {
+ let success = '0';
+
+ if (data.success) {
+ success = '1';
+ }
+
+ var url =
+ '../prod/order/' +
+ order_id +
+ '/?success=' +
+ success +
+ '&action=send';
+ reloadDialog(url);
+ },
+ error: function () {
+ $('button.deny, button.send', cont).prop('disabled', false);
+ $('.activity_indicator', cont).hide();
+ },
+ timeout: function () {
+ $('button.deny, button.send', cont).prop('disabled', false);
+ $('.activity_indicator', cont).hide();
+ }
+ });
+ }
+
+ function do_deny_documents(order_id, elements_ids) {
+ let cont = $dialog.getDomElement();
+ $('button.deny, button.send', cont).prop('disabled', true);
+ $('.activity_indicator', cont).show();
+
+ $.ajax({
+ type: 'POST',
+ url: '../prod/order/' + order_id + '/deny/',
+ dataType: 'json',
+ data: {
+ 'elements[]': elements_ids
+ },
+ success: function (data) {
+ let success = '0';
+
+ if (data.success) {
+ success = '1';
+ }
+
+ var url =
+ '../prod/order/' +
+ order_id +
+ '/?success=' +
+ success +
+ '&action=deny';
+ reloadDialog(url);
+ },
+ error: function () {
+ $('button.deny, button.send', cont).prop('disabled', false);
+ $('.activity_indicator', cont).hide();
+ },
+ timeout: function () {
+ $('button.deny, button.send', cont).prop('disabled', false);
+ $('.activity_indicator', cont).hide();
+ }
+ });
+ }
+
+ function renderOrderDetailView(countSelected) {
+ if (countSelected > 1) {
+ $('#wrapper-padding').hide();
+ $('.external-order-action').hide();
+ $('#wrapper-multiple').show();
+ $('#wrapper-no-item').hide();
+ let elementArrayType = [];
+ $(
+ '.order_list .selectable.selected',
+ $dialog.getDomElement()
+ ).each(function (i, n) {
+ //elementArrayType = _.union(elementArrayType, $(n).attr('class').split(/\s+/));
+ elementArrayType.push($(n).attr('class').split(/\s+/));
+ });
+ updateButtonStatusMultiple(elementArrayType);
+ //updateButtonStatus(elementArrayType);
+ } else if (countSelected === 1) {
+ $('#wrapper-padding').show();
+ $('.external-order-action').show();
+ $('#wrapper-multiple').hide();
+ $('#wrapper-no-item').hide();
+ } else {
+ $('#wrapper-padding').hide();
+ $('.external-order-action').hide();
+ $('#wrapper-multiple').hide();
+ $('#wrapper-no-item').show();
+ }
+ $('#preview-layout-multiple .title').html(countSelected);
+ }
+
+ function updateButtonStatusMultiple(elementArrayType) {
+ $('#order-action button.deny, #order-action button.send').hide();
+ let countObj = elementArrayType.reduce(
+ function (m, v) {
+ for (let k in m) {
+ if (~v.indexOf(k)) m[k]++;
+ }
+ return m;
+ },
+ { validated: 0, selectable: 0, waitingForValidation: 0 }
+ );
+
+ let html = '';
+ if (countObj.validated > 0) {
+ html +=
+ '' +
+ window.orderItemData.translatedText.itemsAlreadySent +
+ ': ' +
+ countObj.validated +
+ '
';
+ }
+
+ if (countObj.waitingForValidation > 0) {
+ html +=
+ '' +
+ window.orderItemData.translatedText.itemsWaitingValidation +
+ ': ' +
+ countObj.waitingForValidation +
+ '
';
+ }
+
+ //for the remaining items
+ let remaining =
+ countObj.selectable -
+ (countObj.validated + countObj.waitingForValidation);
+ if (remaining > 0) {
+ html +=
+ '' +
+ window.orderItemData.translatedText.nonSentItems +
+ ': ' +
+ remaining +
+ '
';
+ $('#order-action button.deny, #order-action button.send').prop(
+ 'disabled',
+ false
+ );
+ $(
+ '#order-action button.deny, #order-action button.send'
+ ).show();
+ }
+
+ $('#wrapper-multiple #text-content').empty();
+ $('#wrapper-multiple #text-content').append(html);
+ }
+
+ /* *
+ * function to update status of send and deny button
+ * params - array of type for each button selected
+ */
+ function updateButtonStatus(elementArrayType) {
+ if (_.contains(elementArrayType, ELEMENT_TYPE.VALIDATED)) {
+ $('#order-action button.deny, #order-action button.send, #order-action button.reset').hide();
+ $('#order-action span.action-text').html(
+ window.orderItemData.translatedText.alreadyValidated +
+ ' '
+ );
+ $('#order-action span.action-text').show();
+ } else if (
+ _.contains(elementArrayType, ELEMENT_TYPE.WAITINGFORVALIDATION)
+ ) {
+ $('#order-action button.deny, #order-action button.send, #order-action span.action-text').hide();
+ $('#order-action button.reset').show();
+ //$('#order-action button.send').show();
+ //$('#order-action button.send').prop('disabled', true);
+ } else if (_.contains(elementArrayType, ELEMENT_TYPE.DENIED)) {
+ $('#order-action button.deny, #order-action button.reset').hide();
+ $('#order-action span.action-text').html('window.orderItemData.translatedText.refusedPreviously');
+ //$('#order-action button.send').prop('disabled', false);
+ $('#order-action button.send, #order-action span.action-text').show();
+ } else {
+ // $('#order-action button.send, #order-action button.deny').prop('disabled', false);
+ $('#order-action button.send, #order-action button.deny').show();
+ $('#order-action span.action-text, #order-action button.reset').hide();
+ }
+ }
+
+ function loadPreviewAndCaption(elem) {
+ $('#preview-layout').empty();
+ $('#caption-layout').empty();
+ updateButtonStatus(elem.attr('class').split(/\s+/));
+ let elementids = elem.attr('elementids').split('_');
+ let sbasId = elementids[0];
+ let recordId = elementids[1];
+ let prevAjax = $.ajax({
+ type: 'GET',
+ url: '../prod/records/record/' + sbasId + '/' + recordId + '/',
+ dataType: 'json',
+ success: function (data) {
+ if (data.error) {
+ return;
+ }
+
+ $('#preview-layout').append(data.html_preview);
+ $('#caption-layout').append(data.desc);
+
+ }
+ });
+ }
+
+ function reloadDialog(url) {
+ const baseUrl = configService.get('baseUrl');
+ $.ajax({
+ type: 'GET',
+ url: `${baseUrl}${url}`,
+ success: function (data) {
+ if (data.error) {
+ return;
+ }
+ $dialog.setContent(data);
+ _onOrderItemReady($dialog);
+ }
+ });
+ }
+ };
+
+ return {
+ openModal
+ };
+};
+
+
+export default orderItem;
diff --git a/Phraseanet-production-client/src/components/preferences/index.js b/Phraseanet-production-client/src/components/preferences/index.js
new file mode 100644
index 0000000000..d332b4d38d
--- /dev/null
+++ b/Phraseanet-production-client/src/components/preferences/index.js
@@ -0,0 +1,416 @@
+import $ from 'jquery';
+import * as appCommons from './../../phraseanet-common';
+let highlight = require('imports-loader?$=jquery!../utils/jquery-plugins/highlight');
+let colorpicker = require('imports-loader?$=jquery!../utils/jquery-plugins/colorpicker/colorpicker');
+const preferences = services => {
+ const { configService, localeService, appEvents } = services;
+ const url = configService.get('baseUrl');
+ const initialize = (options = {}) => {
+ const { $container } = options;
+
+ render();
+
+ $container.on('change', '#ADVSRCH_FILTER_FACET', event => {
+ let $el = $(event.currentTarget);
+ event.preventDefault();
+ appCommons.userModule.setPref('facet', $el.prop('checked'));
+ appEvents.emit('search.updateFacetData');
+ appEvents.emit('search.doRefreshState');
+ });
+
+ $container.on('click', '.open-preferences', event => {
+ event.preventDefault();
+ openModal(event);
+ });
+
+ $container.on('click', '.preferences-options-submit', event => {
+ event.preventDefault();
+ submitState();
+ });
+
+ $container.on('change', '.preferences-options-start-page', event => {
+ event.preventDefault();
+ setInitialStateOptions();
+ });
+
+ $container.on('change', '.preferences-options-search-reload', event => {
+ let $el = $(event.currentTarget);
+ event.preventDefault();
+ appCommons.userModule.setPref(
+ 'advanced_search_reload',
+ $el.prop('checked') ? '1' : '0'
+ );
+ });
+
+ $container.on('change', '.preferences-options-use-truncation', event => {
+ let $el = $(event.currentTarget);
+ event.preventDefault();
+ appCommons.userModule.setPref(
+ 'use_truncation',
+ $el.prop('checked') ? '1' : '0'
+ );
+ });
+
+ $container.on(
+ 'change',
+ '.preferences-options-presentation-thumbnail',
+ event => {
+ let $el = $(event.currentTarget);
+ event.preventDefault();
+ appCommons.userModule.setPref('view', $el.val());
+ appEvents.emit('search.doRefreshState');
+ }
+ );
+
+ $container.on(
+ 'change',
+ '.preferences-options-presentation-list',
+ event => {
+ let $el = $(event.currentTarget);
+ event.preventDefault();
+ appCommons.userModule.setPref('view', $el.val());
+ appEvents.emit('search.doRefreshState');
+ }
+ );
+
+ $container.on(
+ 'change',
+ '.preferences-options-rollover-caption',
+ event => {
+ let $el = $(event.currentTarget);
+ event.preventDefault();
+ appCommons.userModule.setPref('rollover_thumbnail', $el.val());
+ appEvents.emit('search.doRefreshState');
+ }
+ );
+
+ $container.on(
+ 'change',
+ '.preferences-options-rollover-preview',
+ event => {
+ let $el = $(event.currentTarget);
+ event.preventDefault();
+ appCommons.userModule.setPref('rollover_thumbnail', $el.val());
+ appEvents.emit('search.doRefreshState');
+ }
+ );
+
+ $container.on(
+ 'change',
+ '.preferences-options-technical-display',
+ event => {
+ let $el = $(event.currentTarget);
+ event.preventDefault();
+ appCommons.userModule.setPref('technical_display', $el.val());
+ appEvents.emit('search.doRefreshState');
+ }
+ );
+ $container.on(
+ 'change',
+ '.preferences-options-rollover-preview',
+ event => {
+ let $el = $(event.currentTarget);
+ event.preventDefault();
+ appCommons.userModule.setPref('technical_display', $el.val());
+ appEvents.emit('search.doRefreshState');
+ }
+ );
+ $container.on(
+ 'change',
+ '.preferences-options-rollover-preview',
+ event => {
+ let $el = $(event.currentTarget);
+ event.preventDefault();
+ appCommons.userModule.setPref('technical_display', $el.val());
+ appEvents.emit('search.doRefreshState');
+ }
+ );
+
+ $container.on(
+ 'change',
+ '.preferences-options-doctype-display',
+ event => {
+ let $el = $(event.currentTarget);
+ event.preventDefault();
+ appCommons.userModule.setPref(
+ 'doctype_display',
+ $el.prop('checked') ? '1' : '0'
+ );
+ appEvents.emit('search.doRefreshState');
+ }
+ );
+
+ $container.on('change', '.preferences-options-basket-status', event => {
+ let $el = $(event.currentTarget);
+ event.preventDefault();
+ appCommons.userModule.setPref(
+ 'basket_status_display',
+ $el.prop('checked') ? '1' : '0'
+ );
+ });
+
+ $container.on(
+ 'change',
+ '.preferences-options-basket-caption',
+ event => {
+ let $el = $(event.currentTarget);
+ event.preventDefault();
+ appCommons.userModule.setPref(
+ 'basket_caption_display',
+ $el.prop('checked') ? '1' : '0'
+ );
+ }
+ );
+
+ $container.on('change', '.preferences-options-basket-title', event => {
+ let $el = $(event.currentTarget);
+ event.preventDefault();
+ appCommons.userModule.setPref(
+ 'basket_title_display',
+ $el.prop('checked') ? '1' : '0'
+ );
+ });
+
+
+ $container.on('change', '.preferences-options-basket-type', event => {
+ let $el = $(event.currentTarget);
+ event.preventDefault();
+ appCommons.userModule.setPref(
+ 'basket_type_display',
+ $el.prop('checked') ? '1' : '0'
+ );
+ });
+
+ $container.on('click', '.preference-change-theme-action', event => {
+ let $el = $(event.currentTarget);
+ let color = $el.data('theme');
+ let minified = configService.get('debug') ? '' : '.min';
+ // setCss()
+ $('#skinCss').attr(
+ 'href',
+ `/assets/production/skin-${color}${minified}.css`
+ );
+
+ /* $.post(`${configService.get('baseUrl')}/user/preferences/`, {
+ prop: 'css',
+ value: color,
+ t: Math.random()
+ });*/
+ var skin = '';
+ $.ajax({
+ type: 'POST',
+ url: `${url}user/preferences/`,
+ data: {
+ prop: 'css',
+ value: color,
+ t: Math.random()
+ },
+ success: function (data) {
+ $('body').removeClass().addClass('PNB ' + color);
+ /* console.log('saved:' + color);*/
+ return;
+ }
+ });
+
+ });
+
+ $container.on('change', '.preferences-options-collection-order', event => {
+ let el = $('#look_box_settings select[name=orderByName]');
+ event.preventDefault();
+ appCommons.userModule.setPref(
+ 'order_collection_by',
+ el.val()
+ );
+ });
+
+ $('.preferences-facet-order').change( function (event) {
+ let el = $('.look_box_settings select[name=orderFacet]');
+ event.preventDefault();
+ appCommons.userModule.setPref(
+ 'order_facet',
+ el.val()
+ );
+ appEvents.emit('search.updateFacetData');
+ });
+
+ $('.preferences-facet-values-order').change( function (event) {
+ let el = $('.look_box_settings select[name=facetValuesOrder]');
+ event.preventDefault();
+ appCommons.userModule.setPref(
+ 'facet_values_order',
+ el.val()
+ );
+ appEvents.emit('search.updateFacetData');
+ });
+
+ $container.on('change', '.upload-options-collection', event => {
+ let el = $('.settings-box select[name=base_id]');
+ event.preventDefault();
+ appCommons.userModule.setPref(
+ 'upload_last_used_collection',
+ el.val()
+ );
+ });
+
+ $('#nperpage_slider').slider({
+ value: parseInt($('#nperpage_value').val(), 10),
+ min: 10,
+ max: 100,
+ step: 10,
+ slide: function (event, ui) {
+ $('#nperpage_value').val(ui.value);
+ },
+ stop: function (event, ui) {
+ appCommons.userModule.setPref(
+ 'images_per_page',
+ $('#nperpage_value').val()
+ );
+ }
+ });
+ $('#sizeAns_slider').slider({
+ value: parseInt($('#sizeAns_value').val(), 10),
+ min: 90,
+ max: 270,
+ step: 10,
+ slide: function (event, ui) {
+ $('#sizeAns_value').val(ui.value);
+ },
+ stop: function (event, ui) {
+ appCommons.userModule.setPref(
+ 'images_size',
+ $('#sizeAns_value').val()
+ );
+ }
+ });
+ $('#backcolorpickerHolder').ColorPicker({
+ flat: true,
+ color: '404040',
+ livePreview: false,
+ eventName: 'mouseover',
+ onSubmit: function (hsb, hex, rgb, el) {
+ var back_hex = '';
+ var unactive = '';
+ var sim_b;
+
+ if (hsb.b >= 50) {
+ back_hex = '000000';
+
+ sim_b = 0.1 * hsb.b;
+ } else {
+ back_hex = 'FFFFFF';
+
+ sim_b = 100 - 0.1 * (100 - hsb.b);
+ }
+
+ sim_b = 0.1 * hsb.b;
+
+ var sim_rgb = appCommons.utilsModule.hsl2rgb(
+ hsb.h,
+ hsb.s,
+ sim_b
+ );
+ var sim_hex = appCommons.utilsModule.RGBtoHex(
+ sim_rgb.r,
+ sim_rgb.g,
+ sim_rgb.b
+ );
+
+ appCommons.userModule.setPref('background-selection', hex);
+ appCommons.userModule.setPref(
+ 'background-selection-disabled',
+ sim_hex
+ );
+ appCommons.userModule.setPref('fontcolor-selection', back_hex);
+
+ $('style[title=color_selection]').empty();
+
+ var datas =
+ '.diapo.selected,#reorder_box .diapo.selected, #EDIT_ALL .diapo.selected, .list.selected, .list.selected .diapo' +
+ '{' +
+ ' COLOR: #' +
+ back_hex +
+ ';' +
+ ' BACKGROUND-COLOR: #' +
+ hex +
+ ';' +
+ '}';
+ $('style[title=color_selection]').empty().text(datas);
+ }
+ });
+ $('#backcolorpickerHolder')
+ .find('.colorpicker_submit')
+ .append($('#backcolorpickerHolder .submiter'))
+ .bind('click', function () {
+ $(this).highlight('#CCCCCC');
+ });
+ $('#look_box .tabs').tabs();
+ };
+
+ const render = () => {
+ let availableThemes = configService.get('availableThemes');
+ let themeTpl = '';
+
+ for (let t in availableThemes) {
+ let curTheme = availableThemes[t];
+ themeTpl += `
`;
+ }
+ // generates themes
+ $('#theme-container').empty().append(themeTpl);
+ };
+
+ // look_box
+ function setInitialStateOptions() {
+ var el = $('#look_box_settings select[name=start_page]');
+
+ switch (el.val()) {
+ case 'LAST_QUERY':
+ case 'PUBLI':
+ case 'HELP':
+ $('#look_box_settings input[name=start_page_value]').hide();
+ break;
+ case 'QUERY':
+ $('#look_box_settings input[name=start_page_value]').show();
+ break;
+ default:
+ }
+ }
+
+ function submitState() {
+ var el = $('#look_box_settings select[name=start_page]');
+ var val = el.val();
+
+ var start_page_query = $(
+ '#look_box_settings input[name=start_page_value]'
+ ).val();
+
+ if (val === 'QUERY') {
+ appCommons.userModule.setPref('start_page_query', start_page_query);
+ }
+
+ appCommons.userModule.setPref('start_page', val);
+ }
+
+ function openModal(event) {
+ $('#look_box')
+ .dialog({
+ closeOnEscape: true,
+ resizable: false,
+ width: 450,
+ height: 500,
+ modal: true,
+ draggable: false,
+ overlay: {
+ backgroundColor: '#000',
+ opacity: 0.7
+ }
+ })
+ .dialog('open');
+ }
+
+ return {
+ initialize,
+ openModal
+ };
+};
+
+export default preferences;
diff --git a/Phraseanet-production-client/src/components/publication/index.js b/Phraseanet-production-client/src/components/publication/index.js
new file mode 100644
index 0000000000..daba2be519
--- /dev/null
+++ b/Phraseanet-production-client/src/components/publication/index.js
@@ -0,0 +1,454 @@
+import $ from 'jquery';
+let lazyload = require('jquery-lazyload');
+import dialog from './../../phraseanet-common/components/dialog';
+
+const publication = (services) => {
+ let ajaxState = {
+ query: null,
+ isRunning: false
+ };
+ let $answers;
+ let curPage;
+ const { configService, localeService, appEvents } = services;
+ const url = configService.get('baseUrl');
+
+ const initialize = () => {
+
+ $answers = $('#answers');
+
+ // refresh current view
+ $answers.on('click', '.feed_reload', function (event) {
+ event.preventDefault();
+ fetchPublications(curPage);
+ });
+
+ // navigate to a specific feed
+ $answers.on('click', '.ajax_answers', function (event) {
+ event.preventDefault();
+ var $this = $(this);
+ var append = $this.hasClass('append');
+ var noScroll = $this.hasClass('no_scroll');
+
+ _fetchRemote($(event.currentTarget).attr('href'), {})
+ .then(function (data) {
+ if (!append) {
+ $answers.empty();
+ if (!noScroll) {
+ $answers.scrollTop(0);
+ }
+ $answers.append(data);
+
+ $answers.find('img.lazyload').lazyload({
+ container: $answers
+ });
+ } else {
+ $('.see_more.loading', $answers).remove();
+ $answers.append(data);
+
+ $answers.find('img.lazyload').lazyload({
+ container: $answers
+ });
+
+ if (!noScroll) {
+ $answers.animate({
+ scrollTop: ($answers.scrollTop() + $answers.innerHeight() - 80)
+ });
+ }
+ }
+ appEvents.emit('search.doAfterSearch');
+ });
+
+ });
+
+ // subscribe_rss
+ $answers.on('click', '.subscribe_rss', function (event) {
+ event.preventDefault();
+ let $this = $(this);
+ let renew = false;
+
+ /*if (typeof (renew) === 'undefined') {
+ renew = 'false';
+ } else {
+ renew = renew ? 'true' : 'false';
+ }*/
+
+ var buttons = {};
+ buttons[localeService.t('renewRss')] = function () {
+ $this.trigger({
+ type: 'click',
+ renew: true
+ });
+ };
+ buttons[localeService.t('fermer')] = function () {
+ $('#DIALOG').empty().dialog('destroy');
+ };
+
+ event.stopPropagation();
+
+ $.ajax({
+ type: 'GET',
+ url: $this.attr('href') + (event.renew === true ? '?renew=true' : ''),
+ dataType: 'json',
+ success: function (data) {
+ if (data.texte !== false && data.titre !== false) {
+ if ($('#DIALOG').data('ui-dialog')) {
+ $('#DIALOG').dialog('destroy');
+ }
+ $('#DIALOG').attr('title', data.titre)
+ .empty()
+ .append(data.texte)
+ .dialog({
+ autoOpen: false,
+ closeOnEscape: true,
+ resizable: false,
+ draggable: false,
+ modal: true,
+ buttons: buttons,
+ width: 650,
+ height: 250,
+ overlay: {
+ backgroundColor: '#000',
+ opacity: 0.7
+ },
+ open: function() {
+ $('#copy-feed').on('click', function (event) {
+ event.preventDefault();
+ var copyText = document.getElementById('input-select-copy');
+ /* Select the text field */
+ copyText.select();
+ copyText.setSelectionRange(0, 99999); /*For mobile devices*/
+
+ document.execCommand('copy');
+ });
+ },
+ }).dialog('open');
+
+ }
+ }
+ });
+ });
+
+ // edit a feed
+ $answers.on('click', '.feed .entry a.feed_edit', function () {
+ var $this = $(this);
+ $.ajax({
+ type: 'GET',
+ url: $this.attr('href'),
+ dataType: 'html',
+ success: function (data) {
+ return openModal(data);
+ }
+ });
+ return false;
+ });
+
+ // remove a feed
+ $answers.on('click', '.feed .entry a.feed_delete', function () {
+ if (!confirm('etes vous sur de vouloir supprimer cette entree ?')) {
+ return false;
+ }
+ var $this = $(this);
+ $.ajax({
+ type: 'POST',
+ url: $this.attr('href'),
+ dataType: 'json',
+ success: function (data) {
+ if (data.error === false) {
+ var $entry = $this.closest('.entry');
+ $entry.animate({
+ height: 0,
+ opacity: 0
+ }, function () {
+ $entry.remove();
+ });
+ } else {
+ alert(data.message);
+ }
+ }
+ });
+ return false;
+ });
+
+
+ $answers.on('mouseover', '.feed .entry', function () {
+ $(this).addClass('hover');
+ });
+
+ $answers.on('mouseout', '.feed .entry', function () {
+ $(this).removeClass('hover');
+ });
+
+ $answers.on('click', '.see_more a', function (event) {
+ const $see_more = $(this).closest('.see_more');
+ $see_more.addClass('loading');
+ });
+ };
+
+
+ const _fetchRemote = function (url, data) {
+ let page = 0;
+ if (data.page === undefined) {
+ page = data.page;
+ }
+
+ ajaxState.query = $.ajax({
+ type: 'GET',
+ url: url,
+ dataType: 'html',
+ data: data,
+ beforeSend: function () {
+ if (ajaxState.isRunning && ajaxState.query.abort) {
+ ajaxState.query.abort();
+ }
+ if (page === 0) {
+ appEvents.emit('search.doClearSearch');
+ }
+ ajaxState.isRunning = true;
+ $answers.addClass('loading');
+ },
+ error: function () {
+ ajaxState.isRunning = false;
+ $answers.removeClass('loading');
+ },
+ timeout: function () {
+ ajaxState.isRunning = false;
+ $answers.removeClass('loading');
+ },
+ success: function (data) {
+ ajaxState.isRunning = false;
+ }
+ });
+ return ajaxState.query;
+ };
+
+ function checkFeedVFieldError() {
+ if ($('.feed_warning').hasClass('alert-error')) {
+ $('.ui-dialog-buttons').find('button').eq(1).prop('disabled', true);
+ } else {
+ $('.ui-dialog-buttons').find('button').eq(1).prop('disabled', false);
+ }
+ }
+
+ function feedFieldValidator (field, feedWarning , length) {
+ field.on('change keyup',function () {
+ if ( $(this).val().length > length){
+ feedWarning.addClass('alert alert-error');
+ }else {
+ feedWarning.removeClass('alert alert-error');
+ }
+ checkFeedVFieldError();
+ });
+ }
+ var openModal = function (data) {
+ let buttons = {};
+ let modal = dialog.create(services, {
+ size: 'Full',
+ closeOnEscape: true,
+ closeButton: true,
+ title: localeService.t('Publication')
+ });
+ //Add custom class to dialog wrapper
+ $('.dialog-Full').closest('.ui-dialog').addClass('black-dialog-wrap publish-dialog');
+
+ modal.setContent(data);
+
+ buttons[localeService.t('valider')] = onSubmitPublication;
+
+ modal.setOption('buttons', buttons);
+ let $feeds_item = $('.feeds .feed', modal.getDomElement());
+ let $form = $('form.main_form', modal.getDomElement());
+ let $feed_title_field = $('#feed_add_title', modal.getDomElement());
+ let $feed_title_warning = $('.feed_title_warning', modal.getDomElement());
+ let $feed_subtitle_field = $('#feed_add_subtitle', modal.getDomElement());
+ let $feed_subtitle_warning = $('.feed_subtitle_warning', modal.getDomElement());
+ feedFieldValidator($feed_title_field,$feed_title_warning, 128);
+ feedFieldValidator($feed_subtitle_field,$feed_subtitle_warning, 1024);
+
+ $feeds_item.bind('click', function () {
+ $feeds_item.removeClass('selected');
+ $(this).addClass('selected');
+ $('input[name="feed_id"]', $form).val($('input', this).val());
+ }).hover(function () {
+ $(this).addClass('hover');
+ }, function () {
+ $(this).removeClass('hover');
+ });
+
+ $form.bind('submit', function () {
+ return false;
+ });
+
+ let formMode = 'create';
+ // is edit mode?
+ if ($('input[name="item_id"]').length > 0) {
+ formMode = 'edit';
+ }
+
+ $('#modal_feed .record_list').sortable({
+ placeholder: 'ui-state-highlight',
+ stop: function (event, ui) {
+
+
+ var lst = [];
+ $('#modal_feed .record_list .sortable form').each(function (i, el) {
+ if (formMode === 'create') {
+ lst.push($('input[name="sbas_id"]', el).val() + '_' + $('input[name="record_id"]', el).val());
+ } else {
+ lst.push($('input[name="item_id"]', el).val());
+
+ }
+ });
+ $('#modal_feed form.main_form input[name="lst"]').val(lst.join(';'));
+ }
+ });
+
+ return;
+ };
+
+ const onSubmitPublication = () => {
+ var $dialog = dialog.get(1);
+ var error = false;
+ var $form = $('form.main_form', $dialog.getDomElement());
+
+ $('.required_text', $form).each(function (i, el) {
+ if ($.trim($(el).val()) === '') {
+ $(el).addClass('error');
+ error = true;
+ }
+ });
+
+ if (error) {
+ alert(localeService.t('feed_require_fields'));
+ }
+
+ if ($('input[name="feed_id"]', $form).val() === '') {
+ alert(localeService.t('feed_require_feed'));
+ error = true;
+ }
+
+ if (error) {
+ return false;
+ }
+
+ $.ajax({
+ type: 'POST',
+ url: $form.attr('action'),
+ data: $form.serializeArray(),
+ dataType: 'json',
+ beforeSend: function () {
+ $('button', $dialog.getDomElement()).prop('disabled', true);
+ },
+ error: function () {
+ $('button', $dialog.getDomElement()).prop('disabled', false);
+ },
+ timeout: function () {
+ $('button', $dialog.getDomElement()).prop('disabled', false);
+ },
+ success: function (data) {
+ $('.state-navigation').trigger('click');
+ $('button', $dialog.getDomElement()).prop('disabled', false);
+ if (data.error === true) {
+ alert(data.message);
+ return;
+ }
+
+ if ($('form.main_form', $dialog.getDomElement()).hasClass('entry_update')) {
+ var id = $('form input[name="entry_id"]', $dialog.getDomElement()).val();
+ var container = $('#entry_' + id);
+
+ container.replaceWith(data.datas);
+
+ container.hide().fadeIn();
+
+ // @TODO: something was happening here
+ $answers.find('img.lazyload').lazyload({
+ container: $answers
+ });
+ }
+
+ $dialog.close(1);
+ }
+ });
+ }
+
+ var fetchPublications = function (page) {
+ if (page === undefined && $answers !== undefined) {
+ // @TODO $answers can be undefined
+ $answers.empty();
+ }
+ if ($answers !== undefined) {
+ curPage = page;
+ return _fetchRemote(`${url}prod/feeds/`, {
+ page: page
+ })
+ .then(function (data) {
+ $('.next_publi_link', $answers).remove();
+
+ $answers.append(data);
+
+ $answers.find('img.lazyload').lazyload({
+ container: $answers
+ });
+
+ appEvents.emit('search.doAfterSearch');
+ if (page > 0) {
+ $answers.stop().animate({
+ scrollTop: $answers.scrollTop() + $answers.height()
+ }, 700);
+ }
+ return;
+ });
+ }
+ };
+
+
+ var publishRecords = function (type, value) {
+ var options = {
+ lst: '',
+ ssel: '',
+ act: ''
+ };
+
+ switch (type) {
+ case 'IMGT':
+ case 'CHIM':
+ options.lst = value;
+ break;
+
+ case 'STORY':
+ options.story = value;
+ break;
+ case 'SSTT':
+ options.ssel = value;
+ break;
+ default:
+ }
+
+ $.post(`${url}prod/feeds/requestavailable/`
+ , options
+ , function (data) {
+
+ return openModal(data);
+ });
+
+ return;
+ };
+
+ const activatePublicationState = () => {
+ appEvents.emit('publication.fetch');
+ }
+
+ appEvents.listenAll({
+ 'publication.activeState': activatePublicationState,
+ 'publication.fetch': fetchPublications
+ });
+ return {
+ initialize,
+ fetchPublications,
+ publishRecords,
+ openModal
+ };
+};
+
+export default publication;
+
diff --git a/Phraseanet-production-client/src/components/record/addToBasket.js b/Phraseanet-production-client/src/components/record/addToBasket.js
new file mode 100644
index 0000000000..95a31f9b5a
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/addToBasket.js
@@ -0,0 +1,22 @@
+import $ from 'jquery';
+
+const addToBasket = (services) => {
+ const { configService, localeService, appEvents } = services;
+ let $container = null;
+ const initialize = () => {
+ $container = $('body');
+ $container.on('click', '.record-add-to-basket-action', (event) => {
+ event.preventDefault();
+ let $el = $(event.currentTarget);
+ let dbId = $el.data('db-id');
+ let recordId = $el.data('record-id');
+ appEvents.emit('workzone.doAddToBasket', {
+ dbId, recordId, event: event.currentTarget
+ });
+ });
+ };
+
+ return { initialize };
+};
+
+export default addToBasket;
diff --git a/Phraseanet-production-client/src/components/record/bridge.js b/Phraseanet-production-client/src/components/record/bridge.js
new file mode 100644
index 0000000000..456ac52500
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/bridge.js
@@ -0,0 +1,31 @@
+import $ from 'jquery';
+import dialog from './../../phraseanet-common/components/dialog';
+import recordBridge from './recordBridge/index';
+
+const bridgeRecord = (services) => {
+ const { configService, localeService, appEvents } = services;
+ const url = configService.get('baseUrl');
+
+ const openModal = (datas) => {
+
+ const $dialog = dialog.create(services, {
+ size: 'Full',
+ title: 'Bridge',
+ loading: false
+ });
+
+ return $.post(`${url}prod/bridge/manager/`, datas, function (data) {
+ $dialog.setContent(data);
+ _onDialogReady();
+ return;
+ });
+ };
+
+ const _onDialogReady = () => {
+ recordBridge(services).initialize();
+ };
+
+ return { openModal };
+};
+
+export default bridgeRecord;
diff --git a/Phraseanet-production-client/src/components/record/delete.js b/Phraseanet-production-client/src/components/record/delete.js
new file mode 100644
index 0000000000..10f2aefe8a
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/delete.js
@@ -0,0 +1,185 @@
+import $ from 'jquery';
+import dialog from './../../phraseanet-common/components/dialog';
+
+const deleteRecord = (services) => {
+ const {configService, localeService, appEvents} = services;
+ const url = configService.get('baseUrl');
+ let workzoneSelection = [];
+ let searchSelection = [];
+
+ const openModal = (datas) => {
+ let $dialog = dialog.create(services, {
+ size: '480x160',
+ title: localeService.t('warning')
+ });
+ $.ajax({
+ type: 'POST',
+ url: `${url}prod/records/delete/what/`,
+ dataType: 'html',
+ data: datas,
+ success: function (data) {
+ $dialog.setOption('height', 'auto');
+ $dialog.setContent(data);
+
+ //reset top position of dialog
+ $dialog.getDomElement().offsetParent().css('top', ($(window).height() - $dialog.getDomElement()[0].clientHeight) / 2);
+ _onDialogReady();
+ }
+ });
+
+ return false;
+ };
+ const _onDialogReady = () => {
+ var $dialog = dialog.get(1);
+ var $dialogBox = $dialog.getDomElement();
+ var $closeButton = $('button.ui-dialog-titlebar-close', $dialogBox.parent());
+ var $cancelButton = $('button.cancel', $dialogBox);
+ var $delChildren = $("input[name='del_children']", $dialogBox);
+ var titleBox = $(".ui-dialog-title", $dialogBox.parent());
+ titleBox.prepend(' ');
+
+
+ /**
+ * the checkbox "delete stories children too" changes
+ **/
+ $delChildren.bind("change", function () {
+ fSetDelChildren($(this).is(':checked'));
+ });
+
+ $cancelButton.bind('click', function () {
+ $dialog.close();
+ });
+
+ /**
+ * set the dlg content according the "delete children" ckbox
+ * the counts (records will be deleted, records rejected...) will update
+ */
+ var fSetDelChildren = function (delChildren) {
+ if (delChildren) {
+ $("#delete_records_parent_only").hide();
+ $("#delete_records_with_children").show();
+ } else {
+ $("#delete_records_with_children").hide();
+ $("#delete_records_parent_only").show();
+ }
+ };
+
+ /**
+ * click ok : run delete tasks
+ */
+ $('button.submiter', $dialogBox).bind('click', function () {
+ let CHUNKSIZE = 3,
+ MAXTASKS = 5;
+ let $this = $(this);
+ let $form = $(this).closest("form"),
+ $counter = $form.find(".to_delete_count"),
+ $trash_counter = $form.find(".to_trash_count"),
+ $loader = $form.find(".form-action-loader");
+ let lst = $("input[name='lst']", $form).val().split(';');
+
+ /**
+ * same parameters for every delete call, except the list of (CHUNKSIZE) records
+ * nb: do NOT ask to delete children since they're included in lst
+ */
+ let ajaxParms = {
+ type: $form.attr("method"),
+ url: $form.attr("action"),
+ data: {
+ 'lst': "" // set in f
+ },
+ dataType: "json"
+ };
+
+ let runningTasks = 0, // number of running tasks
+ canceling = false;
+ /**
+ * cancel or close dlg will ask tasks to stop
+ */
+ let fCancel = function () {
+ $closeButton.hide();
+ $cancelButton.hide();
+ $loader.show();
+ canceling = true;
+ };
+ /**
+ * task fct : will loop itself while there is job to do
+ *
+ * @param iTask (int) The task number 0...MAXTASKS-1, usefull only to debug
+ */
+ let fTask = function (iTask) {
+ if (canceling) {
+ return;
+ }
+ // pop & truncate
+ ajaxParms.data.lst = lst.splice(0, CHUNKSIZE).join(';');
+ $.ajax(ajaxParms)
+ .success(function (data) { // prod feedback only if result ok
+ $.each(data, function (i, n) {
+ let imgt = $('#IMGT_' + n),
+ chim = $('.CHIM_' + n),
+ stories = $('.STORY_' + n);
+ $('.doc_infos', imgt).remove();
+ try {
+ $imgt.draggable("destroy");
+ } catch (e) {
+ // no-op
+ }
+ imgt.unbind("click")
+ .removeAttr("ondblclick")
+ .removeClass("selected")
+ .removeClass("IMGT")
+ .find("img")
+ .unbind();
+ imgt.find(".thumb img")
+ .attr("src", "/assets/common/images/icons/deleted.png")
+ .css({
+ width: '100%',
+ height: 'auto',
+ margin: '0 10px',
+ top: '0'
+ });
+ chim.parent().slideUp().remove();
+ imgt.find(".status,.title,.bottom").empty();
+
+ appEvents.emit('search.selection.remove', {records: n});
+
+ if (stories.length > 0) {
+ appEvents.emit('workzone.refresh');
+ } else {
+ appEvents.emit('workzone.selection.remove', {records: n});
+ }
+ });
+ })
+ .then(function () { // go on even in case of error
+ // countdown
+ $counter.html(lst.length);
+ $trash_counter.html(lst.length);
+ if (lst.length === 0 || canceling) {
+ // end of a task
+ if (--runningTasks === 0) {
+ $dialog.close();
+ $('#nbrecsel').empty().append(lst.length);
+ }
+ } else {
+ // don't recurse, give a delay to running fct to end
+ window.setTimeout(fTask, 10, iTask);
+ }
+ });
+ };
+
+ // cancel or close the dlg is the same : wait
+ $dialog.setOption('closeOnEscape', false);
+ $closeButton.unbind("click").bind("click", fCancel);
+ $cancelButton.unbind("click").bind("click", fCancel);
+ // run a bunch of tasks in //
+ for (runningTasks = 0; runningTasks < MAXTASKS && lst.length > 0; runningTasks++) {
+ fTask(runningTasks); // pass the task his index to get nice console logs
+ }
+
+ });
+ fSetDelChildren(false);
+ };
+ return {openModal};
+}
+
+export default deleteRecord;
diff --git a/Phraseanet-production-client/src/components/record/edit.js b/Phraseanet-production-client/src/components/record/edit.js
new file mode 100644
index 0000000000..a7c5865327
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/edit.js
@@ -0,0 +1,160 @@
+import $ from 'jquery';
+import recordEditorService from './recordEditor/index';
+import * as appCommons from './../../phraseanet-common';
+
+const editRecord = (services) => {
+ const { configService, localeService, appEvents } = services;
+ const url = configService.get('baseUrl');
+ let $container = null;
+ let recordEditor = recordEditorService(services);
+ appEvents.listenAll({
+ 'record.doEdit': _doEdit
+ });
+
+ const initialize = () => {
+
+
+ $container = $('body');
+ $container.on('click', '.edit-record-action', function (event) {
+ event.preventDefault();
+ let $el = $(event.currentTarget);
+ let type = '';
+ let kind = $el.data('kind');
+ let idContent = $el.data('id');
+
+ switch (kind) {
+ case 'basket':
+ type = 'SSTT';
+ break;
+ case 'record':
+ type = 'IMGT';
+ break;
+ default:
+ }
+
+ _doEdit({type: type, value: idContent});
+ });
+
+
+ };
+
+ const openModal = (datas) => {
+ $('#EDITWINDOW').empty().addClass('loading');
+ //commonModule.showOverlay(2);
+
+ $('#EDITWINDOW').show();
+
+ $.ajax({
+ url: `${url}prod/records/edit/`,
+ type: 'POST',
+ dataType: 'html',
+ data: datas,
+ success: (data) => {
+ $('#EDITWINDOW').removeClass('loading').empty().html(data);
+ // let recordEditor = recordEditorService(services);
+ recordEditor.initialize({
+ $container: $('#EDITWINDOW'),
+ recordConfig: window.recordEditorConfig
+ });
+
+ $('#tooltip').hide();
+ return;
+ },
+ error: function (XHR, textStatus, errorThrown) {
+ if (XHR.status === 0) {
+ return false;
+ }
+ }
+ });
+
+ return true;
+ };
+
+ // open Modal
+ function _doEdit(options) {
+ let {type, value} = options;
+ var datas = {
+ lst: '',
+ ssel: '',
+ act: ''
+ };
+
+ switch (type) {
+ case 'IMGT':
+ datas.lst = value;
+ break;
+
+ case 'SSTT':
+ datas.ssel = value;
+ break;
+
+ case 'STORY':
+ datas.story = value;
+ break;
+ default:
+ }
+
+ return openModal(datas);
+ }
+
+ const onGlobalKeydown = (event, specialKeyState) => {
+ if (specialKeyState === undefined) {
+ let specialKeyState = {
+ isCancelKey: false,
+ isShortcutKey: false
+ };
+ }
+ switch (event.keyCode) {
+ case 9: // tab ou shift-tab
+ fieldNavigate(
+ event,
+ appCommons.utilsModule.is_shift_key(event) ? -1 : 1
+ );
+ specialKeyState.isCancelKey = specialKeyState.isShortcutKey = true;
+ break;
+ case 27:
+ cancelChanges({ event });
+ specialKeyState.isShortcutKey = true;
+ break;
+
+ case 33: // pg up
+ if (
+ !options.textareaIsDirty ||
+ validateFieldChanges(event, 'ask_ok')
+ ) {
+ skipImage(event, 1);
+ }
+ specialKeyState.isCancelKey = true;
+ break;
+ case 34: // pg dn
+ if (
+ !options.textareaIsDirty ||
+ validateFieldChanges(event, 'ask_ok')
+ ) {
+ skipImage(event, -1);
+ }
+ specialKeyState.isCancelKey = true;
+ break;
+ default:
+ }
+ return specialKeyState;
+ };
+
+ function fieldNavigate(evt, dir) {
+ let current_field = $('#divS .edit_field.active');
+ if (current_field.length === 0) {
+ current_field = $('#divS .edit_field:first');
+ current_field.trigger('click');
+ } else {
+ if (dir >= 0) {
+ current_field.next().trigger('click');
+ } else {
+ current_field.prev().trigger('click');
+ }
+ }
+ }
+
+ return { initialize, openModal, onGlobalKeydown };
+};
+
+export default editRecord;
diff --git a/Phraseanet-production-client/src/components/record/export.js b/Phraseanet-production-client/src/components/record/export.js
new file mode 100644
index 0000000000..ada1d1fe66
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/export.js
@@ -0,0 +1,464 @@
+import $ from 'jquery';
+import dialog from './../../phraseanet-common/components/dialog';
+const humane = require('humane-js');
+
+const exportRecord = services => {
+ const { configService, localeService, appEvents } = services;
+ const url = configService.get('baseUrl');
+ let $container = null;
+ const initialize = () => {
+ $container = $('body');
+ $container.on('click', '.record-export-action', function (event) {
+ event.preventDefault();
+ let $el = $(event.currentTarget);
+ let key = '';
+ let kind = $el.data('kind');
+ let idContent = $el.data('id');
+
+ switch (kind) {
+ case 'basket':
+ key = 'ssel';
+ break;
+ case 'record':
+ key = 'lst';
+ break;
+ default:
+ }
+
+ doExport(`${key}=${idContent}`);
+ });
+ };
+
+ const openModal = datas => doExport(datas);
+
+ function doExport(datas) {
+ var $dialog = dialog.create(services, {
+ size: 'Medium',
+ title: localeService.t('export')
+ });
+
+ $.ajax({
+ method: 'POST',
+ url: `${url}prod/export/multi-export/`,
+ data: datas,
+ success: function (data) {
+ $dialog.setContent(data);
+ if (window.exportConfig.isGuest) {
+ dialog.get(1).close();
+ let guestModal = dialog.create(
+ {
+ size: '500x100',
+ closeOnEscape: true,
+ closeButton: false,
+ title: window.exportConfig.msg.modalTile
+ },
+ 2
+ );
+ guestModal.setContent(window.exportConfig.msg.modalContent);
+ } else {
+ _onExportReady($dialog, window.exportConfig);
+ }
+ }
+ });
+
+ return true;
+ }
+
+ const _onExportReady = ($dialog, dataConfig) => {
+ $('.tabs', $dialog.getDomElement()).tabs();
+
+ $('.close_button', $dialog.getDomElement()).bind('click', function () {
+ $dialog.close();
+ });
+
+ var tabs = $('.tabs', $dialog.getDomElement());
+
+ if (dataConfig.haveFtp === true) {
+ $('#ftp_form_selector')
+ .bind('change', function () {
+ $('#ftp .ftp_form').hide();
+ $('#ftp .ftp_form_' + $(this).val()).show();
+ $('.ftp_folder_check', dialog.get(1).getDomElement())
+ .unbind('change')
+ .bind('change', function () {
+ if ($(this).prop('checked')) {
+ $(this).next().prop('disabled', false);
+ } else {
+ $(this).next().prop('disabled', true);
+ }
+ });
+ })
+ .trigger('change');
+ }
+
+ $('a.TOUview').bind('click', function (event) {
+ event.preventDefault();
+ let $el = $(event.currentTarget);
+ var options = {
+ size: 'Medium',
+ closeButton: true,
+ title: dataConfig.msg.termOfUseTitle
+ };
+
+ let termOfuseDialog = dialog.create(services, options, 2);
+
+ $.get($el.attr('href'), function (content) {
+ termOfuseDialog.setContent(content);
+ });
+ });
+
+ $('.close_button').bind('click', function () {
+ $dialog.close();
+ });
+
+ $('#download .download_button').bind('click', function () {
+ if (!check_subdefs($('#download'), dataConfig)) {
+ return false;
+ }
+
+ if (!check_TOU($('#download'), dataConfig)) {
+ return false;
+ }
+
+ var total = 0;
+ var count = 0;
+
+ $('input[name="obj[]"]', $('#download')).each(function () {
+ var total_el = $(
+ '#download input[name=download_' + $(this).val() + ']'
+ );
+ var count_el = $(
+ '#download input[name=count_' + $(this).val() + ']'
+ );
+ if ($(this).prop('checked')) {
+ total += parseInt($(total_el).val(), 10);
+ count += parseInt($(count_el).val(), 10);
+ }
+ });
+
+ if (count > 1 && total / 1024 / 1024 > dataConfig.maxDownload) {
+ if (
+ confirm(
+ `${dataConfig.msg.fileTooLarge} \n ${dataConfig.msg
+ .fileTooLargeAlt}`
+ )
+ ) {
+ $(
+ 'input[name="obj[]"]:checked',
+ $('#download')
+ ).each(function (i, n) {
+ $(
+ 'input[name="obj[]"][value="' + $(n).val() + '"]',
+ $('#sendmail')
+ ).prop('checked', true);
+ });
+
+ $(document).find('input[name="taglistdestmail"]').tagsinput('add', dataConfig.user.email);
+
+ var tabs = $('.tabs', $dialog.getDomElement());
+ tabs.tabs('option', 'active', 1);
+ }
+
+ return false;
+ }
+ $('#download form').submit();
+ $dialog.close();
+ });
+
+ $('#order .order_button').bind('click', function () {
+ let title = '';
+ if (!check_TOU($('#order'), dataConfig)) {
+ return false;
+ }
+
+ $('#order .order_button_loader').css('visibility', 'visible');
+
+ var options = $('#order form').serialize();
+
+ var $this = $(this);
+ $this.prop('disabled', true).addClass('disabled');
+ $.post(
+ `${url}prod/order/`,
+ options,
+ function (data) {
+ $this.prop('disabled', false).removeClass('disabled');
+
+ $('#order .order_button_loader').css(
+ 'visibility',
+ 'hidden'
+ );
+
+ if (!data.error) {
+ title = dataConfig.msg.success;
+ } else {
+ title = dataConfig.msg.warning;
+ }
+
+ var options = {
+ size: 'Alert',
+ closeButton: true,
+ title: title
+ };
+
+ dialog.create(services, options, 2).setContent(data.msg);
+
+ if (!data.error) {
+ humane.info(data.msg);
+ $dialog.close();
+ } else {
+ humane.error(data.msg);
+ }
+
+ return;
+ },
+ 'json'
+ );
+ });
+
+ $('#ftp .ftp_button').bind('click', function () {
+ if (!check_subdefs($('#ftp'), dataConfig)) {
+ return false;
+ }
+
+ if (!check_TOU($('#ftp'), dataConfig)) {
+ return false;
+ }
+
+ $('#ftp .ftp_button_loader').show();
+
+ $('#ftp .ftp_form:hidden').remove();
+
+ var $this = $(this);
+
+ var options_addr = $('#ftp_form_stock form:visible').serialize();
+ var options_join = $('#ftp_joined').serialize();
+
+ $this.prop('disabled', true);
+ $.post(
+ `${url}prod/export/ftp/`,
+ options_addr + '&' + options_join,
+ function (data) {
+ $this.prop('disabled', false);
+ $('#ftp .ftp_button_loader').hide();
+
+ if (data.success) {
+ humane.info(data.message);
+ $dialog.close();
+ } else {
+ var alert = dialog.create(
+ services,
+ {
+ size: 'Alert',
+ closeOnEscape: true,
+ closeButton: true,
+ title: dataConfig.msg.warning
+ },
+ 2
+ );
+
+ alert.setContent(data.message);
+ }
+ return;
+ },
+ 'json'
+ );
+ });
+
+ $('#ftp .tryftp_button').bind('click', function () {
+ $('#ftp .tryftp_button_loader').css('visibility', 'visible');
+ var $this = $(this);
+ $this.prop('disabled', true);
+ var options_addr = $('#ftp_form_stock form:visible').serialize();
+
+ $.post(
+ `${url}prod/export/ftp/test/`,
+ // no need to include 'ftp_joined' checkboxes to test ftp
+ options_addr,
+ function (data) {
+ $('#ftp .tryftp_button_loader').css('visibility', 'hidden');
+
+ var options = {
+ size: 'Alert',
+ closeButton: true,
+ title: data.success
+ ? dataConfig.msg.success
+ : dataConfig.msg.warning
+ };
+
+ dialog
+ .create(services, options, 3)
+ .setContent(data.message);
+
+ $this.prop('disabled', false);
+
+ return;
+ }
+ );
+ });
+
+ $('#sendmail .sendmail_button').bind('click', function () {
+ if(!validEmail($('input[name="taglistdestmail"]', $('#sendmail')).val(), dataConfig)) {
+ return false;
+ }
+
+ if (!check_subdefs($('#sendmail'), dataConfig)) {
+ return false;
+ }
+
+ if (!check_TOU($('#sendmail'), dataConfig)) {
+ return false;
+ }
+
+ if ($('iframe[name=""]').length === 0) {
+ $('body').append(
+ ''
+ );
+ }
+
+ $('#sendmail form').submit();
+ humane.infoLarge($('#export-send-mail-notif').val());
+ $dialog.close();
+ });
+
+ $('.datepicker', $dialog.getDomElement()).datepicker({
+ changeYear: true,
+ changeMonth: true,
+ dateFormat: 'yy-mm-dd'
+ });
+
+ $(
+ 'a.undisposable_link',
+ $dialog.getDomElement()
+ ).bind('click', function () {
+ $(this).parent().parent().find('.undisposable').slideToggle();
+ return false;
+ });
+
+ $(
+ 'input[name="obj[]"]',
+ $('#download, #sendmail, #ftp')
+ ).bind('change', function () {
+ var $form = $(this).closest('form');
+
+ if ($('input.caption[name="obj[]"]:checked', $form).length > 0) {
+ $('div.businessfields', $form).show();
+ } else {
+ $('div.businessfields', $form).hide();
+ }
+ });
+ };
+
+ function validateEmail(email) {
+ var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
+ return re.test(email);
+ }
+
+ function validEmail(emailList, dataConfig) {
+ //split emailList by ; , or whitespace and filter empty element
+ let emails = emailList.split(/[ ,;]+/).filter(Boolean);
+ let alert;
+ for(let i=0; i < emails.length; i++) {
+ if (!validateEmail(emails[i])) {
+
+ alert = dialog.create(
+ services,
+ {
+ size: 'Alert',
+ closeOnEscape: true,
+ closeButton: true,
+ title: dataConfig.msg.warning
+ },
+ 2
+ );
+
+ alert.setContent(dataConfig.msg.invalidEmail);
+ return false;
+ }
+ }
+ return true;
+ }
+
+
+ function check_TOU(container, dataConfig) {
+ let checkbox = $('input[name="TOU_accept"]', $(container));
+ let go = checkbox.length === 0 || checkbox.prop('checked');
+ let alert;
+ if (!go) {
+ alert = dialog.create(
+ services,
+ {
+ size: 'Small',
+ closeOnEscape: true,
+ closeButton: true,
+ title: dataConfig.msg.warning
+ },
+ 2
+ );
+
+ alert.setContent(dataConfig.msg.termOfUseAgree);
+
+ return false;
+ }
+ return true;
+ }
+
+ function check_subdefs(container, dataConfig) {
+ let go = false;
+ let required = false;
+ let alert;
+
+ $('input[name="obj[]"]', $(container)).each(function () {
+ if ($(this).prop('checked')) {
+ go = true;
+ }
+ });
+
+ $('input.required, textarea.required', container).each(function (i, n) {
+ if ($.trim($(n).val()) === '') {
+ required = true;
+ $(n).addClass('error');
+ } else {
+ $(n).removeClass('error');
+ }
+ });
+
+ if (required) {
+ alert = dialog.create(
+ services,
+ {
+ size: 'Alert',
+ closeOnEscape: true,
+ closeButton: true,
+ title: dataConfig.msg.warning
+ },
+ 2
+ );
+
+ alert.setContent(dataConfig.msg.requiredFields);
+
+ return false;
+ }
+ if (!go) {
+ alert = dialog.create(
+ services,
+ {
+ size: 'Alert',
+ closeOnEscape: true,
+ closeButton: true,
+ title: dataConfig.msg.warning
+ },
+ 2
+ );
+
+ alert.setContent(dataConfig.msg.missingSubdef);
+
+ return false;
+ }
+
+ return true;
+ }
+
+ return { initialize, openModal };
+};
+
+export default exportRecord;
diff --git a/Phraseanet-production-client/src/components/record/feedback.js b/Phraseanet-production-client/src/components/record/feedback.js
new file mode 100644
index 0000000000..801746b629
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/feedback.js
@@ -0,0 +1,44 @@
+import $ from 'jquery';
+import dialog from './../../phraseanet-common/components/dialog';
+import pushRecord from './recordPush/index';
+
+const recordFeedbackModal = (services, datas) => {
+ const { configService, localeService, appEvents } = services;
+ const url = configService.get('baseUrl');
+
+
+ const openModal = (datas) => {
+ /* disable push closeonescape as an over dialog may exist (add user) */
+ let $dialog = dialog.create(services, {
+ size: 'Full',
+ title: localeService.t('feedback')
+ });
+
+ $dialog.getDomElement().closest('.ui-dialog').addClass('feedback_dialog_container');
+
+ $.post(`${url}prod/push/validateform/`, datas, function (data) {
+ // data content's javascript can't be fully refactored
+ $dialog.setContent(data);
+ _onDialogReady();
+ return;
+ });
+
+ return true;
+ };
+
+ const _onDialogReady = () => {
+ pushRecord(services).initialize({
+ feedback: {
+ containerId: '#PushBox',
+ context: 'Feedback'
+ },
+ listManager: {
+ containerId: '#ListManager'
+ }
+ });
+ };
+
+ return { openModal };
+};
+
+export default recordFeedbackModal;
diff --git a/Phraseanet-production-client/src/components/record/index.js b/Phraseanet-production-client/src/components/record/index.js
new file mode 100644
index 0000000000..9fc66e02fc
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/index.js
@@ -0,0 +1,40 @@
+import {Observable} from 'rx';
+// import {ajax} from 'jquery';
+import $ from 'jquery';
+
+let recordService = (services) => {
+ const {configService} = services;
+ const url = configService.get('baseUrl');
+ const notificationEndPoint = 'session/notifications/';
+ let initialize = () => {
+ };
+
+ let getNotification = (data) => {
+ let notificationPromise = $.Deferred();
+ $.ajax({
+ type: 'POST',
+ url: `${url}${notificationEndPoint}`,
+ data: data,
+ dataType: 'json'
+ }).done((data) => {
+ data.status = data.status || false;
+ if (data.status === 'ok') {
+ notificationPromise.resolve(data);
+ } else {
+ notificationPromise.reject(data);
+ }
+ })
+ .fail((data) => {
+ notificationPromise.reject(data);
+ });
+ return notificationPromise.promise();
+ };
+
+ let stream = Observable.fromPromise(getNotification);
+ return {
+ initialize,
+ getNotification,
+ stream
+ };
+};
+export default recordService;
diff --git a/Phraseanet-production-client/src/components/record/model/index.js b/Phraseanet-production-client/src/components/record/model/index.js
new file mode 100644
index 0000000000..223a7fd340
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/model/index.js
@@ -0,0 +1,449 @@
+import $ from 'jquery';
+
+function checkVocabId(VocabularyId) {
+ if (typeof VocabularyId === 'undefined') {
+ VocabularyId = null;
+ }
+
+ if (VocabularyId === '') {
+ VocabularyId = null;
+ }
+
+ return VocabularyId;
+}
+
+var recordFieldValue = function (meta_id, value, VocabularyId) {
+
+ VocabularyId = checkVocabId(VocabularyId);
+
+ this.datas = {
+ meta_id: meta_id,
+ value: value,
+ VocabularyId: VocabularyId
+ };
+
+ var $this = this;
+};
+
+recordFieldValue.prototype = {
+ getValue: function () {
+ return this.datas.value;
+ },
+ getMetaId: function () {
+ return this.datas.meta_id;
+ },
+ getVocabularyId: function () {
+ return this.datas.VocabularyId;
+ },
+ setValue: function (value, VocabularyId) {
+
+ this.datas.value = value;
+ this.datas.VocabularyId = checkVocabId(VocabularyId);
+ return this;
+ },
+ remove: function () {
+ this.datas.value = '';
+ this.datas.VocabularyId = null;
+
+ return this;
+ }
+};
+
+var databoxField = function (name, label, meta_struct_id, options) {
+
+ var defaults = {
+ multi: false,
+ required: false,
+ readonly: false,
+ maxLength: null,
+ minLength: null,
+ type: 'string',
+ separator: null,
+ vocabularyControl: null,
+ vocabularyRestricted: false
+ };
+
+ options = (typeof options === 'object') ? options : {};
+
+ if (isNaN(meta_struct_id)) {
+ throw 'meta_struct_id should be a number';
+ }
+
+ this.name = name;
+ this.label = label;
+ this.meta_struct_id = meta_struct_id;
+ this.options = $.extend(defaults, options);
+
+ if (this.options.multi === true && this.options.separator === null) {
+ this.options.separator = ';';
+ }
+
+};
+
+databoxField.prototype = {
+ getMetaStructId: function () {
+ return this.meta_struct_id;
+ },
+ getName: function () {
+ return this.name;
+ },
+ getLabel: function () {
+ return this.label;
+ },
+ isMulti: function () {
+ return this.options.multi;
+ },
+ isRequired: function () {
+ return this.options.required;
+ },
+ isReadonly: function () {
+ return this.options.readonly;
+ },
+ getMaxLength: function () {
+ return this.options.maxLength;
+ },
+ getMinLength: function () {
+ return this.options.minLength;
+ },
+ getType: function () {
+ return this.options.type;
+ },
+ getSeparator: function () {
+ return this.options.separator;
+ }
+};
+
+var recordField = function (databoxField, arrayValues) {
+
+ this.databoxField = databoxField;
+ this.options = {
+ dirty: false
+ };
+ this.datas = [];
+
+ if (arrayValues instanceof Array) {
+ if (arrayValues.length > 1 && !databoxField.isMulti()) {
+ throw 'You can not add multiple values to a non multi field ' + databoxField.getName();
+ }
+
+ var first = true;
+
+ for (let v in arrayValues) {
+ if (typeof arrayValues[v] !== 'object') {
+ if (window.console) {
+ console.error('Trying to add a non-recordFieldValue to the field...');
+ }
+
+ continue;
+ }
+
+ if (isNaN(arrayValues[v].getMetaId())) {
+ if (window.console) {
+ console.error('Trying to add a recordFieldValue without metaId...');
+ }
+
+ continue;
+ }
+
+ if (!first && this.options.multi === false) {
+ if (window.console) {
+ console.error('Trying to add multi values in a non-multi field');
+ }
+ }
+
+ /*if (window.console) {
+ console.log('adding a value : ', arrayValues[v]);
+ }*/
+
+ this.datas.push(arrayValues[v]);
+ first = false;
+ }
+ }
+
+ var $this = this;
+};
+recordField.prototype = {
+ getName: function () {
+ return this.databoxField.getName();
+ },
+ getMetaStructId: function () {
+ return this.databoxField.getMetaStructId();
+ },
+ isMulti: function () {
+ return this.databoxField.isMulti();
+ },
+ isRequired: function () {
+ return this.databoxField.isRequired();
+ },
+ isDirty: function () {
+ return this.options.dirty;
+ },
+ addValue: function (value, merge, VocabularyId) {
+
+ VocabularyId = checkVocabId(VocabularyId);
+
+ merge = !!merge;
+
+/* if (this.databoxField.isReadonly()) {
+ if (window.console) {
+ console.error('Unable to set a value to a readonly field');
+ }
+
+ return this;
+ }*/
+
+ if (window.console) {
+ console.log('adding value ', value, ' vocId : ', VocabularyId, ' ; merge is ', merge);
+ }
+
+ if (this.isMulti()) {
+ if (!this.hasValue(value, VocabularyId)) {
+ if (window.console) {
+ console.log('adding new multi value ', value);
+ }
+ this.datas.push(new recordFieldValue(null, value, VocabularyId));
+ this.options.dirty = true;
+ } else {
+ if (window.console) {
+ console.log('already have ', value);
+ }
+ }
+ } else {
+ if (merge === true && this.isEmpty() === false && VocabularyId === null) {
+ if (window.console) {
+ console.log('Merging value ', value);
+ }
+ this.datas[0].setValue(this.datas[0].getValue() + ' ' + value, VocabularyId);
+
+ this.options.dirty = true;
+ } else {
+ if (merge === true && this.isEmpty() === false && VocabularyId !== null) {
+ if (window.console) {
+ console.error('Cannot merge vocabularies');
+ }
+ this.datas[0].setValue(value, VocabularyId);
+ } else {
+
+ if (!this.hasValue(value, VocabularyId)) {
+ if (this.datas.length === 0) {
+ /*if (window.console) {
+ console.log('Adding new value ', value);
+ }*/
+ this.datas.push(new recordFieldValue(null, value, VocabularyId));
+ } else {
+ if (window.console) {
+ console.log('Updating value ', value);
+ }
+ this.datas[0].setValue(value, VocabularyId);
+ }
+ this.options.dirty = true;
+ }
+ }
+ }
+ }
+
+ return this;
+ },
+ hasValue: function (value, VocabularyId) {
+
+ if (typeof value === 'undefined') {
+ if (window.console) {
+ console.error('Trying to check the presence of an undefined value');
+ }
+ }
+
+ VocabularyId = checkVocabId(VocabularyId);
+
+ for (let d in this.datas) {
+ if (VocabularyId !== null) {
+ if (this.datas[d].getVocabularyId() === VocabularyId) {
+ if (window.console) {
+ console.log('already got the vocab ID');
+ }
+ return true;
+ }
+ } else if (this.datas[d].getVocabularyId() === null && this.datas[d].getValue() === value) {
+ if (window.console) {
+ console.log('already got this value');
+ }
+ return true;
+ }
+ }
+ return false;
+ },
+ removeValue: function (value, vocabularyId) {
+
+ if (this.databoxField.isReadonly()) {
+ if (window.console) {
+ console.error('Unable to set a value to a readonly field');
+ }
+
+ return this;
+ }
+
+ vocabularyId = checkVocabId(vocabularyId);
+
+ if (window.console) {
+ console.log('Try to remove value ', value, vocabularyId, this.datas);
+ }
+
+ for (let d in this.datas) {
+ if (window.console) {
+ console.log('loopin... ', this.datas[d].getValue());
+ }
+ if (this.datas[d].getVocabularyId() !== null) {
+ if (this.datas[d].getVocabularyId() === vocabularyId) {
+ if (window.console) {
+ console.log('Found within the vocab ! removing... ');
+ }
+ this.datas[d].remove();
+ this.options.dirty = true;
+ }
+ } else if (this.datas[d].getValue() === value) {
+ if (window.console) {
+ console.log('Found ! removing... ');
+ }
+ this.datas[d].remove();
+ this.options.dirty = true;
+ }
+ }
+ return this;
+ },
+ isEmpty: function () {
+ var empty = true;
+
+ for (let d in this.datas) {
+ if (this.datas[d].getValue() !== '') {
+ empty = false;
+ }
+ }
+ return empty;
+ },
+ empty: function () {
+
+ if (this.databoxField.isReadonly()) {
+ if (window.console) {
+ console.error('Unable to set a value to a readonly field');
+ }
+
+ return this;
+ }
+
+ for (let d in this.datas) {
+ this.datas[d].remove();
+ this.options.dirty = true;
+ }
+ return this;
+ },
+ getValue: function () {
+
+ if (this.isMulti()) {
+ throw 'This field is multi, I can not give you a single value';
+ }
+
+ if (this.isEmpty()) {
+ return null;
+ }
+
+ return this.datas[0];
+ },
+ getValues: function () {
+
+ if (!this.isMulti()) {
+ throw 'This field is not multi, I can not give you multiple values';
+ }
+
+ if (this.isEmpty()) {
+ return [];
+ }
+
+ var arrayValues = [];
+
+ for (let d in this.datas) {
+ if (this.datas[d].getValue() === '') {
+ continue;
+ }
+
+ arrayValues.push(this.datas[d]);
+ }
+
+ return arrayValues;
+ },
+ sort: function (algo) {
+ this.datas.sort(algo);
+
+ return this;
+ },
+ getSerializedValues: function () {
+
+ var arrayValues = [];
+ var values = this.getValues();
+
+ for (let v in values) {
+ arrayValues.push(values[v].getValue());
+ }
+
+ return arrayValues.join(' ; ');
+ },
+ replaceValue: function (search, replace) {
+
+ if (this.databoxField.isReadonly()) {
+ if (window.console) {
+ console.error('Unable to set a value to a readonly field');
+ }
+
+ return 0;
+ }
+
+ var n = 0;
+
+ for (let d in this.datas) {
+ if (this.datas[d].getVocabularyId() !== null) {
+ continue;
+ }
+
+ var value = this.datas[d].getValue();
+ var replacedValue = value.replace(search, replace);
+
+ if (value === replacedValue) {
+ continue;
+ }
+
+ n++;
+
+ this.removeValue(value);
+
+ if (!this.hasValue(replacedValue)) {
+ this.addValue(replacedValue);
+ }
+
+ this.options.dirty = true;
+ }
+
+ return n;
+ },
+ exportDatas: function () {
+
+ var returnValue = [];
+
+ for (let d in this.datas) {
+ var temp = {
+ meta_id: this.datas[d].getMetaId() ? this.datas[d].getMetaId() : '',
+ meta_struct_id: this.getMetaStructId(),
+ value: this.datas[d].getValue()
+ };
+
+ if (this.datas[d].getVocabularyId()) {
+ temp.vocabularyId = this.datas[d].getVocabularyId();
+ }
+ returnValue.push(temp);
+ }
+
+ return returnValue;
+ }
+};
+
+export {
+ databoxField, recordFieldValue, recordField
+};
+
diff --git a/Phraseanet-production-client/src/components/record/move.js b/Phraseanet-production-client/src/components/record/move.js
new file mode 100644
index 0000000000..77ed60b9a5
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/move.js
@@ -0,0 +1,104 @@
+import $ from 'jquery';
+import dialog from './../../phraseanet-common/components/dialog';
+const humane = require('humane-js');
+
+let $dialog = null;
+
+const moveRecord = (services) => {
+ const { configService, localeService, appEvents } = services;
+ const url = configService.get('baseUrl');
+
+ const openModal = (datas) => {
+ $dialog = dialog.create(services, {
+ size: 'Small phrasea-black-dialog',
+ title: localeService.t('move'),
+ closeButton: true,
+ });
+ //Add custom class to dialog wrapper
+ $('.phrasea-black-dialog').closest('.ui-dialog').addClass('black-dialog-wrap move-dialog');
+
+ return _getMovableRecords(datas)
+ .then((data) => {
+ if (data.success !== undefined) {
+ if (data.success === true) {
+ $dialog.setContent(data.template);
+ _bindFormEvents();
+ } else {
+ if (data.message !== undefined) {
+ $dialog.setContent(data.message);
+ }
+ }
+ }
+ }, (data) => {
+ if (data.message !== undefined) {
+ $dialog.setContent(data.message);
+ }
+
+ });
+ };
+
+ const _bindFormEvents = () => {
+ $dialog = dialog.get(1);
+
+ var $form = $dialog.getDomElement();
+ var buttons = {};
+
+ buttons[localeService.t('valider')] = function () {
+ var coll_son = $('input[name="chg_coll_son"]:checked', $form).length > 0 ? '1' : '0';
+ var datas = {
+ lst: $('input[name="lst"]', $form).val(),
+ base_id: $('select[name="base_id"]', $form).val(),
+ chg_coll_son: coll_son
+ };
+
+ var buttonPanel = $dialog.getDomElement()
+ .closest('.ui-dialog')
+ .find('.ui-dialog-buttonpane');
+
+
+ $(":button:contains('" + localeService.t('valider') + "')", buttonPanel)
+ .attr('disabled', true).addClass('ui-state-disabled');
+
+ _postMovableRecords(datas).then(
+ (data) => {
+ $dialog.close();
+ if (data.success) {
+ humane.info(data.message);
+ } else {
+ humane.error(data.message);
+ }
+ $(":button:contains('" + localeService.t('valider') + "')", buttonPanel)
+ .attr('disabled', false).removeClass('ui-state-disabled');
+ },
+ () => {
+
+ }
+ );
+
+ return false;
+ };
+
+ $dialog.setOption('buttons', buttons);
+ };
+
+ const _getMovableRecords = (datas) => {
+ return $.ajax({
+ type: 'POST',
+ url: `${url}prod/records/movecollection/`,
+ data: datas
+ });
+ };
+
+ const _postMovableRecords = (datas) => {
+ return $.ajax({
+ type: 'POST',
+ url: `${url}prod/records/movecollection/apply/`,
+ dataType: 'json',
+ data: datas
+ });
+ };
+
+ return { openModal };
+};
+
+export default moveRecord;
diff --git a/Phraseanet-production-client/src/components/record/print.js b/Phraseanet-production-client/src/components/record/print.js
new file mode 100644
index 0000000000..ad75cd49ce
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/print.js
@@ -0,0 +1,77 @@
+import $ from 'jquery';
+const printRecord = (services) => {
+ const {configService, localeService, appEvents} = services;
+ const url = configService.get('baseUrl');
+ let $container = null;
+
+ appEvents.listenAll({
+ 'record.doPrint': doPrint
+ });
+
+ const initialize = () => {
+ $container = $('body');
+ $container.on('click', '.record-print-action', function (event) {
+ event.preventDefault();
+ let $el = $(event.currentTarget);
+ let key = '';
+ let kind = $el.data('kind');
+ let idContent = $el.data('id');
+
+ switch (kind) {
+ case 'basket':
+ key = 'ssel';
+ break;
+ case 'record':
+ key = 'lst';
+ break;
+ default:
+ }
+
+ doPrint(`${key}=${idContent}`);
+ });
+ };
+
+ const openModal = (datas) => {
+ return doPrint($.param(datas))
+ }
+
+ function doPrint(value) {
+ if ($('#DIALOG').data('ui-dialog')) {
+ $('#DIALOG').dialog('destroy');
+ }
+ $('#DIALOG').attr('title', localeService.t('print'))
+ .empty().addClass('loading')
+ .dialog({
+ resizable: false,
+ closeOnEscape: true,
+ modal: true,
+ width: '800',
+ height: '500',
+ open: function (event, ui) {
+ $(this).dialog('widget').css('z-index', '1999');
+ },
+ close: function (event, ui) {
+ $(this).dialog('widget').css('z-index', 'auto');
+ }
+ })
+ .dialog('open');
+
+ $.ajax({
+ type: 'POST',
+ url: `${url}prod/printer/?${value}`,
+ dataType: 'html',
+ beforeSend: function () {
+
+ },
+ success: function (data) {
+ $('#DIALOG').removeClass('loading').empty()
+ .append(data);
+ return;
+ }
+ });
+ }
+
+ return {initialize, openModal};
+};
+
+export default printRecord;
diff --git a/Phraseanet-production-client/src/components/record/property.js b/Phraseanet-production-client/src/components/record/property.js
new file mode 100644
index 0000000000..6d54af95b1
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/property.js
@@ -0,0 +1,137 @@
+import $ from 'jquery';
+import dialog from './../../phraseanet-common/components/dialog';
+
+const propertyRecord = (services) => {
+ const { configService, localeService, appEvents } = services;
+ const url = configService.get('baseUrl');
+
+ const openModal = (datas) => {
+ return doProperty(datas);
+ };
+
+ const doProperty = (datas) => {
+ var $dialog = dialog.create(services, {
+ size: 'Medium',
+ title: $('#property-title').val()
+ });
+
+ $.ajax({
+ type: 'GET',
+ data: datas,
+ url: `${url}prod/records/property/`,
+ success: function (data) {
+ $dialog.setContent(data);
+ _onPropertyReady($dialog);
+ }
+ });
+
+ return true;
+ };
+
+ const _onPropertyReady = ($dialog) => {
+ $('#tabs-records-property').tabs({
+ beforeLoad: function (event, ui) {
+
+ ui.ajaxSettings.data = {
+ lst: $('input[name=original_selection]', $(this)).val(),
+ };
+
+ // load template only once
+ if (ui.tab.data('loaded')) {
+ event.preventDefault();
+ return;
+ }
+
+ ui.jqXHR.success(function () {
+ ui.tab.data('loaded', true);
+ ui.tab.find('span').html('');
+ typeTabContent($dialog, '#' + ui.tab.attr('aria-controls'));
+ });
+
+ ui.tab.find('span').html('' + localeService.t('loading') + ' ');
+ },
+ load: function (event, ui) {
+ ui.tab.find('span').empty();
+ }
+ });
+ propertyTabContent($dialog);
+
+
+ };
+ /**
+ * Property Tab
+ * @param $dialogBox
+ */
+ const propertyTabContent = ($dialog) => {
+
+ const $propertyContainer = $('#property-status');
+
+ $propertyContainer.on('click', 'button.cancel', function () {
+ $dialog.close();
+ });
+
+ $propertyContainer.on('click', 'button.submiter', function () {
+ var $this = $(this);
+ var form = $(this).closest('form');
+ var loader = form.find('form-action-loader');
+
+ $.ajax({
+ type: form.attr('method'),
+ url: form.attr('action'),
+ data: form.serializeArray(),
+ dataType: 'json',
+ beforeSend: function () {
+ $this.attr('disabled', true);
+ loader.show();
+ },
+ success: function (data) {
+ $dialog.close();
+ },
+ complete: function () {
+ $this.attr('disabled', false);
+ loader.hide();
+ }
+ });
+ });
+ };
+ /**
+ * Type Tab
+ * @param $dialog
+ * @param typeContainerId
+ */
+ const typeTabContent = ($dialog, typeContainerId) => {
+
+ const $typeContainer = $(typeContainerId);
+
+ $typeContainer.on('click', 'button.cancel', function () {
+ $dialog.close();
+ });
+ $typeContainer.on('click', 'button.submiter', function () {
+ var $this = $(this);
+ var form = $(this).closest('form');
+ var loader = form.find('form-action-loader');
+
+ $.ajax({
+ type: form.attr('method'),
+ url: form.attr('action'),
+ data: form.serializeArray(),
+ dataType: 'json',
+ beforeSend: function () {
+ $this.attr('disabled', true);
+ loader.show();
+ },
+ success: function (data) {
+ $dialog.close();
+ },
+ complete: function () {
+ $this.attr('disabled', false);
+ loader.hide();
+ }
+ });
+ });
+ };
+
+ return {openModal};
+};
+
+export default propertyRecord;
diff --git a/Phraseanet-production-client/src/components/record/publish.js b/Phraseanet-production-client/src/components/record/publish.js
new file mode 100644
index 0000000000..049cf61918
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/publish.js
@@ -0,0 +1,24 @@
+import $ from 'jquery';
+import dialog from './../../phraseanet-common/components/dialog';
+import publication from '../publication';
+
+const recordPublishModal = (services, datas) => {
+ const { configService, localeService, appEvents } = services;
+ const url = configService.get('baseUrl');
+
+ const openModal = (datas) => {
+
+ $.post(`${url}prod/feeds/requestavailable/`
+ , datas
+ , function (data) {
+
+ return publication(services).openModal(data);
+ });
+
+ return true;
+ };
+
+ return { openModal };
+};
+
+export default recordPublishModal;
diff --git a/Phraseanet-production-client/src/components/record/push.js b/Phraseanet-production-client/src/components/record/push.js
new file mode 100644
index 0000000000..d0b1b4cff8
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/push.js
@@ -0,0 +1,44 @@
+import $ from 'jquery';
+import dialog from './../../phraseanet-common/components/dialog';
+import pushRecordWindow from './recordPush/index';
+
+const pushRecord = (services, datas) => {
+ const {configService, localeService, appEvents} = services;
+ const url = configService.get('baseUrl');
+
+
+ const openModal = (datas) => {
+
+ let $dialog = dialog.create(services, {
+ size: 'Full',
+ title: localeService.t('push')
+ });
+
+ $dialog.getDomElement().closest('.ui-dialog').addClass('push_dialog_container');
+
+ $.post(`${url}prod/push/sendform/`, datas, function (data) {
+ $dialog.setContent(data);
+ _onDialogReady();
+ return;
+ });
+
+ return true;
+ };
+
+ const _onDialogReady = () => {
+ pushRecordWindow(services).initialize({
+ feedback: {
+ containerId: '#PushBox',
+ context: 'Push'
+ },
+ listManager: {
+ containerId: '#ListManager'
+ }
+ });
+ };
+
+
+ return {openModal};
+};
+
+export default pushRecord;
diff --git a/Phraseanet-production-client/src/components/record/recordBridge/index.js b/Phraseanet-production-client/src/components/record/recordBridge/index.js
new file mode 100644
index 0000000000..3945bea1db
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/recordBridge/index.js
@@ -0,0 +1,331 @@
+import $ from 'jquery';
+import dialog from './../../../phraseanet-common/components/dialog';
+
+const recordBridge = (services) => {
+ const { configService, localeService, appEvents } = services;
+ const url = configService.get('baseUrl');
+ let pub_tabs = $('#pub_tabs');
+ let container = $('#dialog_publicator');
+ let managerUrl = container.data('url');
+ let $panel;
+ const initialize = () => {
+ pub_tabs.tabs({
+ beforeLoad: function (event, ui) {
+ ui.tab.html_tab = ui.tab.find('span').html();
+ ui.tab.find('span').html('' + localeService.t('Loading') + '... ');
+ },
+ load: function (event, ui) {
+ ui.tab.find('span').empty().append(ui.tab.html_tab);
+ $panel = $(ui.panel);
+ $('.container-bridge', $panel).removeClass('loading');
+ $panel.addClass('PNB');
+ $panel.wrapInner("
");
+ panel_load($panel);
+ },
+ beforeActivate: function (event, ui) {
+ if ($(ui.tab).hasClass('account')) {
+ var container = $('.container-bridge', ui.panel);
+ container.empty();
+ $('.container', ui.panel).addClass('loading');
+ }
+ }
+ }).addClass('ui-tabs-vertical ui-helper-clearfix');
+
+ $('.ui-tabs-nav', pub_tabs).removeClass('ui-corner-all');
+
+
+ $('.new_bridge_button', pub_tabs).bind('click', function () {
+ var url = $(this).parent('form').find('input[name="url"]').val();
+ popme(url);
+
+ return false;
+ });
+
+ $('ul li a.account', pub_tabs).bind('click', function () {
+ $('#dialog_publicator form[name="current_datas"] input[name="account_id"]').val($('input[name="account_id"]', this).val());
+ });
+
+ $('ul li.ui-tabs-selected a.account', pub_tabs).trigger('click');
+
+ $('#publicator_selection .PNB10:first').selectable();
+
+ $('#publicator_selection button.act_upload').bind('click', function () {
+
+ var $this = $(this);
+ var $form = $this.closest('form');
+
+ $('input[name=lst]', $form).val(
+ $.makeArray(
+ $('#publicator_selection .diapo.ui-selected').map(function (i, el) {
+ return $(el).attr('id').split('_').slice(2, 4).join('_');
+ })
+ ).join(';')
+ );
+
+ var account_id = $('form[name="current_datas"] input[name="account_id"]').val();
+ $('input[name="account_id"]', $form).val(account_id);
+
+ var $panel = $('#pub_tabs .ui-tabs-panel:visible');
+
+ $.ajax({
+ type: 'GET',
+ url: `${url}prod/bridge/upload/`,
+ data: $form.serializeArray(),
+ beforeSend: function () {
+ $panel.empty().addClass('loading');
+ },
+ success: function (datas) {
+ $panel.removeClass('loading').append(datas);
+ panel_load($panel);
+ },
+ error: function () {
+ $panel.removeClass('loading');
+ },
+ timeout: function () {
+ $panel.removeClass('loading');
+ }
+ });
+
+ return false;
+ });
+
+
+ $('li', pub_tabs).removeClass('ui-corner-top').addClass('ui-corner-left');
+
+ $('#api_connexion').click(function () {
+ if (container.data('ui-dialog')) {
+ container.dialog('close');
+ }
+ });
+ };
+
+
+ function popme(url) {
+ var newwindow = window.open(url, 'logger', 'height=500,width=800');
+ if (window.focus) {
+ newwindow.focus();
+ }
+
+ return false;
+ }
+
+ function panel_load($panel) {
+ $('.new_bridge_button', $panel).bind('click', function () {
+ var url = $(this).parent('form').find('input[name="url"]').val();
+ popme(url);
+
+ return false;
+ });
+
+ $('.error_box, .notice_box', $panel).delay(10000).fadeOut();
+
+ $('.back_link', $panel).bind('click', function () {
+ if ($('#pub_tabs').data('ui-tabs')) {
+ $('#pub_tabs').tabs('load', $('#pub_tabs').tabs('option', 'active'));
+ }
+
+ return false;
+ });
+
+ $('.bridge_action', $panel).bind('click', function () {
+ var $this = $(this);
+
+ $.ajax({
+ type: 'GET',
+ url: $(this).attr('href'),
+ beforeSend: function () {
+ var container = $('.container-bridge', $panel);
+ container.empty();
+ if (!$this.hasClass('bridge_logout')) {
+ container.addClass('loading');
+ }
+ },
+ success: function (datas) {
+ $('.container-bridge', $panel).removeClass('loading').append(datas);
+ panel_load($panel);
+ },
+ error: function () {
+ $panel.removeClass('loading');
+ },
+ timeout: function () {
+ $panel.removeClass('loading');
+ }
+ });
+
+ return false;
+ });
+
+ $('.delete-account', $panel).bind('click', function () {
+ let account_id = $(this).val();
+ let buttons = {};
+
+ buttons[localeService.t('valider')] = function () {
+ $.ajax({
+ type: 'POST',
+ dataType: 'json',
+ url: `${url}prod/bridge/adapter/${account_id}/delete/`,
+ data: {},
+ success: function (datas) {
+ if (datas.success) {
+ confirmBox.close();
+ appEvents.emit('push.reload', managerUrl);
+ // pushModule.reloadBridge(managerUrl);
+ } else {
+ confirmBox.close();
+ var alertBox = dialog.create(services, {
+ size: 'Alert',
+ closeOnEscape: true,
+ closeButton: true
+ }, 2);
+
+ alertBox.setContent(datas.message);
+ }
+ }
+ });
+ };
+
+ var confirmBox = dialog.create(services, {
+ size: 'Alert',
+ closeOnEscape: true,
+ closeButton: true,
+ cancelButton: true,
+ buttons: buttons
+ }, 2);
+
+ confirmBox.setContent(localeService.t('You are about to delete this account. Would you like to continue ?'));
+ });
+
+ $('.form_submitter', $panel).bind('click', function () {
+ var $form = $(this).closest('form');
+ var method = $form.attr('method');
+
+ method = $.inArray(method.toLowerCase(), ['post', 'get']) ? method : 'POST';
+
+ $.ajax({
+ type: method,
+ url: $form.attr('action'),
+ data: $form.serializeArray(),
+ beforeSend: function () {
+ $panel.empty().addClass('loading');
+ },
+ success: function (datas) {
+ $panel.removeClass('loading').append(datas);
+ panel_load($panel);
+ },
+ error: function () {
+ $panel.removeClass('loading');
+ },
+ timeout: function () {
+ $panel.removeClass('loading');
+ }
+ });
+
+ return false;
+ });
+
+
+ $('.bridge_all_selector', $panel).bind('click', function () {
+ var checkboxes = $('.bridge_element_selector', $panel);
+ var $this = $(this);
+
+ checkboxes.each(function (i, checkbox) {
+ if ($(checkbox).is(':checked') !== $this.is(':checked')) {
+ var event = $.Event('click');
+ event.selector_all = true;
+ $(checkbox).trigger(event);
+ }
+ });
+ });
+
+ $('.bridge_element_selector', $panel)
+ .bind('click', function (event) {
+
+ var $this = $(this);
+
+ if (event.selector_all) {
+ $this.prop('checked', $('.bridge_all_selector', $panel).is(':checked'));
+ }
+
+ $('form[name="bridge_selection"] input[name="elements_list"]', $panel).val(
+ $.makeArray($('.bridge_element_selector:checked', $panel).map(function (i, el) {
+ return ($(el).val());
+ })).join(';')
+ );
+
+ if ($this.is(':checked')) {
+ $this.closest('.element').addClass('selected');
+ } else {
+ $this.closest('.element').removeClass('selected');
+ }
+
+ if (!event.selector_all) {
+ var bool = !($('.bridge_element_selector:checked', $panel).length !== $('.bridge_element_selector', $panel).length);
+ $('.bridge_all_selector', $panel).prop('checked', bool);
+ } else {
+ if (event.stopPropagation) {
+ event.stopPropagation();
+ }
+
+ return false;
+ }
+ });
+
+
+ $('a.form_multiple_submitter', $panel).bind('click', function () {
+
+ var $form = $(this).closest('form');
+ var elements = $('form[name="bridge_selection"] input[name="elements_list"]', $panel).val();
+
+ var n_elements = 0;
+ if ($.trim(elements) !== '') {
+ n_elements = elements.split(';').length;
+ }
+
+ if (n_elements === 0 && $form.hasClass('action_works_standalone') === false) {
+ alert('No records selected');
+
+ return false;
+ }
+ if (n_elements === 1 && $form.hasClass('action_works_single_element') === false) {
+ alert('This action works only with a single records');
+
+ return false;
+ }
+ if (n_elements > 1 && $form.hasClass('action_works_many_element') === false) {
+ alert('This action works only with many records');
+
+ return false;
+ }
+
+ $('input[name="elements_list"]', $form).val(elements);
+
+ $.ajax({
+ type: 'GET',
+ url: $form.attr('action'),
+ data: $form.serializeArray(),
+ beforeSend: function () {
+ $panel.empty().addClass('loading');
+ },
+ success: function (datas) {
+ $panel.removeClass('loading').append(datas);
+ panel_load($panel);
+ },
+ error: function () {
+ $panel.removeClass('loading');
+ },
+ timeout: function () {
+ $panel.removeClass('loading');
+ }
+ });
+
+ return false;
+
+ });
+ }
+
+
+ return {
+ initialize
+ };
+};
+export default recordBridge;
diff --git a/Phraseanet-production-client/src/components/record/recordEditor/index.js b/Phraseanet-production-client/src/components/record/recordEditor/index.js
new file mode 100644
index 0000000000..97bf4c2a10
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/recordEditor/index.js
@@ -0,0 +1,1840 @@
+import $ from 'jquery';
+import _ from 'underscore';
+import merge from 'lodash.merge';
+import * as appCommons from './../../../phraseanet-common';
+import { cleanTags } from '../../utils/utils';
+import { sprintf } from 'sprintf-js';
+import recordEditorLayout from './layout';
+import presetsModule from './presets';
+import searchReplace from './plugins/searchReplace';
+import preview from './plugins/preview';
+import thesaurusDatasource from './plugins/thesaurusDatasource';
+import geonameDatasource from './plugins/geonameDatasource';
+import leafletMap from './../../geolocalisation/providers/mapbox';
+import Emitter from '../../core/emitter';
+import RecordCollection from './models/recordCollection';
+import FieldCollection from './models/fieldCollection';
+import StatusCollection from './models/statusCollection';
+
+require('./../../../phraseanet-common/components/tooltip');
+require('./../../../phraseanet-common/components/vendors/contextMenu');
+
+const recordEditorService = services => {
+ const { configService, localeService, appEvents } = services;
+ const url = configService.get('baseUrl');
+ let recordEditorEvents;
+ let $container = null;
+ let options = {};
+ let recordConfig = {};
+ let ETHSeeker;
+ let $editorContainer = null;
+ let $ztextStatus;
+ let $editTextArea;
+ let $editMonoValTextArea;
+ let $editMultiValTextArea;
+ let $toolsTabs;
+ let $idExplain;
+
+ const initialize = params => {
+ let initWith = ({ $container, recordConfig } = params);
+ recordEditorEvents = new Emitter();
+ options = {};
+ $editorContainer = options.$container = $container; //$('#idFrameE');
+ options.recordConfig = recordConfig || {};
+ options.textareaIsDirty = false;
+ options.fieldLastValue = '';
+ options.lastClickId = null;
+ options.sbas_id = false;
+ options.what = false;
+ options.newrepresent = false;
+
+ $ztextStatus = $('#ZTextStatus', options.$container);
+ $editTextArea = $('#idEditZTextArea', options.$container);
+ $editMonoValTextArea = $('#ZTextMonoValued', options.$container);
+ $editMultiValTextArea = $('#EditTextMultiValued', options.$container);
+ $toolsTabs = $('#EDIT_MID_R .tabs', options.$container);
+ $idExplain = $('#idExplain', options.$container);
+
+ $toolsTabs.tabs({
+ activate: function (event, ui) {
+ recordEditorEvents.emit('tabChange', {
+ tab: ui.newPanel.selector
+ });
+ }
+ });
+ _bindEvents();
+ startThisEditing(recordConfig);
+ };
+
+ const _bindEvents = () => {
+ onUserInputComplete = _.debounce(onUserInputComplete, 300);
+
+ recordEditorEvents.listenAll({
+ 'recordEditor.addMultivaluedField': addValueInMultivaluedField,
+ 'recordEditor.onUpdateFields': refreshFields,
+ 'recordEditor.submitAllChanges': submitChanges,
+ 'recordEditor.cancelAllChanges': cancelChanges,
+
+ 'recordEditor.addValueFromDataSource': addValueFromDataSource,
+ 'recordEditor.addPresetValuesFromDataSource': addPresetValuesFromDataSource,
+ /* eslint-disable quote-props */
+ appendTab: appendTab,
+ 'recordEditor.activateToolTab': activateToolTab
+ });
+
+ // set grouping (regroupement) image
+ $editorContainer.parent().on('click', '.set-grouping-image-action', event => {
+ let $el = $(event.currentTarget);
+ setRegDefault($el.data('index'), $el.data('record-id'));
+ })
+
+ $editorContainer
+ .on('click', '.select-record-action', event => {
+ let $el = $(event.currentTarget);
+ _onSelectRecord(event, $el.data('index'));
+ })
+ // status field edition
+ .on('click', '.edit-status-action', event => {
+ event.cancelBubble = true;
+ event.stopPropagation();
+
+ if (
+ !options.textareaIsDirty ||
+ validateFieldChanges(event, 'ask_ok') === true
+ ) {
+ enableStatusField(event);
+ }
+ return false;
+ })
+ // edit field by name / set active for edition
+ .on('click', '.edit-field-action', event => {
+ let $el = $(event.currentTarget);
+ if (
+ !options.textareaIsDirty ||
+ validateFieldChanges(event, 'ask_ok') === true
+ ) {
+ onSelectField(event, $el.data('id'));
+ }
+ return false;
+ })
+ .on('click', '.field-navigate-action', event => {
+ event.preventDefault();
+ let $el = $(event.currentTarget);
+ let dir = $el.data('direction') === 'forward' ? 1 : -1;
+
+ fieldNavigate(event, dir);
+ })
+ .on('submit', '.add-multivalued-field-action', event => {
+ event.preventDefault();
+ let $el = $(event.currentTarget);
+ let fieldValue = $('#' + $el.data('input-id')).val();
+
+ addValueInMultivaluedField({ value: fieldValue });
+ })
+ .on('click', '.edit-multivalued-field-action', event => {
+ event.preventDefault();
+ let $el = $(event.currentTarget);
+
+ _editMultivaluedField($el, $el.data('index'));
+ })
+ .on('click', '.toggle-status-field-action', event => {
+ event.preventDefault();
+ let $el = $(event.currentTarget);
+ let state = $el.data('state') === true ? 1 : 0;
+ toggleStatus(event, $el.data('bit'), state);
+ })
+ .on('click', '.commit-field-action', event => {
+ event.preventDefault();
+ let $el = $(event.currentTarget);
+ validateFieldChanges(event, $el.data('mode'));
+ })
+ .on('click', '.apply-multi-desc-action', event => {
+ event.preventDefault();
+ submitChanges({ event });
+ })
+ .on('click', '.cancel-multi-desc-action', event => {
+ event.preventDefault();
+ cancelChanges({ event });
+ })
+ .on('mouseup mousedown keyup keydown', '#idEditZTextArea', function (
+ event
+ ) {
+ switch (event.type) {
+ case 'mouseup':
+ _onTextareaMouseUp(event);
+ break;
+ case 'mousedown':
+ _onTextareaMouseDown(event);
+ break;
+ case 'keyup':
+ _onTextareaKeyUp(event);
+ break;
+ case 'keydown':
+ _onTextareaKeyDown(event);
+ break;
+ default:
+ }
+ });
+ };
+
+ const onGlobalKeydown = (event, specialKeyState) => {
+ if (specialKeyState === undefined) {
+ let specialKeyState = {
+ isCancelKey: false,
+ isShortcutKey: false
+ };
+ }
+ switch (event.keyCode) {
+ case 9: // tab ou shift-tab
+ fieldNavigate(
+ event,
+ appCommons.utilsModule.is_shift_key(event) ? -1 : 1
+ );
+ specialKeyState.isCancelKey = specialKeyState.isShortcutKey = true;
+ break;
+ case 27:
+ cancelChanges({ event });
+ specialKeyState.isShortcutKey = true;
+ break;
+
+ case 33: // pg up
+ if (
+ !options.textareaIsDirty ||
+ validateFieldChanges(event, 'ask_ok')
+ ) {
+ skipImage(event, 1);
+ }
+ specialKeyState.isCancelKey = true;
+ break;
+ case 34: // pg dn
+ if (
+ !options.textareaIsDirty ||
+ validateFieldChanges(event, 'ask_ok')
+ ) {
+ skipImage(event, -1);
+ }
+ specialKeyState.isCancelKey = true;
+ break;
+ default:
+ }
+ return specialKeyState;
+ };
+
+ function startThisEditing(params) {
+ // sbas_id, what, regbasprid, ssel) {
+ let {
+ hasMultipleDatabases,
+ databoxId,
+ mode,
+ notActionable,
+ notActionableMsg,
+ state
+ } = params;
+
+ if (hasMultipleDatabases === true) {
+ $('#EDITWINDOW').hide();
+ // editor can't be run
+ $('#dialog-edit-many-sbas', options.$container).dialog({
+ modal: true,
+ resizable: false,
+ buttons: {
+ Ok: function () {
+ $(this).dialog('close');
+ }
+ }
+ });
+ return;
+ }
+ if (notActionable > 0) {
+ alert(notActionableMsg);
+ }
+
+ options.sbas_id = databoxId;
+ options.what = mode;
+ options = merge(options, state);
+
+ options.fieldCollection = new FieldCollection(state.T_fields);
+ options.statusCollection = new StatusCollection(state.T_statbits);
+ options.recordCollection = new RecordCollection(
+ state.T_records,
+ options.fieldCollection,
+ options.statusCollection,
+ state.T_sgval
+ );
+
+ $editMultiValTextArea.bind('keyup', function () {
+ _reveal_mval($(this).val());
+ });
+
+ $('#divS div.edit_field:odd').addClass('odd');
+ $('#divS div')
+ .bind('mouseover', function () {
+ $(this).addClass('hover');
+ })
+ .bind('mouseout', function () {
+ $(this).removeClass('hover');
+ });
+
+ $('#editcontextwrap').remove();
+
+ if ($('#editcontextwrap').length === 0) {
+ $('body').append('
');
+ }
+
+ // if is a group, only select the group
+ if (options.what === 'GRP') {
+ _toggleGroupSelection();
+ } else {
+ _edit_select_all();
+ }
+
+ /**Edit Story Select all item **/
+ $('#select-all-diapo').change(function() {
+ if(this.checked) {
+ _edit_select_all_right(true);
+ }
+ else{
+ _edit_select_all_right(false);
+ }
+ });
+
+ $('.previewTips, .DCESTips, .fieldTips', options.$container).tooltip({
+ fixable: true,
+ fixableIndex: 1200
+ });
+ $('.infoTips', options.$container).tooltip();
+
+ if (options.what === 'GRP') {
+ $('#EDIT_FILM2 .reg_opts').show();
+
+ $.each($('#EDIT_FILM2 .contextMenuTrigger'), function () {
+ var id = $(this).attr('id').split('_').slice(1, 3).join('_');
+ $(this).contextMenu('#editContext_' + id + '', {
+ appendTo: '#editcontextwrap',
+ openEvt: 'click',
+ dropDown: true,
+ theme: 'vista',
+ showTransition: 'slideDown',
+ hideTransition: 'hide',
+ shadow: false
+ });
+ });
+ }
+
+ $('#idEditDateZone', options.$container).datepicker({
+ changeYear: true,
+ changeMonth: true,
+ dateFormat: 'yy/mm/dd',
+ onSelect: function (dateText, inst) {
+ var lval = $editTextArea.val();
+ if (lval !== dateText) {
+ options.fieldLastValue = lval;
+ $editTextArea.val(dateText);
+ $editTextArea.trigger('keyup.maxLength');
+ options.textareaIsDirty = true;
+ validateFieldChanges(null, 'ok');
+ }
+ }
+ });
+
+ checkRequiredFields();
+
+ try {
+ $('#divS .edit_field:first').trigger('mousedown');
+ } catch (err) {}
+
+ let recordEditorServices = {
+ configService,
+ localeService,
+ recordEditorEvents
+ };
+
+ recordEditorLayout(recordEditorServices).initialize({
+ $container: $editorContainer,
+ parentOptions: options
+ });
+ presetsModule(recordEditorServices).initialize({
+ $container: $editorContainer,
+ parentOptions: options
+ });
+ // init plugins
+ searchReplace(recordEditorServices).initialize({
+ $container: $editorContainer,
+ parentOptions: options
+ });
+ preview(recordEditorServices).initialize({
+ $container: $('#TH_Opreview .PNB10'),
+ parentOptions: options
+ });
+
+ geonameDatasource(recordEditorServices).initialize({
+ $container: $editorContainer,
+ parentOptions: options,
+ $editTextArea,
+ $editMultiValTextArea
+ });
+
+ leafletMap({
+ configService,
+ localeService,
+ eventEmitter: recordEditorEvents
+ }).initialize({
+ $container: $editorContainer,
+ parentOptions: options,
+ searchable: true,
+ tabOptions: {
+ position: 2
+ },
+ editable: true
+ });
+
+ ETHSeeker = thesaurusDatasource(recordEditorServices).initialize({
+ $container: $editorContainer,
+ parentOptions: options,
+ $editTextArea,
+ $editMultiValTextArea
+ });
+
+ recordEditorEvents.emit('recordSelection.changed', {
+ selection: getRecordSelection()
+ });
+ }
+
+ function _toggleGroupSelection() {
+ var groupIndex = 0;
+ _onSelectRecord(false, groupIndex);
+ }
+
+ function skipImage(evt, step) {
+ let cache = $('#EDIT_FILM2');
+ let first = $('.diapo.selected:first', cache);
+ let last = $('.diapo.selected:last', cache);
+ let sel = $('.diapo.selected', cache);
+
+ sel.removeClass('selected');
+
+ let i =
+ step === 1
+ ? parseInt(last.attr('pos'), 10) + 1
+ : parseInt(first.attr('pos'), 10) - 1;
+
+ if (i < 0) {
+ i = parseInt($('.diapo:last', cache).attr('pos'), 10);
+ } else if (i >= $('.diapo', cache).length) {
+ i = 0;
+ }
+
+ _onSelectRecord(evt, i);
+ }
+
+ function setRegDefault(n, record_id) {
+ options.newrepresent = record_id;
+
+ var src = $('#idEditDiapo_' + n).find('img.edit_IMGT').attr('src');
+ var style = $('#idEditDiapo_' + n).find('img.edit_IMGT').attr('style');
+
+ $('#EDIT_GRPDIAPO .edit_IMGT').attr('src', src).attr('style', style);
+ }
+
+ // // ---------------------------------------------------------------------------
+ // // on change de champ courant
+ // // ---------------------------------------------------------------------------
+
+ /**
+ * Set a field active by it's meta struct id
+ * Open it's editor
+ * @param evt
+ * @param fieldIndex
+ * @private
+ */
+ function onSelectField(evt, fieldIndex) {
+ $editTextArea.blur();
+ $editMultiValTextArea.blur();
+ $('.editDiaButtons', options.$container).hide();
+
+ $($editTextArea, $editMultiValTextArea).unbind('keyup.maxLength');
+ let fields = options.fieldCollection.getFields();
+ let field = options.fieldCollection.getFieldByIndex(fieldIndex);
+
+ if (fieldIndex >= 0) {
+ // @TODO field edition area should be hooked by plugins
+
+ if (fields === undefined || fields.length === 0) {
+ return;
+ }
+
+ if (field !== undefined) {
+ let name = field.required
+ ? field.label +
+ ' * '
+ : field.label;
+ $('#idFieldNameEdit', options.$container).html(name);
+
+ let suggestedValuesCollection = options.recordCollection.getFieldSuggestedValues(); //{};
+
+ if (!_.isEmpty(suggestedValuesCollection[fieldIndex])) {
+ var selectElement = $('' + localeService.t("suggested_values") + ' ');
+ var selectIdValue = "idSelectSuggestedValues_" + fieldIndex;
+ selectElement.attr('id', selectIdValue);
+
+ $.each(suggestedValuesCollection[fieldIndex], function (key, value) {
+ var optionElement = $(" ");
+ optionElement.attr("value", key);
+ optionElement.text(key);
+ selectElement.append(optionElement);
+ });
+
+ selectElement.on('change', function (e) {
+ if (field.multi === true) {
+ $editMultiValTextArea.val($(this).val());
+ $editMultiValTextArea.trigger('keyup.maxLength');
+ addValueInMultivaluedField({
+ value: $editMultiValTextArea.val()
+ });
+ } else {
+ if (appCommons.utilsModule.is_ctrl_key(e)) {
+ var t = $editTextArea.val();
+ $editTextArea.val(t + (t ? ' ; ' : '') + $(this).val());
+ } else {
+ $editTextArea.val($(this).val());
+ }
+ $editTextArea.trigger('keyup.maxLength');
+ options.textareaIsDirty = true;
+ if (field._status !== 2) {
+ validateFieldChanges(evt, 'ask_ok');
+ }
+ }
+ });
+
+ $('#idFieldSuggestedValues', options.$container).empty().append(selectElement);
+
+ $('#idFieldSuggestedValues', options.$container).css('visibility', 'visible');
+ $('.edit-zone-title', options.$container).css('height', 80);
+ $('#EDIT_EDIT', options.$container).css('top', 80);
+
+ } else {
+ $('#idFieldSuggestedValues', options.$container).css('visibility', 'hidden');
+ $('.edit-zone-title', options.$container).css('height', 45);
+ $('#EDIT_EDIT', options.$container).css('top', 45);
+ }
+
+ // attachFieldVocabularyAutocomplete
+ $($editTextArea, $editMultiValTextArea).autocomplete({
+ minLength: 2,
+ appendTo: '#idEditZone',
+ source: function (request, response) {
+ $.ajax({
+ url: `${url}prod/records/edit/vocabulary/${field.vocabularyControl}/`,
+ dataType: 'json',
+ data: {
+ sbas_id: options.sbas_id,
+ query: request.term
+ },
+ success: function (data) {
+ response(data.results);
+ }
+ });
+ },
+ select: function (event, ui) {
+ addValueInMultivaluedField({
+ value: ui.item.label,
+ vocabularyId: ui.item.id
+ });
+
+ return false;
+ }
+ });
+
+ // attachFieldLengthRestriction
+ if (field.maxLength > 0) {
+ $idExplain.html('');
+
+ $($editTextArea, $editMultiValTextArea)
+ .bind('keyup.maxLength', function (event) {
+ let $this = $(event.currentTarget);
+ var remaining = Math.max(
+ field.maxLength - $(this).val().length,
+ 0
+ );
+ $idExplain.html(`
+
+ Caracteres restants : ${remaining}
+ `);
+ $(
+ '.metadatas_restrictionsTips',
+ $idExplain
+ ).tooltip();
+ })
+ .trigger('keyup.maxLength');
+ } else {
+ $idExplain.html('');
+ }
+
+ if (!field.multi) {
+ // champ monovalue : textarea
+ $('.editDiaButtons', options.$container).hide();
+
+ if (field.type === 'date') {
+ $editTextArea.css('height', '16px');
+ $('#idEditDateZone', options.$container).show();
+ } else {
+ $('#idEditDateZone', options.$container).hide();
+ $editTextArea.css('height', '100%');
+ }
+
+ $ztextStatus.hide();
+ $('#ZTextMultiValued', options.$container).hide();
+ $editMonoValTextArea.show();
+
+ if (field._status === 2) {
+ // heterogene
+ $editTextArea.val((options.fieldLastValue = ''));
+ $editTextArea.addClass('hetero');
+ $('#idDivButtons', options.$container).show(); // valeurs h�t�rog�nes : les 3 boutons remplacer/ajouter/annuler
+ } else {
+ // homogene
+ $editTextArea.val(
+ (options.fieldLastValue = field._value)
+ );
+ $editTextArea.removeClass('hetero');
+
+ $('#idDivButtons', options.$container).hide(); // valeurs homog�nes
+ if (field.type === 'date') {
+ let v = field._value.split(' ');
+ let d = v[0].split('/');
+ let dateObj = new Date();
+ if (d.length === 3) {
+ dateObj.setYear(d[0]);
+ dateObj.setMonth(d[1] - 1);
+ dateObj.setDate(d[2]);
+ }
+
+ if (
+ $('#idEditDateZone', options.$container).data(
+ 'ui-datepicker'
+ )
+ ) {
+ $(
+ '#idEditDateZone',
+ options.$container
+ ).datepicker('setDate', dateObj);
+ }
+ }
+ }
+ options.textareaIsDirty = false;
+
+ $('#idEditZone', options.$container).show();
+
+ $editTextArea.trigger('keyup.maxLength');
+
+ self.setTimeout(() => $editTextArea.focus(), 50);
+ } else {
+ // champ multivalue : liste
+ $ztextStatus.hide();
+ $editMonoValTextArea.hide();
+ $('#ZTextMultiValued', options.$container).show();
+
+ $('#idDivButtons', options.$container).hide(); // valeurs homogenes
+
+ _updateCurrentMval(fieldIndex);
+
+ $editMultiValTextArea.val('');
+ $('#idEditZone', options.$container).show();
+
+ $editMultiValTextArea.trigger('keyup.maxLength');
+
+ self.setTimeout(() => $editMultiValTextArea.focus(), 50);
+
+ // reveal_mval();
+ }
+ }
+ } else {
+ // pas de champ, masquer la zone du textarea
+ $('#idEditZone', options.$container).hide();
+ $('.editDiaButtons', options.$container).hide();
+ }
+ setActiveField(fieldIndex);
+ }
+
+ function refreshFields(evt) {
+ $('.editDiaButtons', options.$container).hide();
+
+ // initialize values:
+ let initializedStatus = options.statusCollection.fillWithRecordValues(
+ options.recordCollection.getRecords()
+ );
+
+ // tous les statusbits de la base
+ for (let statusIndex in initializedStatus) {
+ var ck0 = $('#idCheckboxStatbit0_' + statusIndex);
+ var ck1 = $('#idCheckboxStatbit1_' + statusIndex);
+
+ switch (initializedStatus[statusIndex]._value) {
+ case '0':
+ case 0:
+ ck0
+ .removeClass('gui_ckbox_0 gui_ckbox_2')
+ .addClass('gui_ckbox_1');
+ ck1
+ .removeClass('gui_ckbox_1 gui_ckbox_2')
+ .addClass('gui_ckbox_0');
+ break;
+ case '1':
+ case 1:
+ ck0
+ .removeClass('gui_ckbox_1 gui_ckbox_2')
+ .addClass('gui_ckbox_0');
+ ck1
+ .removeClass('gui_ckbox_0 gui_ckbox_2')
+ .addClass('gui_ckbox_1');
+ break;
+ case '2':
+ ck0
+ .removeClass('gui_ckbox_0 gui_ckbox_1')
+ .addClass('gui_ckbox_2');
+ ck1
+ .removeClass('gui_ckbox_0 gui_ckbox_1')
+ .addClass('gui_ckbox_2');
+ break;
+ default:
+ }
+ }
+
+ var nostatus = $('.diapo.selected.nostatus', options.$container).length;
+ var status_box = $('#ZTextStatus');
+ $('.nostatus, .somestatus, .displaystatus', status_box).hide();
+
+ if (nostatus === 0) {
+ $('.displaystatus', status_box).show();
+ } else {
+ var yesstatus = $('.diapo.selected', options.$container).length;
+ if (nostatus === yesstatus) {
+ $('.nostatus', status_box).show();
+ } else {
+ $('.somestatus, .displaystatus', status_box).show();
+ }
+ }
+
+ populateFields();
+ let fieldIndex = options.fieldCollection.getActiveFieldIndex();
+ if (fieldIndex === -1) {
+ enableStatusField(evt);
+ } else {
+ onSelectField(evt, fieldIndex);
+ }
+ }
+
+ /**
+ * Populate all fields values from [1-n] records data
+ */
+ function populateFields() {
+ let records = options.recordCollection.getRecords();
+ let fields = options.fieldCollection.getFields();
+ // tous les champs de la base
+ for (let f in fields) {
+ let currentField = options.fieldCollection.getFieldByIndex(f);
+
+ currentField._status = 0; // val unknown
+ for (let i in records) {
+ let currentRecord = options.recordCollection.getRecordByIndex(
+ i
+ );
+ if (!currentRecord._selected) {
+ continue;
+ }
+
+ let v = '';
+ if (!currentRecord.fields[f].isEmpty()) {
+ // le champ existe dans la fiche
+ if (currentField.multi) {
+ // champ multi : on compare la concat des valeurs
+ v = currentRecord.fields[f].getSerializedValues();
+ } else {
+ v = currentRecord.fields[f].getValue().getValue();
+ }
+ }
+
+ if (currentField._status === 0) {
+ currentField._value = v;
+ currentField._status = 1;
+ } else if (
+ currentField._status === 1 &&
+ currentField._value !== v
+ ) {
+ currentField._value = '*****';
+ currentField._status = 2;
+ break; // plus la peine de verifier le champ sur les autres records
+ }
+ }
+ var o = document.getElementById('idEditField_' + f);
+
+ if (o) {
+ // mixed
+ if (currentField._status === 2) {
+ o.innerHTML = "xxxxx ";
+ } else {
+ var v = currentField._value;
+ v = v instanceof Array ? v.join(';') : v;
+ o.innerHTML = cleanTags(v).replace(
+ /\n/gm,
+ "¶ "
+ );
+ }
+ }
+ options.fieldCollection.updateField(f, currentField);
+ }
+ }
+
+ /**
+ * enable pseudo-field "status"
+ * @param evt
+ */
+ function enableStatusField(evt) {
+ $('.editDiaButtons', options.$container).hide();
+
+ $editTextArea.blur();
+ $editMultiValTextArea.blur();
+
+ $('#idFieldNameEdit', options.$container).html('[STATUS]');
+ $idExplain.html(' ');
+
+ $('#ZTextMultiValued', options.$container).hide();
+ $editMonoValTextArea.hide();
+ $ztextStatus.show();
+
+ $('#idEditZone', options.$container).show();
+
+ document.getElementById('editFakefocus').focus();
+ // options.curField = -1;
+ setActiveField(-1);
+ }
+
+ function _updateCurrentMval(metaStructId, highlightValue, vocabularyId) {
+ // on compare toutes les valeurs de chaque fiche selectionnee
+ options.T_mval = []; // tab des mots, pour trier
+ var a = []; // key : mot ; val : nbr d'occurences distinctes
+ var n = 0; // le nbr de records selectionnes
+
+ let records = options.recordCollection.getRecords();
+ for (let r in records) {
+ let currentRecord = options.recordCollection.getRecordByIndex(r);
+ if (!currentRecord._selected) {
+ continue;
+ }
+
+ currentRecord.fields[metaStructId].sort(_sortCompareMetas);
+
+ var values = currentRecord.fields[metaStructId].getValues();
+
+ for (let v in values) {
+ let word = values[v].getValue();
+ let key = values[v].getVocabularyId() + '%' + word;
+
+ if (typeof a[key] === 'undefined') {
+ a[key] = {
+ n: 0,
+ f: []
+ }; // n:nbr d'occurences DISTINCTES du mot ; f:flag presence mot dans r
+ options.T_mval.push(values[v]);
+ }
+
+ if (!a[key].f[r]) {
+ a[key].n++; // premiere apparition du mot dans le record r
+ }
+ a[key].f[r] = true; // on ne recomptera pas le mot s'il apparait a nouveau dans le meme record
+ }
+
+ n++;
+ }
+
+ options.T_mval.sort(_sortCompareMetas);
+
+ var t = '';
+ // pour lire le tableau 'a' dans l'ordre trie par 'editor.T_mval'
+ for (let i in options.T_mval) {
+ let value = options.T_mval[i];
+ let word = value.getValue();
+ let key = value.getVocabularyId() + '%' + word;
+
+ let extra = value.getVocabularyId()
+ ? ' '
+ : '';
+
+ if (i > 0) {
+ if (
+ value.getVocabularyId() !== null &&
+ options.T_mval[i - 1].getVocabularyId() ===
+ value.getVocabularyId()
+ ) {
+ continue;
+ }
+ if (
+ value.getVocabularyId() === null &&
+ options.T_mval[i - 1].getVocabularyId() === null
+ ) {
+ if (options.T_mval[i - 1].getValue() === value.getValue()) {
+ continue; // on n'accepte pas les doublons
+ }
+ }
+ }
+
+ t +=
+ '' +
+ '
' +
+ extra +
+ '' +
+ $('
').text(word).html() +
+ " " +
+ ' ' +
+ ' ' +
+ '
' +
+ '
';
+ }
+
+ $('#ZTextMultiValued_values', options.$container).html(t);
+
+ $('#ZTextMultiValued_values .add_all', options.$container)
+ .unbind('click')
+ .bind('click', function () {
+ let container = $(this).closest('div');
+
+ let span = $('span.value', container);
+
+ let value = span.text();
+ let vocab_id = span.attr('vocabid');
+
+ addValueInMultivaluedField({
+ value: value,
+ vocabularyId: vocab_id
+ });
+ populateFields();
+ return false;
+ });
+ $('#ZTextMultiValued_values .remove_all', options.$container)
+ .unbind('click')
+ .bind('click', function () {
+ let container = $(this).closest('div');
+
+ let span = $('span.value', container);
+
+ let value = span.text();
+ let vocab_id = span.attr('vocabid');
+
+ removeValueFromMultivaluedField(value, vocab_id);
+ populateFields();
+ return false;
+ });
+
+ populateFields();
+ }
+
+ // ---------------------------------------------------------------------------------------------------------
+ // en mode textarea, on clique sur ok, cancel ou fusion
+ // appele egalement quand on essaye de changer de champ ou d'image : si ret=false on interdit le changement
+ // ---------------------------------------------------------------------------------------------------------
+ function validateFieldChanges(evt, action) {
+ // action : 'ok', 'fusion' ou 'cancel'
+ if (options.fieldCollection.getActiveFieldIndex() === '?') {
+ return true;
+ }
+ let fieldIndex = options.fieldCollection.getActiveFieldIndex();
+ let currentField = options.fieldCollection.getActiveField();
+ let records = options.recordCollection.getRecords();
+
+ if (action === 'cancel') {
+ // on restore le contenu du champ
+ $editTextArea.val(options.fieldLastValue);
+ $editTextArea.trigger('keyup.maxLength');
+ options.textareaIsDirty = false;
+ return true;
+ }
+
+ if (
+ action === 'ask_ok' &&
+ options.textareaIsDirty &&
+ currentField._status === 2
+ ) {
+ alert(localeService.t('edit_hetero'));
+ return false;
+ }
+ let o = document.getElementById('idEditField_' + fieldIndex);
+ if (o !== undefined) {
+ let t = $editTextArea.val();
+ for (let recordIndex in records) {
+ let record = options.recordCollection.getRecordByIndex(
+ recordIndex
+ );
+ if (!record._selected) {
+ continue; // on ne modifie pas les fiches non selectionnees
+ }
+
+ if (action === 'ok' || action === 'ask_ok') {
+ options.recordCollection.addRecordFieldValue(
+ recordIndex,
+ fieldIndex,
+ {
+ value: t,
+ merge: false,
+ vocabularyId: null
+ }
+ );
+ } else if (action === 'fusion' || action === 'ask_fusion') {
+ options.recordCollection.addRecordFieldValue(
+ recordIndex,
+ fieldIndex,
+ {
+ value: t,
+ merge: true,
+ vocabularyId: null
+ }
+ );
+ }
+
+ checkRequiredFields(recordIndex, fieldIndex);
+ }
+ }
+
+ populateFields();
+
+ options.textareaIsDirty = false;
+
+ onSelectField(evt, fieldIndex);
+ return true;
+ }
+
+ // ---------------------------------------------------------------------------
+ // on a clique sur une checkbox de status
+ // ---------------------------------------------------------------------------
+ function toggleStatus(evt, bit, val) {
+ let ck0 = $('#idCheckboxStatbit0_' + bit);
+ let ck1 = $('#idCheckboxStatbit1_' + bit);
+
+ switch (val) {
+ case 0:
+ ck0.attr('class', 'gui_ckbox_1');
+ ck1.attr('class', 'gui_ckbox_0');
+ break;
+ case 1:
+ ck0.attr('class', 'gui_ckbox_0');
+ ck1.attr('class', 'gui_ckbox_1');
+ break;
+ default:
+ }
+ options.recordCollection.setStatus(bit, val);
+ }
+
+ // ---------------------------------------------------------------------------
+ // on a clique sur une thumbnail
+ // ---------------------------------------------------------------------------
+ function _onSelectRecord(event, recordIndex) {
+ let fieldIndex = options.fieldCollection.getActiveFieldIndex();
+ if (fieldIndex >= 0) {
+ if (
+ options.textareaIsDirty &&
+ validateFieldChanges(event, 'ask_ok') === false
+ ) {
+ return;
+ }
+ }
+
+ let records = options.recordCollection.getRecords();
+ let record = options.recordCollection.getRecordByIndex(recordIndex);
+
+ // guideline : si on mousedown sur une selection, c'est qu'on risque de draguer, donc on ne desectionne pas
+ if (event && event.type === 'mousedown' && record._selected) {
+ return;
+ }
+
+ if (
+ event &&
+ appCommons.utilsModule.is_shift_key(event) &&
+ options.lastClickId !== null
+ ) {
+ // shift donc on sel du editor.lastClickId a ici
+ let pos_from = options.T_pos[options.lastClickId];
+ let pos_to = options.T_pos[recordIndex];
+ if (pos_from > pos_to) {
+ let tmp = pos_from;
+ pos_from = pos_to;
+ pos_to = tmp;
+ }
+
+ for (let pos = pos_from; pos <= pos_to; pos++) {
+ let id = options.T_id[pos];
+ let record = options.recordCollection.getRecordByIndex(id);
+ // toutes les fiches selectionnees
+ if (!record._selected) {
+ record._selected = true;
+ $('#idEditDiapo_' + id, options.$container).addClass(
+ 'selected'
+ );
+ }
+ }
+ } else {
+ if (!event || !appCommons.utilsModule.is_ctrl_key(event)) {
+ // on deselectionne tout avant
+
+ for (let recordIndex in records) {
+ let record = options.recordCollection.getRecordByIndex(
+ recordIndex
+ );
+ // toutes les fiches selectionnees
+ if (record._selected) {
+ record._selected = false;
+ $(
+ '#idEditDiapo_' + recordIndex,
+ options.$container
+ ).removeClass('selected');
+ }
+ }
+ }
+ if (recordIndex >= 0) {
+ record._selected = !record._selected;
+ if (record._selected) {
+ $(
+ '#idEditDiapo_' + recordIndex,
+ options.$container
+ ).addClass('selected');
+ } else {
+ $(
+ '#idEditDiapo_' + recordIndex,
+ options.$container
+ ).removeClass('selected');
+ }
+ }
+ }
+
+ let selection = [];
+ let allRecords = $('#EDIT_FILM2 .diapo');
+ let selected = $('#EDIT_FILM2 .diapo.selected');
+ if (selected.length === 1) {
+ let r = selected.attr('id').split('_').pop();
+ recordEditorEvents.emit('recordEditor.onSelectRecord', {
+ recordIndex: r
+ });
+ selection.push(r);
+ } else {
+ for (let pos = 0; pos < selected.length; pos++) {
+ let $record = $(selected[pos]);
+ selection.push($record.attr('id').split('_').pop());
+ }
+ recordEditorEvents.emit('recordSelection.changed', {
+ selection: getRecordSelection()
+ });
+ }
+ /**trigger select all checkbox**/
+ if (selected.length < allRecords.length) {
+ $("#select-all-diapo").removeAttr("checked");
+ }else{
+ if (selected.length == allRecords.length) {
+ $("#select-all-diapo").trigger("click");
+ }
+
+ };
+ options.lastClickId = recordIndex;
+ refreshFields(event);
+ }
+
+ function getRecordSelection() {
+ let selection = [];
+ let selected = $('#EDIT_FILM2 .diapo.selected');
+ for (let pos = 0; pos < selected.length; pos++) {
+ let $record = $(selected[pos]);
+ selection.push($record.attr('id').split('_').pop());
+ }
+ return selection;
+ }
+
+ // ----------------------------------------------------------------------------------
+ // on a clique sur le 'ok' general : save
+ // ----------------------------------------------------------------------------------
+ function submitChanges(fnParams) {
+ let { event } = fnParams;
+
+ if (
+ options.textareaIsDirty &&
+ validateFieldChanges(event, 'ask_ok') === false
+ ) {
+ return false;
+ }
+
+ let required_fields = checkRequiredFields();
+
+ if (required_fields) {
+ alert(localeService.t('some_required_fields'));
+ return false;
+ }
+
+ $('#EDIT_ALL', options.$container).hide();
+ $('#EDIT_WORKING', options.$container).show();
+
+ let params = {
+ mds: options.recordCollection.gatherUpdatedRecords(),
+ sbid: options.sbas_id,
+ act: 'WORK',
+ lst: $('#edit_lst').val(),
+ act_option: 'SAVE' + options.what,
+ ssel: options.ssel
+ };
+ if (options.newrepresent !== false) {
+ params.newrepresent = options.newrepresent;
+ }
+
+ $.ajax({
+ url: `${url}prod/records/edit/apply/`,
+ data: params,
+ type: 'POST',
+ success: function (data) {
+ if (options.what === 'GRP' || options.what === 'SSEL') {
+ recordEditorEvents.emit('workzone.refresh', {
+ basketId: 'current'
+ });
+ }
+ closeModal();
+ // $('#Edit_copyPreset_dlg').remove();
+ // $('#EDITWINDOW').hide();
+ // $editorContainer.find('*').addBack().off();
+ recordEditorEvents.emit('preview.doReload');
+ return;
+ }
+ });
+ }
+
+ function cancelChanges(params) {
+ let { event } = params;
+ let fieldIndex = options.fieldCollection.getActiveFieldIndex();
+
+ let dirty = false;
+
+ event.cancelBubble = true;
+ if (event.stopPropagation) {
+ event.stopPropagation();
+ }
+
+ if (fieldIndex >= 0) {
+ if (
+ options.textareaIsDirty &&
+ validateFieldChanges(event, 'ask_ok') === false
+ ) {
+ return;
+ }
+ }
+
+ dirty = options.recordCollection.isDirty();
+ if (!dirty || confirm(localeService.t('confirm_abandon'))) {
+ closeModal();
+ }
+ }
+
+ const closeModal = () => {
+ $('#Edit_copyPreset_dlg').remove();
+ $('#idFrameE .ww_content', options.$container).empty();
+
+ $toolsTabs.hide().tabs('destroy');
+ $container.find('*').addBack().off();
+ $container.fadeOut().empty();
+ options = {};
+ recordEditorEvents.dispose();
+ };
+
+ function setActiveField(fieldIndex) {
+ // let metaStructId = parseInt(options.curField, 10);
+ options.fieldCollection.setActiveField(fieldIndex);
+ fieldIndex =
+ isNaN(fieldIndex) || fieldIndex < 0 ? 'status' : fieldIndex;
+
+ $('#divS div.active, #divS div.hover').removeClass('active hover');
+ $('#EditFieldBox_' + fieldIndex).addClass('active');
+
+ let cont = $('#divS');
+ let calc =
+ $('#EditFieldBox_' + fieldIndex).offset().top - cont.offset().top; // hauteur relative par rapport au visible
+
+ if (calc > cont.height() || calc < 0) {
+ cont.scrollTop(calc + cont.scrollTop());
+ }
+ }
+
+ function _sortCompareMetas(a, b) {
+ if (typeof a !== 'object') {
+ return -1;
+ }
+ if (typeof b !== 'object') {
+ return 1;
+ }
+ let na = a.getValue().toUpperCase();
+ let nb = b.getValue().toUpperCase();
+ if (na === nb) {
+ return 0;
+ }
+ return na < nb ? -1 : 1;
+ }
+
+ function checkRequiredFields(inputRecordIndex, inputFieldIndex) {
+ let fieldCollection = options.fieldCollection.getFields();
+ let recordCollection = options.recordCollection.getRecords();
+ let requiredFields = false;
+
+ if (typeof inputRecordIndex === 'undefined') {
+ inputRecordIndex = false;
+ }
+ if (typeof inputFieldIndex === 'undefined') {
+ inputFieldIndex = false;
+ }
+
+ for (let fieldIndex in fieldCollection) {
+ let currentField = options.fieldCollection.getFieldByIndex(
+ fieldIndex
+ );
+ if (inputFieldIndex !== false && fieldIndex !== inputFieldIndex) {
+ continue;
+ }
+
+ if (!currentField.required) {
+ continue;
+ }
+
+ for (let recordIndex in recordCollection) {
+ let currentRecord = options.recordCollection.getRecordByIndex(
+ recordIndex
+ );
+ if (
+ inputRecordIndex !== false &&
+ recordIndex !== inputRecordIndex
+ ) {
+ continue;
+ }
+
+ let elem = $('#idEditDiapo_' + recordIndex + ' .require_alert');
+
+ elem.hide();
+
+ if (!currentRecord.fields[fieldIndex]) {
+ elem.show();
+ requiredFields = true;
+ } else {
+ let checkRequired = '';
+
+ // le champ existe dans la fiche
+ if (currentField.multi) {
+ // champ multi : on compare la concat des valeurs
+ checkRequired = $.trim(
+ currentRecord.fields[
+ fieldIndex
+ ].getSerializedValues()
+ );
+ } else if (currentRecord.fields[fieldIndex].getValue()) {
+ checkRequired = $.trim(
+ currentRecord.fields[fieldIndex]
+ .getValue()
+ .getValue()
+ );
+ }
+
+ if (checkRequired === '') {
+ elem.show();
+ requiredFields = true;
+ }
+ }
+ }
+ }
+ return requiredFields;
+ }
+
+ function _edit_select_all() {
+ let records = options.recordCollection.getRecords();
+ $('#EDIT_FILM2 .diapo', options.$container).addClass('selected');
+
+ for (let i in records) {
+ records[i]._selected = true;
+ }
+
+ options.lastClickId = 1;
+
+ refreshFields(null); // null : no evt available
+ }
+
+ function _edit_select_all_right(check) {
+ let records = options.recordCollection.getRecords();
+ console.log(records);
+ if (check == true) {
+ $('#EDIT_FILM2 .diapo', options.$container).addClass('selected');
+ } else {
+ $('#EDIT_FILM2 .diapo', options.$container).removeClass('selected');
+ }
+ for (let i in records) {
+ if (records[i].type !== "unknown") {
+ records[i]._selected = check;
+ }
+ }
+ options.lastClickId = 0;
+
+ refreshFields(null); // null : no evt available
+ }
+
+
+ // ---------------------------------------------------------------------------
+ // highlight la valeur en cours de saisie dans la liste des multi-valeurs
+ // appele par le onkeyup
+ // ---------------------------------------------------------------------------
+ function _reveal_mval(value, vocabularyId) {
+ let records = options.recordCollection.getRecords();
+ let fieldIndex = options.fieldCollection.getActiveFieldIndex();
+ let currentField = options.fieldCollection.getActiveField();
+ let talt;
+
+ if (typeof vocabularyId === 'undefined') {
+ vocabularyId = null;
+ }
+
+ /*if (currentField.tbranch) {
+ if (value !== '') {
+ appEvents.emit('recordEditor.userInputValue', {
+ context: {
+ event: false,
+ currentField,
+ },
+ value
+ });
+ // ETHSeeker.search(value);
+ }
+ }*/
+ onUserInputComplete(false, value, currentField);
+
+ if (value !== '') {
+ // let nsel = 0;
+ for (let recordIndex in records) {
+ let currentRecord = options.recordCollection.getRecordByIndex(
+ recordIndex
+ );
+ if (
+ currentRecord.fields[fieldIndex].hasValue(
+ value,
+ vocabularyId
+ )
+ ) {
+ $('#idEditDiaButtonsP_' + recordIndex).hide();
+ talt = sprintf(localeService.t('editDelSimple'), value);
+ $('#idEditDiaButtonsM_' + recordIndex)
+ .show()
+ .attr('alt', talt)
+ .attr('Title', talt)
+ .unbind('click')
+ .bind('click', function () {
+ let indice = $(this).attr('id').split('_').pop();
+ _edit_diabutton(indice, 'del', value, vocabularyId);
+ });
+ } else {
+ $('#idEditDiaButtonsM_' + recordIndex).hide();
+ $('#idEditDiaButtonsP_' + recordIndex).show();
+ talt = sprintf(localeService.t('editAddSimple'), value);
+ $('#idEditDiaButtonsP_' + recordIndex)
+ .show()
+ .attr('alt', talt)
+ .attr('Title', talt)
+ .unbind('click')
+ .bind('click', function () {
+ let indice = $(this).attr('id').split('_').pop();
+ _edit_diabutton(indice, 'add', value, vocabularyId);
+ });
+ }
+ }
+ $('.editDiaButtons', options.$container).show();
+ }
+
+ $editMultiValTextArea.trigger('focus');
+ return true;
+ }
+
+ /**
+ * Remove a value from a multivalued field
+ * @param value
+ * @param vocabularyId
+ */
+ function removeValueFromMultivaluedField(value, vocabularyId) {
+ let records = options.recordCollection.getRecords();
+ let fieldIndex = options.fieldCollection.getActiveFieldIndex();
+
+ for (let recordIndex in records) {
+ let currentRecord = options.recordCollection.getRecordByIndex(
+ recordIndex
+ );
+
+ if (!currentRecord._selected) {
+ continue;
+ }
+ options.recordCollection.removeRecordFieldValue(
+ recordIndex,
+ fieldIndex,
+ {
+ value,
+ vocabularyId
+ }
+ );
+ }
+ refreshFields(null);
+ }
+
+ /**
+ * Add a value into a multivalued field
+ * @param params
+ */
+ function addValueInMultivaluedField(params) {
+ let { value, vocabularyId } = params;
+ let records = options.recordCollection.getRecords();
+ let fieldIndex = options.fieldCollection.getActiveFieldIndex();
+
+ vocabularyId = vocabularyId === undefined ? null : vocabularyId;
+
+ for (let recordIndex in records) {
+ let currentRecord = options.recordCollection.getRecordByIndex(
+ recordIndex
+ );
+
+ if (!currentRecord._selected) {
+ continue;
+ }
+
+ options.recordCollection.addRecordFieldValue(
+ recordIndex,
+ fieldIndex,
+ {
+ value,
+ merge: false,
+ vocabularyId
+ }
+ );
+ }
+ refreshFields(null);
+ }
+
+ // ---------------------------------------------------------------------------
+ // on a clique sur une des multi-valeurs dans la liste
+ // ---------------------------------------------------------------------------
+ function _editMultivaluedField(mvaldiv, ival) {
+ $(mvaldiv).parent().find('.hilighted').removeClass('hilighted');
+ $(mvaldiv).addClass('hilighted');
+ _reveal_mval(
+ options.T_mval[ival].getValue(),
+ options.T_mval[ival].getVocabularyId()
+ );
+ }
+
+ function _edit_diabutton(recordIndex, act, value, vocabularyId) {
+ let fieldIndex = options.fieldCollection.getActiveFieldIndex();
+ if (act === 'del') {
+ options.recordCollection.removeRecordFieldValue(
+ recordIndex,
+ fieldIndex,
+ {
+ value,
+ vocabularyId
+ }
+ );
+ }
+
+ if (act === 'add') {
+ options.recordCollection.addRecordFieldValue(
+ recordIndex,
+ fieldIndex,
+ {
+ value,
+ merge: false,
+ vocabularyId
+ }
+ );
+ }
+ _updateCurrentMval(fieldIndex, value, vocabularyId);
+ _reveal_mval(value, vocabularyId);
+ }
+
+ // ---------------------------------------------------------------------------
+ // change de champ (avec les fleches autour du nom champ)
+ // ---------------------------------------------------------------------------
+ // edit_chgFld
+ function fieldNavigate(evt, dir) {
+ let current_field = $('#divS .edit_field.active');
+ if (current_field.length === 0) {
+ current_field = $('#divS .edit_field:first');
+ current_field.trigger('click');
+ } else {
+ if (dir >= 0) {
+ current_field.next().trigger('click');
+ } else {
+ current_field.prev().trigger('click');
+ }
+ }
+ }
+
+ const _onTextareaKeyDown = event => {
+ let currentField = options.fieldCollection.getActiveField();
+ let $el = $(event.currentTarget);
+ let cancelKey = false;
+
+ switch (event.keyCode) {
+ case 13:
+ case 10:
+ if (currentField.type === 'date') {
+ cancelKey = true;
+ }
+ break;
+ default:
+ }
+
+ if (cancelKey) {
+ event.cancelBubble = true;
+ if (event.stopPropagation) {
+ event.stopPropagation();
+ }
+ return false;
+ }
+ return true;
+ };
+
+ // ----------------------------------------------------------------------------------------------
+ // des events sur le textarea pour tracker la selection (chercher dans le thesaurus...)
+ // ----------------------------------------------------------------------------------------------
+ const _onTextareaMouseDown = evt => {
+ evt.cancelBubble = true;
+ return true;
+ };
+
+ // mouse up textarea
+ const _onTextareaMouseUp = (event, obj) => {
+ let currentField = options.fieldCollection.getActiveField();
+ let $el = $(event.currentTarget);
+ let value = $el.val();
+
+ onUserInputComplete(event, value, currentField);
+ return true;
+ };
+
+ // key up textarea
+ const _onTextareaKeyUp = (event, obj) => {
+ let currentField = options.fieldCollection.getActiveField();
+ let $el = $(event.currentTarget);
+ let cancelKey = false;
+ let o;
+ switch (event.keyCode) {
+ case 27: // esc : on restore la valeur avant editing
+ // $("#btn_cancel", editor.$container).parent().css("backgroundColor", "#000000");
+ validateFieldChanges(event, 'cancel');
+ // self.setTimeout("document.getElementById('btn_cancel').parentNode.style.backgroundColor = '';", 100);
+ cancelKey = true;
+ break;
+ default:
+ }
+
+ if (cancelKey) {
+ event.cancelBubble = true;
+ if (event.stopPropagation) {
+ event.stopPropagation();
+ }
+ return false;
+ }
+ if (
+ !options.textareaIsDirty &&
+ $editTextArea.val() !== options.fieldLastValue
+ ) {
+ options.textareaIsDirty = true;
+ }
+
+ let searchValue = $el.val(); // obj.value;
+
+ onUserInputComplete(event, searchValue, currentField);
+ return true;
+ };
+
+ /**
+ * debounceable method
+ * @param event
+ * @param value
+ * @param field
+ */
+ let onUserInputComplete = (event, value, field) => {
+ if (value !== '') {
+ recordEditorEvents.emit('recordEditor.userInputValue', {
+ event,
+ value,
+ field
+ });
+ }
+ };
+
+ /**
+ * add field value from a datasource
+ * if the field is not specified, use active one
+ * @param params
+ */
+ const addValueFromDataSource = params => {
+ let { value, field } = params;
+
+ if (field === undefined || field === null) {
+ field = options.fieldCollection.getActiveField();
+ }
+
+ if (field.multi) {
+ $editMultiValTextArea.val(value);
+ $editMultiValTextArea.trigger('keyup.maxLength');
+ recordEditorEvents.emit('recordEditor.addMultivaluedField', {
+ value: $editMultiValTextArea.val()
+ });
+ } else {
+ $editTextArea.val(value);
+ $editTextArea.trigger('keyup.maxLength');
+ options.textareaIsDirty = true;
+ }
+ };
+
+ /**
+ * Bulk field update
+ * @param params
+ */
+ const addPresetValuesFromDataSource = params => {
+ let { data } = params;
+ let mode = params.mode || '';
+ let preselectedRecord = params.recordIndex || false;
+
+ let records = options.recordCollection.getRecords();
+ let fields = options.fieldCollection.getFields();
+
+ for (let fieldIndex in fields) {
+ let field = options.fieldCollection.getFieldByIndex(fieldIndex);
+ field.preset = null;
+ if (typeof data.fields[field.name] !== 'undefined') {
+ field.preset = data.fields[field.name];
+ }
+ options.fieldCollection.updateField(fieldIndex, field);
+ }
+
+ // apply new preset value on each record's fields
+ for (let recordIndex in records) {
+ let record = options.recordCollection.getRecordByIndex(recordIndex);
+ if (!record._selected) {
+ continue;
+ }
+
+ for (let fieldIndex in fields) {
+ let field = options.fieldCollection.getFieldByIndex(fieldIndex);
+ if (field.preset !== null) {
+ for (let val in field.preset) {
+ if (preselectedRecord !== false) {
+ if (preselectedRecord !== recordIndex) {
+ // only update preselected record
+ continue;
+ }
+ }
+ // don't update filled fields in emptyOnly mode:
+ if (
+ mode === 'emptyOnly' &&
+ field._value !== '' &&
+ !record.fields[fieldIndex].isDirty()
+ ) {
+ continue;
+ }
+ options.recordCollection.addRecordFieldValue(
+ recordIndex,
+ fieldIndex,
+ {
+ value: field.preset[val].trim(),
+ merge: false,
+ vocabularyId: null
+ }
+ );
+ }
+ }
+ }
+ }
+ recordEditorEvents.emit('recordEditor.onUpdateFields');
+ };
+
+ /**
+ * get selected records field values
+ * @returns {Array}
+ */
+ const loadSelectedRecords = () => {
+ let records = options.recordCollection.getRecords();
+ let fields = options.fieldCollection.getFields();
+ let selectedRecords = [];
+ for (let recordIndex in records) {
+ let recordFieldValue = {};
+ let record = options.recordCollection.getRecordByIndex(recordIndex);
+ if (!record._selected) {
+ continue;
+ }
+ for (var _recordIndex in options.recordConfig.records) {
+ if (options.recordConfig.records[_recordIndex].id === record.rid) {
+ recordFieldValue["technicalInfo"] = options.recordConfig.records[_recordIndex].technicalInfo;
+ }
+ }
+ for (let fieldIndex in fields) {
+ let field = options.fieldCollection.getFieldByIndex(fieldIndex);
+ let value = null;
+
+ // retrieve original record value (of field)
+ if (field.multi) {
+ value = record.fields[fieldIndex].getSerializedValues();
+ } else {
+ let fieldData = record.fields[fieldIndex].getValue();
+ if (fieldData !== null) {
+ if (fieldData.datas !== undefined) {
+ value = fieldData.datas.value;
+ }
+ }
+ }
+ recordFieldValue[field.name] = value;
+ }
+ selectedRecords.push(recordFieldValue);
+ }
+ return selectedRecords;
+ };
+
+ const appendTab = params => {
+ let { tabProperties, position } = params;
+ const $appendAfterTab = $(
+ `.tabs ul li:eq(${position - 1})`,
+ $container
+ );
+
+ const newTab = `${tabProperties.title} `;
+ $appendAfterTab.after(newTab);
+
+ const appendAfterTabContent = $(
+ `.tabs > div:eq(${position - 1})`,
+ $container
+ );
+ appendAfterTabContent.after(`
`);
+
+ try {
+ $toolsTabs.tabs('refresh');
+ } catch (e) {}
+
+ recordEditorEvents.emit('appendTab.complete', {
+ origParams: params,
+ selection: loadSelectedRecords()
+ });
+ };
+ const activateToolTab = tabId => {
+ $toolsTabs.tabs(
+ 'option',
+ 'active',
+ $toolsTabs.find(`#${tabId}`).index() - 1
+ );
+ };
+
+ return {
+ initialize
+ //onGlobalKeydown: onGlobalKeydown,
+ };
+};
+export default recordEditorService;
diff --git a/Phraseanet-production-client/src/components/record/recordEditor/layout.js b/Phraseanet-production-client/src/components/record/recordEditor/layout.js
new file mode 100644
index 0000000000..87734df689
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/recordEditor/layout.js
@@ -0,0 +1,176 @@
+import $ from 'jquery';
+import * as appCommons from './../../../phraseanet-common';
+
+const recordEditorLayout = services => {
+ const { configService, localeService, recordEditorEvents } = services;
+ let $container = null;
+ let parentOptions = {};
+
+ const initialize = options => {
+ let initWith = ({ $container, parentOptions } = options);
+ $(window).bind('resize', function () {
+ recordEditorEvents.emit('recordEditor.uiResize');
+ _setSizeLimits();
+ });
+
+ _hsplit1();
+ _vsplit2();
+ _vsplit1();
+
+ $('#EDIT_TOP', parentOptions.$container).resizable({
+ handles: 's',
+ minHeight: 100,
+ resize: function () {
+ _hsplit1();
+ recordEditorEvents.emit('recordEditor.uiResize');
+ },
+ stop: function () {
+ _hsplit1();
+ appCommons.userModule.setPref(
+ 'editing_top_box',
+ Math.floor(
+ $('#EDIT_TOP').height() * 100 / $('#EDIT_ALL').height()
+ )
+ );
+ _setSizeLimits();
+ }
+ });
+
+ $('#divS_wrapper', parentOptions.$container).resizable({
+ handles: 'e',
+ minWidth: 200,
+ resize: function () {
+ _vsplit1();
+ recordEditorEvents.emit('recordEditor.uiResize');
+ },
+ stop: function () {
+ appCommons.userModule.setPref(
+ 'editing_right_box',
+ Math.floor(
+ $('#divS').width() * 100 / $('#EDIT_MID_L').width()
+ )
+ );
+ _vsplit1();
+ _setSizeLimits();
+ }
+ });
+
+ $('#EDIT_MID_R')
+ .css(
+ 'left',
+ $('#EDIT_MID_L').position().left + $('#EDIT_MID_L').width() + 15
+ )
+ .resizable({
+ handles: 'w',
+ minWidth: 200,
+ resize: function () {
+ _vsplit2();
+ recordEditorEvents.emit('recordEditor.uiResize');
+ },
+ stop: function () {
+ appCommons.userModule.setPref(
+ 'editing_left_box',
+ Math.floor(
+ $('#EDIT_MID_R').width() *
+ 100 /
+ $('#EDIT_MID').width()
+ )
+ );
+ _vsplit2();
+ _setSizeLimits();
+ }
+ });
+
+ $('#EDIT_ZOOMSLIDER', parentOptions.$container).slider({
+ min: 60,
+ max: 300,
+ value: parentOptions.recordConfig.diapoSize,
+ slide: function (event, ui) {
+ var v = $(ui.value)[0];
+ $('#EDIT_FILM2 .diapo', parentOptions.$container)
+ .width(v)
+ .height(v);
+ },
+ change: function (event, ui) {
+ parentOptions.recordConfig.diapoSize = $(ui.value)[0];
+ appCommons.userModule.setPref(
+ 'editing_images_size',
+ parentOptions.recordConfig.diapoSize
+ );
+ }
+ });
+
+ _setSizeLimits();
+ };
+
+ function _setSizeLimits() {
+ if (!$('#EDITWINDOW').is(':visible')) {
+ return;
+ }
+
+ if ($('#EDIT_TOP').data('ui-resizable')) {
+ $('#EDIT_TOP').resizable(
+ 'option',
+ 'maxHeight',
+ $('#EDIT_ALL').height() -
+ $('#buttonEditing').height() -
+ 10 -
+ 160
+ );
+ }
+ if ($('#divS_wrapper').data('ui-resizable')) {
+ $('#divS_wrapper').resizable(
+ 'option',
+ 'maxWidth',
+ $('#EDIT_MID_L').width() - 270
+ );
+ }
+ if ($('#EDIT_MID_R').data('ui-resizable')) {
+ $('#EDIT_MID_R').resizable(
+ 'option',
+ 'maxWidth',
+ $('#EDIT_MID_R').width() + $('#idEditZone').width() - 240
+ );
+ }
+ }
+
+ function _hsplit1() {
+ let el = $('#EDIT_TOP');
+ if (el.length === 0) {
+ return;
+ }
+ let h = $(el).outerHeight();
+ $(el).height(h);
+ let t = $(el).offset().top + h;
+
+ $('#EDIT_MID', parentOptions.$container).css('top', t + 'px');
+ }
+
+ function _vsplit1() {
+ $('#divS_wrapper').height('auto');
+
+ let el = $('#divS_wrapper');
+ if (el.length === 0) {
+ return;
+ }
+ let a = $(el).width();
+ el.width(a);
+
+ $('#idEditZone', parentOptions.$container).css('left', a + 20);
+ }
+
+ function _vsplit2() {
+ let el = $('#EDIT_MID_R');
+ if (el.length === 0) {
+ return;
+ }
+ let a = $(el).width();
+ el.width(a);
+ let v = $('#EDIT_ALL').width() - a - 35;
+
+ $('#EDIT_MID_L', parentOptions.$container).width(v);
+ }
+
+ return { initialize };
+};
+export default recordEditorLayout;
diff --git a/Phraseanet-production-client/src/components/record/recordEditor/models/fieldCollection.js b/Phraseanet-production-client/src/components/record/recordEditor/models/fieldCollection.js
new file mode 100644
index 0000000000..b9f297ebbb
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/recordEditor/models/fieldCollection.js
@@ -0,0 +1,81 @@
+import merge from 'lodash.merge';
+
+class FieldCollection {
+ fields;
+
+ constructor(fieldsList) {
+ this.fields = fieldsList;
+ }
+
+ getFields() {
+ return this.fields;
+ }
+
+ getFieldOptionsById(meta_struct_id) {
+ /*var name = this.fields[meta_struct_id].name;
+ var label = this.fields[meta_struct_id].label;
+ var multi = ;
+ var required = this.fields[meta_struct_id].required;
+ var readonly = this.fields[meta_struct_id].readonly;
+ var maxLength = this.fields[meta_struct_id].maxLength;
+ var minLength = this.fields[meta_struct_id].minLength;
+ var type = this.fields[meta_struct_id].type;
+ var separator = this.fields[meta_struct_id].separator;
+ var vocabularyControl = this.fields[meta_struct_id].vocabularyControl || null;
+ var vocabularyRestricted = this.fields[meta_struct_id].vocabularyRestricted || null;*/
+
+ return {
+ multi: this.fields[meta_struct_id].multi,
+ required: this.fields[meta_struct_id].required,
+ readonly: this.fields[meta_struct_id].readonly,
+ maxLength: this.fields[meta_struct_id].maxLength,
+ minLength: this.fields[meta_struct_id].minLength,
+ type: this.fields[meta_struct_id].type,
+ separator: this.fields[meta_struct_id].separator,
+ vocabularyControl: this.fields[meta_struct_id].vocabularyControl || null,
+ vocabularyRestricted: this.fields[meta_struct_id].vocabularyRestricted || null
+ };
+ }
+
+ setActiveField(metaStructId) {
+ this.metaStructId = metaStructId;
+ }
+
+ getActiveFieldIndex() {
+ return this.metaStructId === undefined ? '?' : this.metaStructId;
+ }
+
+ getActiveField() {
+ return this.fields[this.getActiveFieldIndex()]
+ }
+
+ getFieldByIndex(id = false) {
+ if (this.fields[id] !== undefined) {
+ return this.fields[id];
+ }
+ return false;
+ }
+
+ getFieldByName(fieldName) {
+ let foundField = false;
+ for (let field in this.fields) {
+ if (this.fields[field].name === fieldName) {
+ foundField = this.fields[field];
+ }
+ }
+ return foundField;
+ }
+
+ getFieldStatus(id = false) {
+
+ }
+
+ updateField(id, data) {
+ if (this.fields[id] !== undefined) {
+ this.fields[id] = merge(this.fields[id], data);
+ return this.fields[id];
+ }
+ }
+
+}
+export default FieldCollection;
diff --git a/Phraseanet-production-client/src/components/record/recordEditor/models/recordCollection.js b/Phraseanet-production-client/src/components/record/recordEditor/models/recordCollection.js
new file mode 100644
index 0000000000..8c8ebf0991
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/recordEditor/models/recordCollection.js
@@ -0,0 +1,193 @@
+import FieldCollection from './fieldCollection';
+import * as recordModel from '../../../record/model';
+class RecordCollection {
+ records;
+ fieldCollection;
+ statbitCollection;
+ constructor(recordsList, fieldsColl, statusbitList, predefinedValues) {
+ this.records = recordsList;
+ this.statusbits = statusbitList;
+ this.fieldCollection = fieldsColl;
+ this.predefinedValues = predefinedValues;
+ // set each models
+ this.initializeRecordModels();
+ }
+ getRecords() {
+ return this.records;
+ }
+ getRecordByIndex(id = false) {
+ if (this.records[id] !== undefined) {
+ return this.records[id];
+ }
+ return false;
+ }
+
+ initializeRecordModels() {
+ for (let recordIndex in this.records) {
+ // let fields = this.setRecordFields(recordIndex);
+ this.records[recordIndex].fields = this.setRecordFields(recordIndex);
+ //options.fields = fields;
+
+ }
+ }
+ setRecordFields(recordIndex) {
+ let fields = {};
+ for (let fieldIndex in this.records[recordIndex].fields) {
+ var meta_struct_id = this.records[recordIndex].fields[fieldIndex].meta_struct_id;
+
+
+ let currentField = this.fieldCollection.getFieldByIndex(meta_struct_id);
+ var fieldOptions = this.fieldCollection.getFieldOptionsById(meta_struct_id);
+
+ var databoxField = new recordModel.databoxField(currentField.name, currentField.label, meta_struct_id, fieldOptions);
+
+ var values = [];
+
+ for (let v in this.records[recordIndex].fields[fieldIndex].values) {
+ var meta_id = this.records[recordIndex].fields[fieldIndex].values[v].meta_id;
+ var value = this.records[recordIndex].fields[fieldIndex].values[v].value;
+ var vocabularyId = this.records[recordIndex].fields[fieldIndex].values[v].vocabularyId;
+
+ values.push(new recordModel.recordFieldValue(meta_id, value, vocabularyId));
+ }
+
+ fields[fieldIndex] = new recordModel.recordField(databoxField, values);
+ }
+ return fields;
+ }
+
+ /**
+ * Merge all suggestions for 1 or n records
+ * @returns {{}}
+ */
+ getFieldSuggestedValues() {
+ var suggestedValuesCollection = {};
+ var t_selcol = {};
+ var ncolsel = 0;
+ var nrecsel = 0;
+ for (let recordIndex in this.records) {
+ if (!this.records[recordIndex]._selected) {
+ continue;
+ }
+ nrecsel++;
+
+ var bid = 'b' + this.records[recordIndex].bid;
+ if (t_selcol[bid]) {
+ continue;
+ }
+
+ t_selcol[bid] = 1;
+ ncolsel++;
+ for (let f in this.predefinedValues[bid]) {
+ if (!suggestedValuesCollection[f]) {
+ suggestedValuesCollection[f] = {};
+ }
+ for (let ivs in this.predefinedValues[bid][f]) {
+ let vs = this.predefinedValues[bid][f][ivs];
+ if (!suggestedValuesCollection[f][vs]) {
+ suggestedValuesCollection[f][vs] = 0;
+ }
+ suggestedValuesCollection[f][vs]++;
+ }
+ }
+ }
+
+ return suggestedValuesCollection;
+ }
+
+ setStatus(bit, val) {
+ for (let id in this.records) {
+ // toutes les fiches selectionnees
+ if (this.records[id]._selected) {
+ if (this.records[id].editableStatus === true) {
+ this.records[id].statbits[bit].value = val;
+ this.records[id].statbits[bit].dirty = true;
+ }
+ }
+ }
+ }
+
+ isDirty() {
+ let dirty = false;
+ for (let recordIndex in this.records) {
+ for (let fieldIndex in this.records[recordIndex].fields) {
+ if ((dirty |= this.records[recordIndex].fields[fieldIndex].isDirty())) {
+ break;
+ }
+ }
+ for (let bitIndex in this.records[recordIndex].statbits) {
+ if ((dirty |= this.records[recordIndex].statbits[bitIndex].dirty)) {
+ break;
+ }
+ }
+ }
+ return dirty;
+ }
+
+ gatherUpdatedRecords() {
+ let t = [];
+
+ for (let recordIndex in this.records) {
+ let record_datas = {
+ record_id: this.records[recordIndex].rid,
+ metadatas: [],
+ edit: 0,
+ status: null
+ };
+
+ let editDirty = false;
+
+ for (let f in this.records[recordIndex].fields) {
+ if (!this.records[recordIndex].fields[f].isDirty()) {
+ continue;
+ }
+
+ editDirty = true;
+ record_datas.edit = 1;
+
+ record_datas.metadatas = record_datas.metadatas.concat(
+ this.records[recordIndex].fields[f].exportDatas()
+ );
+ }
+
+ // les statbits
+ let tsb = [];
+ for (let n = 0; n < 64; n++) {
+ tsb[n] = 'x';
+ }
+ let sb_dirty = false;
+ for (let n in this.records[recordIndex].statbits) {
+ if (this.records[recordIndex].statbits[n].dirty) {
+ tsb[63 - n] = this.records[recordIndex].statbits[n].value;
+ sb_dirty = true;
+ }
+ }
+
+ if (sb_dirty || editDirty) {
+ if (sb_dirty === true) {
+ record_datas.status = tsb.join('');
+ }
+
+ t.push(record_datas);
+ }
+ }
+ return t;
+ }
+ removeRecordFieldValue(recordIndex, fieldIndex, params) {
+ let {value, vocabularyId} = params;
+ this.records[recordIndex].fields[fieldIndex].removeValue(value, vocabularyId);
+ }
+
+ addRecordFieldValue(recordIndex, fieldIndex, params) {
+ let {value, merge, vocabularyId} = params;
+ this.records[recordIndex].fields[fieldIndex].addValue(value, merge, vocabularyId);
+ }
+
+/* options.recordCollection.removeRecordFieldValue(r, currentFieldId, {
+ value, vocabularyId
+})*/
+ // currentRecord.fields[currentFieldId].removeValue(value, VocabularyId);
+
+
+}
+export default RecordCollection;
diff --git a/Phraseanet-production-client/src/components/record/recordEditor/models/statusCollection.js b/Phraseanet-production-client/src/components/record/recordEditor/models/statusCollection.js
new file mode 100644
index 0000000000..b34d17b5eb
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/recordEditor/models/statusCollection.js
@@ -0,0 +1,37 @@
+import merge from 'lodash.merge';
+class StatusCollection {
+ status;
+
+ constructor(statusList) {
+ this.status = statusList;
+ }
+
+ getStatus() {
+ return this.status;
+ }
+
+ fillWithRecordValues(records) {
+ let prefilledStatus = {};
+ for (let statusIndex in this.status) {
+ prefilledStatus[statusIndex] = merge({}, this.status[statusIndex]);
+ prefilledStatus[statusIndex]._value = '-1'; // val unknown
+ for (let i in records) {
+ if (!records[i]._selected) {
+ continue;
+ }
+ if (records[i].statbits.length === 0) {
+ continue;
+ }
+
+ if (prefilledStatus[statusIndex]._value === '-1') {
+ prefilledStatus[statusIndex]._value = records[i].statbits[statusIndex].value;
+ } else if (prefilledStatus[statusIndex]._value !== records[i].statbits[statusIndex].value) {
+ prefilledStatus[statusIndex]._value = '2';
+ }
+ }
+ }
+
+ return prefilledStatus;
+ }
+}
+export default StatusCollection;
diff --git a/Phraseanet-production-client/src/components/record/recordEditor/plugins/geonameDatasource.js b/Phraseanet-production-client/src/components/record/recordEditor/plugins/geonameDatasource.js
new file mode 100644
index 0000000000..85d87b0dfd
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/recordEditor/plugins/geonameDatasource.js
@@ -0,0 +1,284 @@
+import $ from 'jquery';
+import _ from 'underscore';
+require('geonames-server-jquery-plugin/jquery.geonames.js');
+
+const geonameDatasource = (services) => {
+ const {configService, localeService, recordEditorEvents} = services;
+ const tabContainerName = 'geonameTabContainer';
+ let autoActivateTabOnce = true;
+ let $container = null;
+ let parentOptions = {};
+ let $editTextArea;
+ let $tabContent;
+ let geonamesFieldMapping = false;
+ let cityFields = [];
+ let provinceFields = [];
+ let countryFields = [];
+ let latitudeFields = [];
+ let longitudeFields = [];
+
+ const initialize = (options) => {
+ let initWith = {$container, parentOptions, $editTextArea} = options;
+ let geocodingProviders = configService.get('geocodingProviders');
+ _.each(geocodingProviders, (provider) => {
+ //geoname field mapping
+ if (provider['geonames-field-mapping'] == true) {
+ if (provider['cityfields']) {
+ cityFields = provider['cityfields'].split(',').map(item => item.trim());
+ }
+ if (provider['provincefields']) {
+ provinceFields = provider['provincefields'].split(',').map(item => item.trim());
+ }
+ if (provider['countryfields']) {
+ countryFields = provider['countryfields'].split(',').map(item => item.trim());
+ }
+ if (provider['latitudefields']) {
+ latitudeFields = provider['latitudefields'].split(',').map(item => item.trim());
+ }
+ if (provider['longitudefields']) {
+ longitudeFields = provider['longitudefields'].split(',').map(item => item.trim());
+ }
+ }
+ });
+ recordEditorEvents.emit('appendTab', {
+ tabProperties: {
+ id: tabContainerName,
+ title: localeService.t('Geoname Datasource'),
+ },
+ position: 1
+ });
+ // reset for each fields
+ autoActivateTabOnce = true;
+
+ };
+
+ const onTabAdded = (params) => {
+ let {origParams} = params;
+ if (origParams.tabProperties.id === tabContainerName) {
+ $tabContent = $(`#${tabContainerName}`, $container);
+ bindEvents();
+ }
+ };
+
+ const bindEvents = () => {
+ let cclicks = 0;
+ const cDelay = 350;
+ let cTimer = null;
+ $tabContent.on('click', '.geoname-add-action', (event) => {
+ event.preventDefault();
+ cclicks++;
+
+ if (cclicks === 1) {
+ cTimer = setTimeout(function () {
+ cclicks = 0;
+ }, cDelay);
+
+ } else {
+ clearTimeout(cTimer);
+ onSelectValue(event);
+ cclicks = 0;
+ }
+ })
+ };
+
+ const onSelectValue = (event) => {
+ event.preventDefault();
+ let $el = $(event.currentTarget);
+ let value = $el.data('city');
+
+ // the field may have changed over time
+ let field = parentOptions.fieldCollection.getActiveField();
+
+ switch (field.name) {
+ case 'City':
+ value = $el.data('city');
+ break;
+ case 'Country':
+ value = $el.data('country');
+ break;
+ case 'Province':
+ value = $el.data('province');
+ break;
+ case 'Longitude':
+ value = $el.data('longitude');
+ break;
+ case 'Latitude':
+ value = $el.data('latitude');
+ break;
+ default:
+ break;
+ }
+
+ // send prefill instruction for related fields:
+ // send data for all geo fields (same as preset API)
+ let fields = {};
+ let presets = {};
+ _.each(cityFields, function (field) {
+ fields[field] = [$el.data('city')];
+ });
+ _.each(provinceFields, function (field) {
+ fields[field] = [$el.data('province')];
+ });
+ _.each(countryFields, function (field) {
+ fields[field] = [$el.data('country')];
+ });
+
+ $("#dialog-edit_lat_lon").dialog({
+ resizable: false,
+ height: "auto",
+ width: 400,
+ modal: true,
+ buttons: {
+ confirmYes : function () {
+ $(this).dialog("close");
+ _.each(latitudeFields, function (field) {
+ fields[field] = [String($el.data('latitude'))];
+ });
+ _.each(longitudeFields, function (field) {
+ fields[field] = [String($el.data('longitude'))];
+ });
+ presets.fields = fields;
+ recordEditorEvents.emit('recordEditor.addPresetValuesFromDataSource', {data: presets, mode: ''});
+ // force update on current field:
+ recordEditorEvents.emit('recordEditor.addValueFromDataSource', {value: value, field: field});
+ console.log('Lat & Lon updated')
+ },
+ confirmNo: function () {
+ presets.fields = fields;
+ recordEditorEvents.emit('recordEditor.addPresetValuesFromDataSource', {data: presets, mode: ''});
+ // force update on current field:
+ recordEditorEvents.emit('recordEditor.addValueFromDataSource', {value: value, field: field});
+ $(this).dialog("close");
+ },
+
+ },
+ open: function open() {
+ $('.ui-button-text:contains(confirmYes)').html($('#dialog-edit-yes').val());
+ $('.ui-button-text:contains(confirmNo)').html($('#dialog-edit-no').val());
+ },
+ close: function () {
+ },
+ });
+
+ };
+
+ const highlight = (s, t) => {
+ if (t === '') {
+ return s;
+ }
+ var matcher = new RegExp('(' + t + ')', 'ig');
+ return s.replace(matcher, '$1 ');
+ };
+
+ const searchValue = (params) => {
+
+ let {event, value, field} = params;
+ let datas = {
+ sort: '',
+ sortParams: '',
+ 'client-ip': null,
+ country: '',
+ name: '',
+ limit: 20
+ };
+ let searchType = false;
+ let name;
+ let country;
+
+ let terms = value.split(',');
+ if (terms.length === 2) {
+ country = terms.pop();
+ }
+
+ name = terms.pop();
+
+ if (cityFields.filter(item => item.toLowerCase() == field.name.toLowerCase()).length > 0) {
+ searchType = 'city';
+ datas.name = $.trim(name);
+ datas.country = $.trim(country);
+ } else if (provinceFields.filter(item => item.toLowerCase() == field.name.toLowerCase()).length > 0) {
+ // @TODO - API can't search by region/province
+ searchType = 'city';
+ datas.province = $.trim(name);
+ // datas.country = $.trim(country);
+ } else if (countryFields.filter(item => item.toLowerCase() == field.name.toLowerCase()).length > 0) {
+ searchType = 'city';
+ datas.country = $.trim(name);
+ // } else if (latitudeFields.filter(item => item.toLowerCase() == field.name.toLowerCase()).length > 0) {
+ // searchType = 'latitude';
+ // datas.latitude = $.trim(name);
+ }
+
+ if (searchType === false) {
+ return;
+ }
+
+ // switch tab only on the first search:
+ if (autoActivateTabOnce === true) {
+ recordEditorEvents.emit('recordEditor.activateToolTab', tabContainerName);
+ autoActivateTabOnce = false;
+ }
+
+ fetchGeoname(
+ searchType,
+ datas,
+ function (jqXhr, status, error) {
+ if (jqXhr.status !== 0 && jqXhr.statusText !== 'abort') {
+ console.log('error occured', [jqXhr, status, error])
+ }
+ },
+ function (data) {
+ return data;
+ }
+ );
+ };
+
+ const fetchGeoname = (resource, datas, errorCallback, parseresults) => {
+ let url = configService.get('geonameServerUrl');
+ url = url.substr(url.length - 1) === '/' ? url : url + '/';
+
+ return $.ajax({
+ url: url + resource,
+ data: datas,
+ dataType: 'jsonp',
+ jsonpCallback: 'parseresults',
+ success: function (data) {
+ let template = '';
+ _.map(data || [], function (item) {
+ let matchWith = datas.name !== '' ? datas.name : datas.country;
+
+ let labelName = highlight(item.name, matchWith);
+ let labelCountry = highlight((item.country ? item.country.name || '' : ''), matchWith);
+ let regionName = (item.region ? item.region.name || '' : '');
+ let labelRegion = highlight(regionName, name);
+
+ let location = {
+ value: labelName + (labelRegion !== '' ? ', ' + labelRegion + ' ' : ''),
+ label: (labelCountry !== '' ? labelCountry : ''),
+ geonameid: item.geonameid
+ };
+
+ template += `
+
+ ${location.value}
+
+ ${location.label}
+ `;
+ });
+
+ $tabContent.empty().append(``);
+ },
+ error: function (xhr, status, error) {
+ console.log(status + '; ' + error);
+ }
+ });
+ };
+
+ recordEditorEvents.listenAll({
+ 'appendTab.complete': onTabAdded,
+ 'recordEditor.userInputValue': searchValue
+ });
+
+ return {initialize};
+};
+export default geonameDatasource;
diff --git a/Phraseanet-production-client/src/components/record/recordEditor/plugins/preview.js b/Phraseanet-production-client/src/components/record/recordEditor/plugins/preview.js
new file mode 100644
index 0000000000..6fd631143c
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/recordEditor/plugins/preview.js
@@ -0,0 +1,197 @@
+import $ from 'jquery';
+import pym from 'pym.js';
+import videoEditor from './videoEditor';
+//require('jquery-ui');
+
+const preview = services => {
+ const { configService, localeService, recordEditorEvents } = services;
+ let $container = null;
+ let parentOptions = {};
+ let activeThumbnailFrame = false;
+ let lastRecordIndex = false;
+
+ recordEditorEvents.listenAll({
+ // @TODO debounce
+ 'recordEditor.uiResize': onResize,
+ 'recordSelection.changed': onSelectionChange,
+ 'recordEditor.onSelectRecord': renderPreview,
+ 'recordEditor.tabChange': tabChanged
+ });
+
+ const initialize = options => {
+ let initWith = ({ $container, parentOptions } = options);
+ };
+
+ function onResize() {
+ var selected = $('#EDIT_FILM2 .diapo.selected');
+
+ if (selected.length !== 1) {
+ return false;
+ }
+
+ var id = selected.attr('id').split('_').pop();
+
+ var zoomable = $('img.record.zoomable', $container.parent());
+
+ if (zoomable.length > 0 && zoomable.hasClass('zoomed')) {
+ return false;
+ }
+
+ var h = parseInt(
+ $($container.children()).attr('data-original-height'),
+ 10
+ );
+ var w = parseInt(
+ $($container.children()).attr('data-original-width'),
+ 10
+ );
+
+ var t = 0;
+ var de = 0;
+
+ var margX = 20;
+ var margY = 20;
+
+ if ($('img.record.record_audio', $container).length > 0) {
+ margY = 100;
+ de = 60;
+ }
+ let containerWidth = $container.parent().width();
+ let containerHeight = $container.parent().height();
+
+ // if(datas.doctype != 'flash')
+ // {
+ var ratioP = w / h;
+ var ratioD = containerWidth / containerHeight;
+
+ if (ratioD > ratioP) {
+ // je regle la hauteur d'abord
+ if (parseInt(h, 10) + margY > containerHeight) {
+ h = Math.round(containerHeight - margY);
+ w = Math.round(h * ratioP);
+ }
+ } else {
+ if (parseInt(w, 10) + margX > containerWidth) {
+ w = Math.round(containerWidth - margX);
+ h = Math.round(w / ratioP);
+ }
+ }
+ t = Math.round((containerHeight - h - de) / 2);
+ var l = Math.round((containerWidth - w) / 2);
+ $('.record', $container.parent())
+ .css({
+ width: w,
+ height: h,
+ top: t,
+ left: l,
+ margin: '0 auto',
+ display: 'block'
+ })
+ .attr('width', w)
+ .attr('height', h);
+ }
+
+ function tabChanged(params) {
+ if (params.tab === '#TH_Opreview') {
+ //redraw preview
+ var selected = $('#EDIT_FILM2 .diapo.selected');
+ if (selected.length !== 1) {
+ return false;
+ }
+ var id = selected.attr('id').split('_').pop();
+ renderPreview({
+ recordIndex: id
+ });
+ }
+ }
+
+ function renderPreview(params) {
+ let { recordIndex } = params;
+
+ lastRecordIndex = recordIndex;
+
+ let currentRecord = parentOptions.recordCollection.getRecordByIndex(
+ recordIndex
+ );
+
+ $container.empty();
+
+ switch (currentRecord.type) {
+ case 'video':
+ case 'audio':
+ case 'document':
+ let customId = 'phraseanet-embed-editor-frame';
+ let $template = $(currentRecord.template);
+ $template.attr('id', customId);
+
+ $container.append($template.get(0));
+ activeThumbnailFrame = new pym.Parent(
+ customId,
+ currentRecord.data.preview.url
+ );
+ activeThumbnailFrame.iframe.setAttribute('allowfullscreen', '');
+ break;
+ case 'image':
+ default:
+ $container.append(currentRecord.template);
+ onResize();
+ }
+
+ if ($('img.PREVIEW_PIC.zoomable').length > 0) {
+ $('img.PREVIEW_PIC.zoomable').draggable();
+ }
+
+ /**Resize video on edit**/
+ if(currentRecord.type == 'video') {
+ resizeVideo();
+ $('#phraseanet-embed-editor-frame').css('text-align','center');
+ /*resize of VIDEO */
+ function resizeVideo(){
+ if($('#phraseanet-embed-editor-frame iframe').length > 0) {
+
+ var $sel = $('#phraseanet-embed-editor-frame');
+ var $window = $('#TH_Opreview').height();
+
+ // V is for "video" ; K is for "container" ; N is for "new"
+ var VW = $('#phraseanet-embed-editor-frame ').data( "original-width" );
+ var VH = $('#phraseanet-embed-editor-frame ').data( "original-height" );
+
+ var KW = $sel.width();
+ var KH = $sel.height();
+ KH = $window - 20 ;
+
+ var NW, NH;
+ if( (NH = (VH / VW) * (NW=KW) ) > KH ) { // try to fit exact horizontally, adjust vertically
+ // too bad... new height overflows container height
+ NW = (VW / VH) * (NH=KH); // so fit exact vertically, adjust horizontally
+ }
+ $("#phraseanet-embed-editor-frame iframe").css('width', NW).css('height', NH);
+
+ }
+ }
+ $(window).on("load resize ",function(e){
+ resizeVideo();
+ });
+ $(window).click(".ui-tabs-anchor", function (e) {
+ resizeVideo();
+ });
+ }
+ /**end Resize video on edit**/
+ }
+
+ /**
+ * refresh preview if only one record is selected
+ * @param params
+ */
+ function onSelectionChange(params) {
+ let { selection } = params;
+ if (selection.length === 1) {
+ renderPreview({
+ recordIndex: selection[0]
+ });
+ }
+ }
+
+ return { initialize };
+};
+export default preview;
diff --git a/Phraseanet-production-client/src/components/record/recordEditor/plugins/searchReplace.js b/Phraseanet-production-client/src/components/record/recordEditor/plugins/searchReplace.js
new file mode 100644
index 0000000000..b37e1f4d87
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/recordEditor/plugins/searchReplace.js
@@ -0,0 +1,103 @@
+import $ from 'jquery';
+import merge from 'lodash.merge';
+const humane = require('humane-js');
+/**
+ * Editor Right tab plugin
+ */
+
+// EditReplace
+
+const searchReplace = (services) => {
+ const {configService, localeService, recordEditorEvents} = services;
+ let $container = null;
+ let tRecords = {};
+ let parentOptions = {};
+ recordEditorEvents.listenAll({
+ 'recordEditor.plugin.searchReplace.replace': 'replace'
+ });
+
+ const initialize = (options) => {
+ let initWith = {$container, parentOptions} = options;
+ // recordCollection = parentOptions.recordCollection;
+ tRecords = parentOptions.recordCollection.getRecords();
+
+
+ $($container).on('click', '.record-editor-searchReplace-action', (event) => {
+ event.preventDefault();
+
+ let ntRecords = replace(tRecords);
+
+ // @TODO - reactivate humane
+ // humane.info($.sprintf(localeService.t('nFieldsChanged', n)));
+ recordEditorEvents.emit('recordEditor.onUpdateFields', ntRecords);
+ });
+
+
+ $($container).on('change', '.record-editor-toggle-replace-mode-action', (event) => {
+ event.preventDefault();
+ _toggleReplaceMode(event.currentTarget);
+ });
+ };
+
+ const replace = (tRecords) => {
+ var field = $('#EditSRField', $container).val();
+ var search = $('#EditSearch', $container).val();
+ var replace = $('#EditReplace', $container).val();
+
+ var where = $('[name=EditSR_Where]:checked', $container).val();
+ var commut = '';
+ var rgxp = $('#EditSROptionRX', $container).prop('checked') ? true : false;
+
+ var r_search;
+ if (rgxp) {
+ r_search = search;
+ commut = ($('#EditSR_RXG', $container).prop('checked') ? 'g' : '')
+ + ($('#EditSR_RXI', $container).prop('checked') ? 'i' : '');
+ } else {
+ commut = $('#EditSR_case', $container).prop('checked') ? 'g' : 'gi';
+ r_search = '';
+ for (let i = 0; i < search.length; i++) {
+ var c = search.charAt(i);
+ if (('^$[]()|.*+?\\').indexOf(c) !== -1) {
+ r_search += '\\';
+ }
+ r_search += c;
+ }
+ if (where === 'exact') {
+ r_search = '^' + r_search + '$';
+ }
+ }
+
+ search = new RegExp(r_search, commut);
+
+ let f;
+ let n = 0;
+ for (let r in tRecords) {
+ if (!tRecords[r]._selected) {
+ continue;
+ }
+ for (f in tRecords[r].fields) {
+ if (field === '' || field === f) {
+ n += tRecords[r].fields[f].replaceValue(search, replace);
+ }
+ }
+ }
+
+ return merge({}, tRecords);
+ };
+
+ function _toggleReplaceMode(ckRegExp) {
+
+ if (ckRegExp.checked) {
+ $('#EditSR_TX', $container).hide();
+ $('#EditSR_RX', $container).show();
+ } else {
+ $('#EditSR_RX', $container).hide();
+ $('#EditSR_TX', $container).show();
+ }
+ }
+
+ return {initialize}
+};
+
+export default searchReplace;
diff --git a/Phraseanet-production-client/src/components/record/recordEditor/plugins/thesaurusDatasource.js b/Phraseanet-production-client/src/components/record/recordEditor/plugins/thesaurusDatasource.js
new file mode 100644
index 0000000000..a7c47701ae
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/recordEditor/plugins/thesaurusDatasource.js
@@ -0,0 +1,202 @@
+import $ from 'jquery';
+
+const thesaurusDatasource = (services) => {
+ const {configService, localeService, recordEditorEvents} = services;
+ let $container = null;
+ let parentOptions = {};
+ let ETHSeeker = null;
+ let $editTextArea;
+
+
+ const initialize = (options) => {
+ let initWith = {$container, parentOptions, $editTextArea} = options;
+ let cclicks = 0;
+ const cDelay = 350;
+ let cTimer = null;
+ $container
+ .on('click', '.edit-thesaurus-action', (event) => {
+ event.preventDefault();
+ cclicks++;
+
+ if (cclicks === 1) {
+ cTimer = setTimeout(function () {
+ onSelectBranch(event);
+ cclicks = 0;
+ }, cDelay);
+
+ } else {
+ clearTimeout(cTimer);
+ onSelectTerm(event);
+ cclicks = 0;
+ }
+ })
+ .on('dblclick', '.thesaurus-branch-action', (event) => {
+ // dbl is handled by click event
+ event.preventDefault();
+ })
+
+ ETHSeeker = new ThesaurusSeeker(parentOptions.sbas_id);
+
+ return ETHSeeker;
+ };
+
+ const searchValue = (params) => {
+ let {event, value, field} = params;
+ // ok a thesaurus branch match
+ if (field.tbranch !== undefined) {
+ return ETHSeeker.search(value);
+ }
+ }
+
+
+ function ThesaurusSeeker(sbas_id) {
+ this.jq = null;
+
+ this.sbas_id = sbas_id;
+
+ let zid = ('' + sbas_id).replace(new RegExp('\\.', 'g'), '\\.') + '\\.T';
+
+ this.TH_P_node = $('#TH_P\\.' + zid, parentOptions.$container);
+ this.TH_K_node = $('#TH_K\\.' + zid, parentOptions.$container);
+
+ this._ctimer = null;
+
+ this.search = function (txt) {
+ if (this._ctimer) {
+ clearTimeout(this._ctimer);
+ }
+ this._ctimer = setTimeout(() => {
+ return ETHSeeker.search_delayed('"' + txt.replace("'", "\\'") + '"')
+ }, 125);
+ };
+
+ this.search_delayed = function (txt) {
+ if (this.jq && typeof this.jq.abort === 'function') {
+ this.jq.abort();
+ this.jq = null;
+ }
+ txt = txt.replace("'", "\\'");
+ let url = '/xmlhttp/openbranches_prod.h.php';
+ let parms = {
+ bid: this.sbas_id,
+ lng: localeService.getLocale(),
+ t: txt,
+ mod: 'TREE',
+ u: Math.random()
+ };
+
+ let me = this;
+
+ this.jq = $.ajax({
+ url: url,
+ data: parms,
+ type: 'POST',
+ success: function (ret) {
+ me.TH_P_node.html('...');
+ me.TH_K_node.attr('class', 'h').html(ret);
+ me.jq = null;
+ }
+ });
+ };
+
+ this.openBranch = function (id, thid) {
+ if (this.jq) {
+ this.jq.abort();
+ this.jq = null;
+ }
+ let url = '/xmlhttp/getterm_prod.h.php';
+ let parms = {
+ bid: this.sbas_id,
+ lng: localeService.getLocale(),
+ sortsy: 1,
+ id: thid,
+ typ: 'TH'
+ };
+ let me = this;
+
+
+ this.jq = $.ajax({
+ url: url,
+ data: parms,
+ success: function (ret) {
+ let zid = '#TH_K\\.' + id.replace(new RegExp('\\.', 'g'), '\\.'); // escape les '.' pour jquery
+ $(zid, parentOptions.$container).html(ret);
+ me.jq = null;
+ }
+ });
+ };
+ }
+
+// onclick dans le thesaurus
+ function onSelectBranch(event) {
+ let e;
+ for (e = event.srcElement ? event.srcElement : event.target; e && ((!e.tagName) || (!e.id)); e = e.parentNode);
+
+ if (e) {
+ switch (e.id.substr(0, 4)) {
+ case 'TH_P': // +/- de deploiement de mot
+ toggleBranch(e.id.substr(5));
+ break;
+ default:
+ }
+ }
+ return (false);
+ }
+
+// ondblclick dans le thesaurus
+ function onSelectTerm(event) {
+ let e;
+ for (e = event.srcElement ? event.srcElement : event.target; e && ((!e.tagName) || (!e.id)); e = e.parentNode);
+
+ if (e) {
+ switch (e.id.substr(0, 4)) {
+ case 'TH_W':
+ let currentFieldIndex = parentOptions.fieldCollection.getActiveFieldIndex();
+
+ if (currentFieldIndex >= 0) {
+ let w = $(e).text();
+ recordEditorEvents.emit('recordEditor.addValueFromDataSource', {value: w});
+ }
+ break;
+ default:
+ }
+ }
+ return (false);
+ }
+
+// on ouvre ou ferme une branche de thesaurus
+ function toggleBranch(id) {
+ let o = document.getElementById('TH_K.' + id);
+ if (o.className === 'o') {
+ // on ferme
+ o.className = 'c';
+ document.getElementById('TH_P.' + id).innerHTML = '+';
+ document.getElementById('TH_K.' + id).innerHTML = localeService.t('loading');
+ } else if (o.className === 'c' || o.className === 'h') {
+ // on ouvre
+ o.className = 'o';
+ document.getElementById('TH_P.' + id).innerHTML = '-';
+
+ let t_id = id.split('.');
+ let sbas_id = t_id[0];
+ t_id.shift();
+ let thid = t_id.join('.');
+ let url = '/xmlhttp/getterm_prod.x.php';
+ let parms = 'bid=' + sbas_id;
+ parms += '&lng=' + localeService.getLocale();
+ parms += '&sortsy=1';
+ parms += '&id=' + thid;
+ parms += '&typ=TH';
+
+ ETHSeeker.openBranch(id, thid);
+ }
+ return (false);
+ }
+
+ recordEditorEvents.listenAll({
+ 'recordEditor.userInputValue': searchValue
+ });
+
+ return {initialize};
+};
+export default thesaurusDatasource;
diff --git a/Phraseanet-production-client/src/components/record/recordEditor/plugins/videoEditor.js b/Phraseanet-production-client/src/components/record/recordEditor/plugins/videoEditor.js
new file mode 100644
index 0000000000..6cb13a0b95
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/recordEditor/plugins/videoEditor.js
@@ -0,0 +1,74 @@
+import $ from 'jquery';
+import Flash from 'videojs-flash';
+
+const videoEditor = (services) => {
+ const {configService, localeService, recordEditorEvents} = services;
+ let $container = null;
+ let parentOptions = {};
+ let data;
+ let rangeCapture;
+ let rangeCaptureInstance;
+ let options = {
+ playbackRates: [],
+ fluid: true
+ };
+ const initialize = (params) => {
+ let initWith = {$container, parentOptions, data} = params;
+
+ if (data.videoEditorConfig !== null) {
+ options.seekBackwardStep = data.videoEditorConfig.seekBackwardStep;
+ options.seekForwardStep = data.videoEditorConfig.seekForwardStep;
+ options.playbackRates = data.videoEditorConfig.playbackRates === undefined ? [1, 2, 3] : data.videoEditorConfig.playbackRates;
+ options.vttFieldValue = false;
+ options.ChapterVttFieldName = data.videoEditorConfig.ChapterVttFieldName === undefined ? false : data.videoEditorConfig.ChapterVttFieldName;
+ }
+
+ options.techOrder = ['html5', 'flash'];
+ $container.addClass('video-range-editor-container');
+
+ // get default videoTextTrack value
+ if (options.ChapterVttFieldName !== false) {
+ let vttField = parentOptions.fieldCollection.getFieldByName(options.ChapterVttFieldName);
+ if (vttField !== false) {
+ options.vttFieldValue = vttField._value
+ }
+ }
+
+ require.ensure([], () => {
+
+ // load videoJs lib
+ rangeCapture = require('../../../videoEditor/rangeCapture').default;
+ rangeCaptureInstance = rangeCapture(services);
+ rangeCaptureInstance.initialize(params, options);
+
+ // proxy resize event to rangeStream
+ recordEditorEvents.listenAll({
+ 'recordEditor.uiResize': () => {
+ rangeCaptureInstance.getPlayer().rangeStream.onNext({action: 'resize'})
+ }
+ })
+
+
+ rangeCaptureInstance.getPlayer().rangeStream.subscribe((params) => {
+ switch (params.action) {
+ case 'export-vtt-ranges':
+ if (options.ChapterVttFieldName !== false) {
+
+ let presets = {
+ fields: {}
+ };
+ presets.fields[options.ChapterVttFieldName] = [params.data];
+ recordEditorEvents.emit('recordEditor.addPresetValuesFromDataSource', {
+ data: presets
+ });
+ }
+ break;
+ default:
+ }
+ });
+ });
+ };
+
+ return {initialize};
+};
+export default videoEditor;
diff --git a/Phraseanet-production-client/src/components/record/recordEditor/presets.js b/Phraseanet-production-client/src/components/record/recordEditor/presets.js
new file mode 100644
index 0000000000..3243b443c9
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/recordEditor/presets.js
@@ -0,0 +1,241 @@
+import $ from 'jquery';
+import {cleanTags} from '../../utils/utils';
+
+const presetsModule = (services) => {
+ const {configService, localeService, recordEditorEvents} = services;
+ const url = configService.get('baseUrl');
+ let $container = null;
+ let parentOptions = {};
+ let recordCollection;
+ let fieldCollection;
+ const initialize = (options) => {
+ let initWith = {$container, parentOptions} = options;
+ recordCollection = parentOptions.recordCollection;
+ fieldCollection = parentOptions.fieldCollection;
+ initPresetsModal();
+ };
+
+ const initPresetsModal = () => {
+ let buttons = {};
+ buttons[localeService.t('valider')] = function (event) {
+ $(this).dialog('close');
+ recordEditorEvents.emit('recordEditor.submitAllChanges', {event});
+ };
+ buttons[localeService.t('annuler')] = function (event) {
+ $(this).dialog('close');
+ recordEditorEvents.emit('recordEditor.cancelAllChanges', {event});
+ };
+
+ $('#EDIT_CLOSEDIALOG', $container).dialog({
+ autoOpen: false,
+ closeOnEscape: true,
+ resizable: false,
+ draggable: false,
+ modal: true,
+ buttons: buttons
+ });
+
+ buttons[localeService.t('valider')] = function () {
+ var form = $('#Edit_copyPreset_dlg FORM');
+ var jtitle = $('.EDIT_presetTitle', form);
+ if (jtitle.val() === '') {
+ alert(localeService.t('needTitle'));
+ jtitle[0].focus();
+ return;
+ }
+ var addFields = [];
+ $(':checkbox', form).each(function (idx, elem) {
+ var $el = $(elem);
+ if ($el.is(':checked')) {
+ var fieldIndex = $el.val();
+ let foundField = fieldCollection.getFieldByIndex(fieldIndex);
+ var field = {
+ name: foundField.name,
+ value: []
+ };
+ var tval;
+ if (foundField.multi) {
+ field.value = $.map(
+ foundField._value.split(';'),
+ function (obj, idx) {
+ return obj.trim();
+ }
+ );
+ } else {
+ field.value = [foundField._value.trim()];
+ }
+ addFields.push(field);
+ }
+ });
+
+ $.ajax({
+ type: 'POST',
+ url: `${url}prod/records/edit/presets`,
+ data: {
+ sbas_id: parentOptions.sbas_id,
+ title: jtitle.val(),
+ fields: addFields
+ },
+ dataType: 'json',
+ success: function (data, textStatus) {
+ _preset_paint(data);
+
+ if ($('#Edit_copyPreset_dlg').data('ui-dialog')) {
+ $('#Edit_copyPreset_dlg').dialog('close');
+ }
+ }
+ });
+ };
+
+ buttons[localeService.t('annuler')] = function () {
+ $(this).dialog('close');
+
+ };
+
+ $('#Edit_copyPreset_dlg', $container).dialog({
+ stack: true,
+ closeOnEscape: true,
+ resizable: false,
+ draggable: false,
+ autoOpen: false,
+ modal: true,
+ width: 600,
+ title: localeService.t('newPreset'),
+ close: function (event, ui) {
+ $(this).dialog('widget').css('z-index', 'auto');
+ },
+ open: function (event, ui) {
+ $(this).dialog('widget').css('z-index', '5000');
+ $('.EDIT_presetTitle')[0].focus();
+ },
+ buttons: buttons
+ });
+
+ $.ajax({
+ type: 'GET',
+ url: `${url}prod/records/edit/presets`,
+ data: {
+ sbas_id: parentOptions.sbas_id
+ },
+ dataType: 'json',
+ success: function (data, textStatus) {
+ _preset_paint(data);
+ }
+ });
+ $container.on('click', '#TH_Opresets button.adder', function () {
+ //$('#TH_Opresets button.adder').bind('click', function () {
+ _preset_copy();
+ });
+ }
+
+ function _preset_paint(data) {
+ $('.EDIT_presets_list', parentOptions.$container).html(data.html);
+
+ $container.on('click', '.EDIT_presets_list A.triangle', function () {
+ $(this).parent().parent().toggleClass('opened');
+ return false;
+ }
+ );
+ $container.on('dblclick', '.EDIT_presets_list A.title', function () {
+ var preset_id = $(this).parent().parent().attr('id');
+ if (preset_id.substr(0, 12) === 'EDIT_PRESET_') {
+ _preset_load(preset_id.substr(12));
+ }
+ return false;
+ }
+ );
+ $container.on('click', '.EDIT_presets_list A.delete', function () {
+ var li = $(this).closest('LI');
+ var preset_id = li.attr('id');
+ var title = $(this).parent().children('.title').html();
+ if (preset_id.substr(0, 12) === 'EDIT_PRESET_' && confirm("supprimer le preset '" + title + "' ?")) {
+ _preset_delete(preset_id.substr(12), li);
+ }
+ return false;
+ }
+ );
+ }
+
+ function _preset_copy() {
+ var html = '';
+ let fields = fieldCollection.getFields();
+
+ for (let fieldIndex in fields) {
+ let field = fieldCollection.getFieldByIndex(fieldIndex);
+ if (field._status === 1) {
+ if (field.readonly) {
+ continue;
+ }
+ var c = field._value === '' ? '' : 'checked="1"';
+ html += ' ' + '' + field.label + ' : ';
+ html += cleanTags(field._value) + '
';
+ }
+ }
+ $('#Edit_copyPreset_dlg FORM DIV').html(html);
+ var $dialog = $('#Edit_copyPreset_dlg');
+ if ($dialog.data('ui-dialog')) {
+ // to show dialog on top of edit window
+ $dialog.dialog('widget').css('z-index', 1300);
+ $dialog.dialog('open');
+ }
+ }
+
+ function _preset_delete(presetId, li) {
+ $.ajax({
+ type: 'DELETE',
+ url: `${url}prod/records/edit/presets/${presetId}`,
+ data: {},
+ dataType: 'json',
+ success: function (data, textStatus) {
+ li.remove();
+ }
+ });
+ }
+
+ function _preset_load(presetId) {
+ $.ajax({
+ type: 'GET',
+ url: `${url}prod/records/edit/presets/${presetId}`,
+ data: {},
+ dataType: 'json',
+ success: function (data, textStatus) {
+ if ($('#Edit_copyPreset_dlg').data('ui-dialog')) {
+ $('#Edit_copyPreset_dlg').dialog('close');
+ }
+ let records = recordCollection.getRecords();
+ let fields = fieldCollection.getFields();
+
+ for (let fieldIndex in fields) {
+ let field = fieldCollection.getFieldByIndex(fieldIndex);
+ field.preset = null;
+ if (typeof (data.fields[field.name]) !== 'undefined') {
+ field.preset = data.fields[field.name];
+ }
+ fieldCollection.updateField(fieldIndex, field);
+ }
+ for (let recordIndex in records) {
+ let record = recordCollection.getRecordByIndex(recordIndex);
+ if (!record._selected) {
+ continue;
+ }
+
+ for (let fieldIndex in fields) {
+ let field = fieldCollection.getFieldByIndex(fieldIndex);
+ if (field.preset !== null) {
+ for (let val in field.preset) {
+ // fix : some (old, malformed) presets values may need trim()
+ recordCollection.addRecordFieldValue(recordIndex, fieldIndex, {
+ value: field.preset[val].trim(), merge: false, vocabularyId: null
+ });
+ }
+ }
+ }
+ }
+ recordEditorEvents.emit('recordEditor.onUpdateFields');
+ }
+ });
+ }
+
+ return {initialize};
+};
+export default presetsModule;
diff --git a/Phraseanet-production-client/src/components/record/recordPreview/index.js b/Phraseanet-production-client/src/components/record/recordPreview/index.js
new file mode 100644
index 0000000000..bd9a46515f
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/recordPreview/index.js
@@ -0,0 +1,819 @@
+require('./recordPreview.scss');
+
+import $ from 'jquery';
+import merge from 'lodash.merge';
+import * as Rx from 'rx';
+import Emitter from '../../core/emitter';
+import leafletMap from './../../geolocalisation/providers/mapbox';
+import pym from 'pym.js';
+let image_enhancer = require('imports-loader?$=jquery!../../utils/jquery-plugins/imageEnhancer/imageEnhancer');
+require('./../../../phraseanet-common/components/tooltip');
+const previewRecordService = services => {
+ const { configService, localeService, appEvents } = services;
+ const url = configService.get('baseUrl');
+ let recordPreviewEvents = new Emitter();
+ let $bodyContainer = null;
+ let $previewContainer = null;
+ let $previewTabContainer;
+ let prevAjax;
+ let prevAjaxrunning;
+ let activeThumbnailFrame = false;
+ prevAjaxrunning = false;
+ let stream = new Rx.Subject();
+ let options = {
+ open: false,
+ current: false,
+ slideShow: false,
+ navigation: {
+ perPage: 0,
+ page: 0
+ }
+ };
+ stream.onNext(options);
+ const initialize = () => {
+ $bodyContainer = $('body');
+ $previewContainer = $('#PREVIEWBOX');
+ $previewTabContainer = $('#PREVIEWIMGDESC');
+ $previewTabContainer.tabs({
+ activate: function (event, ui) {
+ recordPreviewEvents.emit('tabChange');
+ }
+ });
+
+ // if contained in record editor (p4.edit.editBox):
+ $('#PREVIEWBOX .gui_vsplitter').draggable({
+ axis: 'x',
+ containment: 'parent',
+ drag: function (event, ui) {
+ var x = $(ui.position.left)[0];
+ if (x < 330 || x > window.bodySize.x - 400) {
+ return false;
+ }
+ var v = $(ui.position.left)[0];
+ $('#PREVIEWLEFT').width(v);
+ $('#PREVIEWRIGHT').css('left', $(ui.position.left)[0]);
+ resizePreview();
+ }
+ });
+ leafletMap({
+ configService,
+ localeService,
+ eventEmitter: recordPreviewEvents
+ }).initialize({
+ $container: $previewContainer,
+ parentOptions: options,
+ searchable: true,
+ tabOptions: {
+ /*tabProperties: {
+ classes: 'descBoxes',
+ },*/
+ position: 3
+ }
+ });
+
+ _bindEvents();
+ };
+
+ const _bindEvents = () => {
+ $bodyContainer
+ .on('click', '.close-preview-action', event => {
+ event.preventDefault();
+ closePreview();
+ })
+ .on('dblclick', '.open-preview-action', event => {
+ let $el = $(event.currentTarget);
+ // env, pos, contId, reload
+ let reload = $el.data('reload') === true ? true : false;
+ _openPreview(
+ event.currentTarget,
+ $el.data('kind'),
+ $el.data('position'),
+ $el.data('id'),
+ $el.data('kind')
+ );
+ })
+ .on('click', '.to-open-preview-action', event => {
+ event.preventDefault();
+ $( '.open-preview-action' ).trigger( "dblclick" );
+ })
+ ;
+ $previewContainer
+ .on('click', '.preview-navigate-action', event => {
+ event.preventDefault();
+ let $el = $(event.currentTarget);
+ let dir =
+ $el.data('direction') === 'forward'
+ ? getNext()
+ : getPrevious();
+ })
+ .on('click', '.preview-start-slideshow-action', event => {
+ event.preventDefault();
+ startSlide();
+ })
+ .on('click', '.preview-stop-slideshow-action', event => {
+ event.preventDefault();
+ stopSlide();
+ })
+ .on('click', '.edit-record-action', event => {
+ if (activeThumbnailFrame !== false) {
+ // tell child iframe to pause:
+ activeThumbnailFrame.sendMessage('pause', 'ok');
+ }
+ event.preventDefault();
+ });
+ };
+
+ /**
+ * Handle global keydown event if preview is open
+ * @param event
+ */
+ const onGlobalKeydown = (event, specialKeyState) => {
+ if (specialKeyState === undefined) {
+ let specialKeyState = {
+ isCancelKey: false,
+ isShortcutKey: false
+ };
+ }
+ if (options.open) {
+ if (
+ $('#dialog_dwnl:visible').length === 0 &&
+ $('#DIALOG1').length === 0 &&
+ $('#DIALOG2').length === 0
+ ) {
+ switch (event.keyCode) {
+ // next
+ case 39:
+ getNext();
+ specialKeyState.isCancelKey = specialKeyState.isShortcutKey = true;
+ break;
+ // previous
+ case 37:
+ getPrevious();
+ specialKeyState.isCancelKey = specialKeyState.isShortcutKey = true;
+ break;
+ case 27: //escape
+ closePreview();
+ break;
+ case 32:
+ var videoElement = $('#PREVIEWIMGCONT iframe').contents().find('video');
+ if (videoElement.length > 0) {
+ if (videoElement.get(0).paused == true) {
+ videoElement.get(0).play();
+ } else {
+ videoElement.get(0).pause();
+ }
+ specialKeyState.isCancelKey = specialKeyState.isShortcutKey = true;
+ }
+ break;
+ default:
+ }
+ }
+ }
+ return specialKeyState;
+ };
+
+ /**
+ *
+ * @param env
+ * @param pos - relative position in current page
+ * @param contId
+ * @param reload
+ */
+ function _openPreview(event, env, pos, contId, reload) {
+ if (contId === undefined) {
+ contId = '';
+ }
+ var roll = 0;
+ var justOpen = false;
+
+ var options_serial = options.navigation.tot_options;
+ var query = options.navigation.tot_query;
+ var navigationContext = '';
+ // keep relative position for answer train:
+ var relativePos = pos;
+ var absolutePos = 0;
+
+ if (!options.open) {
+ $('#PREVIEWIMGCONT').disableSelection();
+
+ justOpen = true;
+
+ if (!navigator.userAgent.match(/msie/i)) {
+ $('#PREVIEWBOX')
+ .css({
+ display: 'block',
+ opacity: 0
+ })
+ .fadeTo(500, 1);
+ } else {
+ $('#PREVIEWBOX').css({
+ display: 'block',
+ opacity: 1
+ });
+ }
+ options.open = true;
+ options.nCurrent = 5;
+ $('#PREVIEWCURRENT, #PREVIEWOTHERSINNER, #SPANTITLE').empty();
+ resizePreview();
+ if (env === 'BASK') {
+ roll = 1;
+ }
+
+ // if comes from story and in workzone
+ if (env === 'REG') {
+ navigationContext = 'storyFromResults';
+ var $source = $(event);
+ if ($source.hasClass('CHIM')) {
+ navigationContext = 'storyFromWorkzone';
+ }
+ }
+ }
+
+ if (reload === true) {
+ roll = 1;
+ }
+
+ $('#tooltip').css({
+ display: 'none'
+ });
+
+ $('#PREVIEWIMGCONT').empty();
+
+ if (navigationContext === 'storyFromWorkzone') {
+ // if event comes from workzone, set to relative position (CHIM == chutier image)
+ absolutePos = relativePos;
+ } else if (navigationContext === 'storyFromResults') {
+ absolutePos = 0;
+ } else {
+ // update real absolute position with pagination for records:
+ absolutePos =
+ parseInt(options.navigation.perPage, 10) *
+ (parseInt(options.navigation.page, 10) - 1) +
+ parseInt(pos, 10);
+ }
+
+ let posAsk = null;
+ prevAjax = $.ajax({
+ type: 'POST',
+ url: `${url}prod/records/`,
+ dataType: 'json',
+ data: {
+ env: env,
+ pos: absolutePos,
+ cont: contId,
+ roll: roll,
+ options_serial: options_serial,
+ query: query
+ },
+ beforeSend: function () {
+ if (prevAjaxrunning) {
+ prevAjax.abort();
+ }
+ if (env === 'RESULT') {
+ $('#current_result_n')
+ .empty()
+ .append(parseInt(pos, 10) + 1);
+ }
+ prevAjaxrunning = true;
+ $('#PREVIEWIMGDESC, #PREVIEWOTHERS').addClass('loading');
+ },
+ error: function (data) {
+ prevAjaxrunning = false;
+ $('#PREVIEWIMGDESC, #PREVIEWOTHERS').removeClass('loading');
+ },
+ timeout: function () {
+ prevAjaxrunning = false;
+ $('#PREVIEWIMGDESC, #PREVIEWOTHERS').removeClass('loading');
+ },
+ success: function (data) {
+ _cancelPreview();
+ prevAjaxrunning = false;
+
+ if (data.error) {
+ $('#PREVIEWIMGDESC, #PREVIEWOTHERS').removeClass('loading');
+ alert(data.error);
+ if (justOpen) {
+ closePreview();
+ }
+ return;
+ }
+ posAsk = data.pos - 1;
+
+ // transform default embed ID in order to avoid conflicts:
+ let customId = 'phraseanet-embed-preview-frame';
+ let $template = $(data.html_preview);
+ $template.find('#phraseanet-embed-frame').attr('id', customId);
+
+ $('#PREVIEWIMGCONT').empty().append($template.get(0));
+ if ($(`#${customId}`).length > 0) {
+ activeThumbnailFrame = new pym.Parent(
+ customId,
+ data.record.preview.url
+ );
+ activeThumbnailFrame.iframe.setAttribute(
+ 'allowfullscreen',
+ ''
+ );
+ //set height of iframe to 100%
+ // activeThumbnailFrame.iframe.setAttribute(
+ // 'height',
+ // '100%'
+ // );
+ /*
+ // warning - if listening events/sendings events,
+ // pym instances should be destroyed when preview is closed
+ activeThumbnailFrame.onMessage('childReady', (child) => {
+ activeThumbnailFrame.sendMessage('parentReady', 'handshake');
+
+ });*/
+ }
+
+ $('#PREVIEWIMGCONT .thumb_wrapper')
+ .width('100%')
+ .height('100%')
+ .image_enhance({ zoomable: true });
+ resizeVideoPreview();
+
+ $('#PREVIEWIMGDESCINNER').empty().append(data.desc);
+ $('#HISTORICOPS').empty().append(data.history);
+ $('#popularity').empty().append(data.popularity);
+
+ if ($('#popularity .bitly_link').length > 0) {
+ if (
+ window.BitlyCB !== undefined &&
+ window.BitlyClient !== undefined
+ ) {
+ window.BitlyCB.statsResponse = function (data) {
+ var result = data.results;
+ if (
+ $('#popularity .bitly_link_' + result.userHash)
+ .length > 0
+ ) {
+ $(
+ '#popularity .bitly_link_' + result.userHash
+ ).append(' (' + result.clicks + ' clicks)');
+ }
+ };
+ window.BitlyClient.stats(
+ $('#popularity .bitly_link').html(),
+ 'BitlyCB.statsResponse'
+ );
+ }
+ }
+
+ options.current = {};
+ options.current.width = parseInt(
+ $('#PREVIEWIMGCONT .thumb_wrapper')
+ .children()
+ .attr('data-original-width'),
+ 10
+ );
+ options.current.height = parseInt(
+ $('#PREVIEWIMGCONT .thumb_wrapper')
+ .children()
+ .attr('data-original-height'),
+ 10
+ );
+ options.current.tot = data.tot;
+ options.current.pos = relativePos;
+ options.current.captions = data.recordCaptions;
+
+ recordPreviewEvents.emit('recordSelection.changed', {
+ selection: [data.recordCaptions]
+ });
+
+ if ($('#PREVIEWBOX img.record.zoomable').length > 0) {
+ $('#PREVIEWBOX img.record.zoomable').draggable();
+ }
+
+ $('#SPANTITLE').empty().append(data.title);
+ $('#PREVIEWTITLE_COLLLOGO')
+ .empty()
+ .append(data.collection_logo);
+ $('#PREVIEWTITLE_COLLNAME')
+ .empty()
+ .append(`${data.databox_name} / ${data.collection_name}`);
+
+ _setPreview();
+
+ if (env !== 'RESULT') {
+ if (justOpen || reload) {
+ _setCurrent(data.current);
+ }
+ _viewCurrent($('#PREVIEWCURRENT li.selected'));
+ } else {
+ if (!justOpen) {
+ $('#PREVIEWCURRENT li.selected').removeClass(
+ 'selected'
+ );
+ $(
+ '#PREVIEWCURRENTCONT li.current' + absolutePos
+ ).addClass('selected');
+ }
+ if (
+ justOpen ||
+ $('#PREVIEWCURRENTCONT li.current' + absolutePos)
+ .length === 0 ||
+ $('#PREVIEWCURRENTCONT li:last')[0] ===
+ $('#PREVIEWCURRENTCONT li.selected')[0] ||
+ $('#PREVIEWCURRENTCONT li:first')[0] ===
+ $('#PREVIEWCURRENTCONT li.selected')[0]
+ ) {
+ _getAnswerTrain(pos, data.tools, query, options_serial);
+ }
+
+ _viewCurrent($('#PREVIEWCURRENT li.selected'));
+ }
+ if (env === 'REG' && $('#PREVIEWCURRENT').html() === '') {
+ _getRegTrain(contId, pos, data.tools);
+ }
+ _setOthers(data.others);
+ _setTools(data.tools);
+ $('#tooltip').css({
+ display: 'none'
+ });
+ $('#PREVIEWIMGDESC, #PREVIEWOTHERS').removeClass('loading');
+ if (!justOpen || options.mode !== env) {
+ resizePreview();
+ }
+
+ options.mode = env;
+ $('#EDIT_query').focus();
+
+ $('#PREVIEWOTHERSINNER .otherBaskToolTip').tooltip();
+ stream.onNext(options);
+ return;
+ }
+ });
+ }
+
+ function resizeVideoPreview() {
+
+ var $sel = $('#phraseanet-embed-preview-frame.videoTips');
+ // V is for "video" ; K is for "container" ; N is for "new"
+ var VW = $sel.data('originalWidth');
+ var VH = $sel.data('originalHeight');
+ var KW = $sel.width();
+ var KH = $sel.height();
+
+ var NW, NH;
+ if( (NH = (VH / VW) * (NW=KW) ) > KH ) { // try to fit exact horizontally, adjust vertically
+ // too bad... new height overflows container height
+ NW = (VW / VH) * (NH=KH); // so fit exact vertically, adjust horizontally
+ }
+ $("iframe", $sel).css('width', NW).css('height', NH);
+
+ }
+
+ function closePreview() {
+ options.open = false;
+ if (activeThumbnailFrame !== false) {
+ // tell child iframe to shutdown:
+ activeThumbnailFrame.sendMessage('dispose', 'ok');
+
+ activeThumbnailFrame = false;
+ }
+ stream.onNext(options);
+ $('#PREVIEWBOX').fadeTo(500, 0);
+ $('#PREVIEWBOX').queue(function () {
+ $(this).css({
+ display: 'none'
+ });
+ _cancelPreview();
+ $(this).dequeue();
+ });
+ }
+
+ function startSlide() {
+ if (!options.slideShow) {
+ options.slideShow = true;
+ }
+ if (options.slideShowCancel) {
+ options.slideShowCancel = false;
+ options.slideShow = false;
+ $('#start_slide').show();
+ $('#stop_slide').hide();
+ }
+ if (!options.open) {
+ options.slideShowCancel = false;
+ options.slideShow = false;
+ $('#start_slide').show();
+ $('#stop_slide').hide();
+ }
+ if (options.slideShow) {
+ $('#start_slide').hide();
+ $('#stop_slide').show();
+ getNext();
+ setTimeout(
+ () => startSlide(),
+ configService.get('previewSlideshow.duration')
+ );
+ }
+ }
+
+ function stopSlide() {
+ options.slideShowCancel = true;
+ $('#start_slide').show();
+ $('#stop_slide').hide();
+ }
+
+ function getNext() {
+ if (options.mode === 'REG' && parseInt(options.current.pos, 10) === 0) {
+ $('#PREVIEWCURRENTCONT li img:first').trigger('click');
+ } else {
+ if (options.mode === 'RESULT') {
+ let posAsk = parseInt(options.current.pos, 10) + 1;
+ posAsk =
+ posAsk >= parseInt(options.navigation.tot, 10) ||
+ isNaN(posAsk)
+ ? 0
+ : posAsk;
+ _openPreview(false, 'RESULT', posAsk, '', false);
+ } else {
+ if (!$('#PREVIEWCURRENT li.selected').is(':last-child')) {
+ $('#PREVIEWCURRENT li.selected')
+ .next()
+ .children('img')
+ .trigger('click');
+ } else {
+ $('#PREVIEWCURRENT li:first-child')
+ .children('img')
+ .trigger('click');
+ }
+ }
+ }
+ }
+
+ function getPrevious() {
+ if (options.mode === 'RESULT') {
+ let posAsk = parseInt(options.current.pos, 10) - 1;
+ if (options.navigation.page === 1) {
+ // may go to last result
+ posAsk =
+ posAsk < 0
+ ? parseInt(options.navigation.tot, 10) - 1
+ : posAsk;
+ }
+ _openPreview(false, 'RESULT', posAsk, '', false);
+ } else {
+ if (!$('#PREVIEWCURRENT li.selected').is(':first-child')) {
+ $('#PREVIEWCURRENT li.selected')
+ .prev()
+ .children('img')
+ .trigger('click');
+ } else {
+ $('#PREVIEWCURRENT li:last-child')
+ .children('img')
+ .trigger('click');
+ }
+ }
+ }
+
+ function _setPreview() {
+ if (!options.current) {
+ return;
+ }
+
+ var zoomable = $('img.record.zoomable');
+ if (zoomable.length > 0 && zoomable.hasClass('zoomed')) {
+ return;
+ }
+
+ var h = parseInt(options.current.height, 10);
+ var w = parseInt(options.current.width, 10);
+ var t = 20;
+ var de = 0;
+
+ var margX = 0;
+ var margY = 0;
+
+ if ($('#PREVIEWIMGCONT .record_audio').length > 0) {
+ margY = 100;
+ de = 60;
+ }
+
+ var ratioP = w / h;
+ var ratioD = parseInt(options.width, 10) / parseInt(options.height, 10);
+
+ if (ratioD > ratioP) {
+ //je regle la hauteur d'abord
+ if (parseInt(h, 10) + margY > parseInt(options.height, 10)) {
+ h = Math.round(parseInt(options.height, 10) - margY);
+ w = Math.round(h * ratioP);
+ }
+ } else {
+ if (parseInt(w, 10) + margX > parseInt(options.width, 10)) {
+ w = Math.round(parseInt(options.width, 10) - margX);
+ h = Math.round(w / ratioP);
+ }
+ }
+
+ t = Math.round((parseInt(options.height, 10) - h - de) / 2);
+ var l = Math.round((parseInt(options.width, 10) - w) / 2);
+ $('#PREVIEWIMGCONT .record')
+ .css({
+ width: w,
+ height: h,
+ top: t,
+ left: l
+ })
+ .attr('width', w)
+ .attr('height', h);
+ }
+
+ function _setCurrent(current) {
+ if (current !== '') {
+ var el = $('#PREVIEWCURRENT');
+ el.removeClass('loading').empty().append(current);
+
+ $('ul', el).width($('li', el).length * 80);
+ $('img.prevRegToolTip', el).tooltip();
+ $.each($('img.openPreview'), function (i, el) {
+ var jsopt = $(el).attr('jsargs').split('|');
+ $(el).removeAttr('jsargs');
+ $(el).removeClass('openPreview');
+ $(el).bind('click', function () {
+ _viewCurrent($(this).parent());
+ // convert abssolute to relative position
+ var absolutePos = jsopt[1];
+ var relativePos =
+ parseInt(absolutePos, 10) -
+ parseInt(options.navigation.perPage, 10) *
+ (parseInt(options.navigation.page, 10) - 1);
+ // keep relative position for answer train:
+ _openPreview(this, jsopt[0], relativePos, jsopt[2], false);
+ });
+ });
+ }
+ }
+
+ function _viewCurrent(el) {
+ if (el.length === 0) {
+ return;
+ }
+ $('#PREVIEWCURRENT li.selected').removeClass('selected');
+ el.addClass('selected');
+ $('#PREVIEWCURRENTCONT').animate({
+ scrollLeft:
+ $('#PREVIEWCURRENT li.selected').position().left +
+ $('#PREVIEWCURRENT li.selected').width() / 2 -
+ $('#PREVIEWCURRENTCONT').width() / 2
+ });
+ return;
+ }
+
+ function reloadPreview() {
+ $('#PREVIEWCURRENT li.selected img').trigger('click');
+ }
+
+ function _getAnswerTrain(pos, tools, query, options_serial) {
+ // keep relative position for answer train:
+ var relativePos = pos;
+ // update real absolute position with pagination:
+ var absolutePos =
+ parseInt(options.navigation.perPage, 10) *
+ (parseInt(options.navigation.page, 10) - 1) +
+ parseInt(pos, 10);
+
+ $('#PREVIEWCURRENTCONT').fadeOut('fast');
+ $.ajax({
+ type: 'POST',
+ url: `${url}prod/query/answer-train/`,
+ dataType: 'json',
+ data: {
+ pos: absolutePos,
+ options_serial: options_serial,
+ query: query
+ },
+ success: function (data) {
+ _setCurrent(data.current);
+ _viewCurrent($('#PREVIEWCURRENT li.selected'));
+ _setTools(tools);
+ return;
+ }
+ });
+ }
+
+ function _getRegTrain(contId, pos, tools) {
+ $.ajax({
+ type: 'POST',
+ url: `${url}prod/query/reg-train/`,
+ dataType: 'json',
+ data: {
+ cont: contId,
+ pos: pos
+ },
+ success: function (data) {
+ _setCurrent(data.current);
+ _viewCurrent($('#PREVIEWCURRENT li.selected'));
+ if (typeof tools !== 'undefined') {
+ _setTools(tools);
+ }
+ return;
+ }
+ });
+ }
+
+ function _cancelPreview() {
+ $('#PREVIEWIMGDESCINNER').empty();
+ $('#PREVIEWIMGCONT').empty();
+ options.current = false;
+ }
+
+ function _setOthers(others) {
+ $('#PREVIEWOTHERSINNER').empty();
+ if (others !== '') {
+ $('#PREVIEWOTHERSINNER').append(others);
+
+ $('#PREVIEWOTHERS table.otherRegToolTip').tooltip();
+ }
+ }
+
+ function _setTools(tools) {
+ $('#PREVIEWTOOL').empty().append(tools);
+ if (!options.slideShowCancel && options.slideShow) {
+ $('#start_slide').hide();
+ $('#stop_slide').show();
+ } else {
+ $('#start_slide').show();
+ $('#stop_slide').hide();
+ }
+ }
+
+ function resizePreview() {
+ options.height = $('#PREVIEWIMGCONT').height();
+ options.width = $('#PREVIEWIMGCONT').width();
+
+ resizeVideoPreview();
+ _setPreview();
+ }
+
+ const shouldResize = () => {
+ if (options.open) {
+ resizePreview();
+ }
+ };
+
+ const shouldReload = () => {
+ if (options.open) {
+ reloadPreview();
+ }
+ };
+
+ const onNavigationChanged = (navigation = {}) => {
+ options.navigation = merge(options.navigation, navigation);
+ };
+
+ const appendTab = params => {
+ let { tabProperties, position } = params;
+ const $appendAfterTab = $(
+ `ul li:eq(${position - 1})`,
+ $previewTabContainer
+ );
+
+ const newTab = `${tabProperties.title} `;
+ $appendAfterTab.after(newTab);
+
+ const appendAfterTabContent = $(
+ ` > div:eq(${position - 1})`,
+ $previewTabContainer
+ );
+ appendAfterTabContent.after(
+ `
`
+ );
+
+ try {
+ $previewTabContainer.tabs('refresh');
+ } catch (e) {}
+ recordPreviewEvents.emit('appendTab.complete', {
+ origParams: params,
+ selection: []
+ });
+ };
+
+ appEvents.listenAll({
+ 'broadcast.searchResultNavigation': onNavigationChanged,
+ 'preview.doResize': shouldResize,
+ 'preview.doReload': shouldReload,
+ 'preview.close': closePreview
+ });
+
+ recordPreviewEvents.listenAll({
+ /* eslint-disable quote-props */
+ appendTab: appendTab
+ });
+
+ return {
+ initialize,
+ onGlobalKeydown,
+ getPreviewStream: () => stream,
+ //_openPreview,
+ startSlide,
+ stopSlide,
+ getNext,
+ getPrevious,
+ reloadPreview,
+ resizePreview
+ };
+};
+export default previewRecordService;
diff --git a/Phraseanet-production-client/src/components/record/recordPreview/recordPreview.scss b/Phraseanet-production-client/src/components/record/recordPreview/recordPreview.scss
new file mode 100644
index 0000000000..c18283d52f
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/recordPreview/recordPreview.scss
@@ -0,0 +1,14 @@
+#PREVIEWIMGDESC #leafletTabContainer {
+ top: 30px;
+ left: 0;
+ bottom: 0;
+ position: absolute;
+ height: auto;
+ width: 100%;
+ overflow: hidden;
+}
+
+#PREVIEWIMGDESC #leafletTabContainer .leaflet-container {
+ overflow: hidden;
+ position: initial !important;
+}
\ No newline at end of file
diff --git a/Phraseanet-production-client/src/components/record/recordPush/addUser.js b/Phraseanet-production-client/src/components/record/recordPush/addUser.js
new file mode 100644
index 0000000000..8d0b5baa5a
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/recordPush/addUser.js
@@ -0,0 +1,140 @@
+/**
+ * triggered via workzone > Basket > context menu
+ */
+import $ from 'jquery';
+import * as _ from 'underscore';
+import dialog from './../../../phraseanet-common/components/dialog';
+import merge from 'lodash.merge';
+require('geonames-server-jquery-plugin/jquery.geonames.js');
+
+const pushAddUser = (services) => {
+ const { configService, localeService, appEvents } = services;
+ const url = configService.get('baseUrl');
+ let searchSelectionSerialized = '';
+ appEvents.listenAll({
+ 'broadcast.searchResultSelection': (selection) => {
+ searchSelectionSerialized = selection.serialized;
+ }
+ });
+
+ const initialize = (options) => {
+ let {$container} = options;
+
+ $container.on('click', '.push-add-user', (event) => {
+ event.preventDefault();
+ const $el = $(event.currentTarget);
+ let dialogOptions = {};
+
+ if ($el.attr('title') !== undefined) {
+ dialogOptions.title = $el.html;
+ }
+
+ if($el.hasClass('validation')) {
+ dialogOptions.isValidation = true;
+ }
+
+ if($el.hasClass('listmanager-add-user')) {
+ dialogOptions.isListManager = true;
+ }
+
+ openModal(dialogOptions);
+ });
+ };
+
+ const openModal = (options = {}) => {
+ const url = configService.get('baseUrl');
+ let dialogOptions = merge({
+ size: '558x305',
+ loading: false,
+ title: localeService.t('create new user'),
+ }, options);
+ const $dialog = dialog.create(services, dialogOptions, 2);
+ $dialog.getDomElement().closest('.ui-dialog').addClass('dialog_container');
+
+ if(dialogOptions.isValidation) {
+ $dialog.getDomElement().closest('.ui-dialog').addClass('validation');
+ }
+
+ if(dialogOptions.isListManager) {
+ $dialog.getDomElement().closest('.ui-dialog').addClass('push-add-user-listmanager');
+ }
+
+ return $.get(`${url}prod/push/add-user/`, function (data) {
+ $dialog.setContent(data);
+ _onDialogReady(window.addUserConfig);
+ return;
+ });
+ };
+
+ const _onDialogReady = (config) => {
+ const $addUserForm = $('#quickAddUser');
+ const $addUserFormMessages = $addUserForm.find('.messages');
+
+ var closeModal = function () {
+ var $dialog = $addUserForm.closest('.ui-dialog-content');
+ if ($dialog.data('ui-dialog')) {
+ $dialog.dialog('destroy').remove();
+ }
+ };
+
+ var submitAddUser = function () {
+ $addUserFormMessages.empty();
+ var method = $addUserForm.attr('method');
+
+ method = $.inArray(method.toLowerCase(), ['post', 'get']) ? method : 'POST';
+ $.ajax({
+ type: method,
+ url: $addUserForm.attr('action'),
+ data: $addUserForm.serializeArray(),
+ beforeSend: function () {
+ $addUserForm.addClass('loading');
+ },
+ success: function (datas) {
+ if (datas.success === true) {
+ appEvents.emit('push.addUser', {
+ $userForm: $addUserForm,
+ callback: closeModal()
+ })
+ //p4.Feedback.addUser($addUserForm, closeModal);
+ } else {
+ if (datas.message !== undefined) {
+ $addUserFormMessages.empty().append('' + datas.message + '
');
+ }
+ }
+ $addUserForm.removeClass('loading');
+ },
+ error: function () {
+ $addUserForm.removeClass('loading');
+ },
+ timeout: function () {
+ $addUserForm.removeClass('loading');
+ }
+ });
+ };
+ if (config.geonameServerUrl.length > 0) {
+ $addUserForm.find('.geoname_field').geocompleter({
+ server: config.geonameServerUrl,
+ limit: 40
+ });
+ }
+ $addUserForm.on('submit', function (event) {
+ event.preventDefault();
+ submitAddUser();
+ });
+
+ $addUserForm.on('click', '.valid', function (event) {
+ event.preventDefault();
+ submitAddUser();
+ });
+
+ $addUserForm.on('click', '.cancel', function (event) {
+ event.preventDefault();
+ closeModal();
+ return false;
+ });
+ };
+
+ return {initialize};
+};
+
+export default pushAddUser;
diff --git a/Phraseanet-production-client/src/components/record/recordPush/feedback.js b/Phraseanet-production-client/src/components/record/recordPush/feedback.js
new file mode 100644
index 0000000000..6b2b923be8
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/recordPush/feedback.js
@@ -0,0 +1,534 @@
+import $ from 'jquery';
+import { Lists } from '../../list/model/index';
+import dialog from './../../../phraseanet-common/components/dialog';
+import Selectable from '../../utils/selectable';
+import pushAddUser from './addUser';
+import * as _ from 'underscore';
+const humane = require('humane-js');
+require('./../../../phraseanet-common/components/tooltip');
+
+const Feedback = function (services, options) {
+ const { configService, localeService, appEvents } = services;
+ const url = configService.get('baseUrl');
+ let $container;
+ let { containerId, context } = options;
+
+ this.url = url;
+ this.container = $container = $(containerId);
+ this.userList = new Lists();
+
+ this.Context = context;
+
+ this.selection = new Selectable(services,
+ $('.user_content .badges', this.container),
+ {
+ selector: '.badge'
+ }
+ );
+
+ pushAddUser(services).initialize({$container: this.container});
+
+ var $this = this;
+
+ this.container.on('mouseenter', '.list-trash-btn', function (event) {
+ var $el = $(event.currentTarget);
+ $el.find('.image-normal').hide();
+ $el.find('.image-hover').show();
+ });
+
+ this.container.on('mouseleave', '.list-trash-btn', function (event) {
+ var $el = $(event.currentTarget);
+ $el.find('.image-normal').show();
+ $el.find('.image-hover').hide();
+ });
+
+ this.container.on('click', '.list-trash-btn', function (event) {
+ var $el = $(event.currentTarget);
+ var list_id = $el.parent().data('list-id');
+
+ appEvents.emit('push.removeList', {
+ list_id: list_id,
+ container: containerId
+ }
+ );
+ });
+
+ this.container.on('click', '.push-refresh-list-action', function (event) {
+ event.preventDefault();
+
+ var callback = function callback(datas) {
+ var context = $(datas);
+ var dataList = $(context).find('.lists').prop('outerHTML');
+
+ var refreshContent = $('.LeftColumn .content .lists', $container);
+ refreshContent.removeClass('loading').append(dataList);
+ };
+
+ $('.LeftColumn .content .lists', $container).empty().addClass('loading');
+
+ $this.userList.get(callback, 'html');
+ });
+
+
+ this.container.on('click', '.content .options .select-all', function (event) {
+ $this.selection.selectAll();
+ });
+
+ this.container.on('click', '.content .options .unselect-all', function (event) {
+ $this.selection.empty();
+ });
+
+ this.container.on('click', '.content .options .delete-selection', function (event) {
+ _.each($('.badges.selectionnable').children(), function(item) {
+ var $elem = $(item);
+ if($elem.hasClass('selected')) {
+ $elem.fadeOut(function () {
+ $elem.remove();
+ });
+ }
+ });
+ return false;
+ });
+
+ $('.UserTips', this.container).tooltip();
+
+ /*this.container.on('click', '.user_adder', function (event) {
+ event.preventDefault();
+ const url = configService.get('baseUrl');
+ var $this = $(this);
+
+ $.ajax({
+ type: 'GET',
+ url: `${url}prod/push/add-user/`,
+ dataType: 'html',
+ beforeSend: function () {
+ var options = {
+ size: 'Medium',
+ title: $this.html()
+ };
+ dialog.create(services, options, 2).getDomElement().addClass('loading');
+ },
+ success: function (data) {
+ dialog.get(2).getDomElement().removeClass('loading').empty().append(data);
+ return;
+ },
+ error: function () {
+ dialog.get(2).close();
+ return;
+ },
+ timeout: function () {
+ dialog.get(2).close();
+ return;
+ }
+ });
+
+ return false;
+ });*/
+
+ this.container.on('click', '.recommended_users', function (event) {
+ var usr_id = $('input[name="usr_id"]', $(this)).val();
+
+ $this.loadUser(usr_id, $this.selectUser);
+
+ return false;
+ });
+
+ this.container.on('click', '.recommended_users_list', function (event) {
+
+ var content = $('#push_user_recommendations').html();
+
+ var options = {
+ size: 'Small',
+ title: $(this).attr('title')
+ };
+
+ let $dialog = dialog.create(services, options, 2);
+ $dialog.setContent(content);
+
+ $dialog.getDomElement().find('a.adder').bind('click', function () {
+
+ $(this).addClass('added');
+
+ var usr_id = $(this).closest('tr').find('input[name="usr_id"]').val();
+
+ $this.loadUser(usr_id, $this.selectUser);
+
+ return false;
+ });
+
+ $dialog.getDomElement().find('a.adder').each(function (i, el) {
+
+ var usr_id = $(this).closest('tr').find('input[name="usr_id"]').val();
+
+ if ($('.badge_' + usr_id, $this.container).length > 0) {
+ $(this).addClass('added');
+ }
+
+ });
+
+
+ return false;
+ });
+
+ //this.container.on('submit', '#PushBox form[name="FeedBackForm"]', function (event) {
+ $('#PushBox form[name="FeedBackForm"]').bind('submit', function () {
+
+ var $this = $(this);
+
+ $.ajax({
+ type: $this.attr('method'),
+ url: $this.attr('action'),
+ dataType: 'json',
+ data: $this.serializeArray(),
+ beforeSend: function () {
+
+ },
+ success: function (data) {
+ if (data.success) {
+ humane.info(data.message);
+ dialog.close(1);
+ appEvents.emit('workzone.refresh');
+ } else {
+ humane.error(data.message);
+ }
+ return;
+ },
+ error: function () {
+
+ return;
+ },
+ timeout: function () {
+
+ return;
+ }
+ });
+
+ return false;
+ });
+
+ $('.FeedbackSend', this.container).bind('click', function (event) {
+ if ($('.badges .badge', $container).length === 0) {
+ alert(localeService.t('FeedBackNoUsersSelected'));
+ return;
+ }
+
+ var buttons = {};
+
+ buttons[localeService.t('annuler')] = function () {
+ $dialog.close();
+ };
+
+ buttons[localeService.t('send')] = function () {
+ if ($.trim($('input[name="name"]', $dialog.getDomElement()).val()) === '') {
+ var options = {
+ size: 'Alert',
+ closeButton: true,
+ title: localeService.t('warning')
+ };
+ var $dialogAlert = dialog.create(services, options, 3);
+ $dialogAlert.setContent(localeService.t('FeedBackNameMandatory'));
+
+ return false;
+ }
+
+ $dialog.close();
+
+ $('input[name="name"]', $FeedBackForm).val($('input[name="name"]', $dialog.getDomElement()).val());
+ $('input[name="duration"]', $FeedBackForm).val($('select[name="duration"]', $dialog.getDomElement()).val());
+ $('textarea[name="message"]', $FeedBackForm).val($('textarea[name="message"]', $dialog.getDomElement()).val());
+ $('input[name="recept"]', $FeedBackForm).prop('checked', $('input[name="recept"]', $dialog.getDomElement()).prop('checked'));
+ $('input[name="force_authentication"]', $FeedBackForm).prop('checked', $('input[name="force_authentication"]', $dialog.getDomElement()).prop('checked'));
+
+ $FeedBackForm.trigger('submit');
+ };
+
+
+ var options = {
+ size: '558x352',
+ buttons: buttons,
+ loading: true,
+ title: localeService.t('send'),
+ closeOnEscape: true,
+ };
+
+ const $el = $(event.currentTarget);
+ if($el.hasClass('validation')) {
+ options.isValidation = true;
+ options.size = '558x415'
+ }
+
+ var $dialog = dialog.create(services, options, 2);
+
+ $dialog.getDomElement().closest('.ui-dialog').addClass('dialog_container');
+ if(options.isValidation) {
+ $dialog.getDomElement().closest('.ui-dialog').addClass('validation');
+ }
+
+
+ var $FeedBackForm = $('form[name="FeedBackForm"]', $container);
+
+ var html = _.template($('#feedback_sendform_tpl').html());
+
+ $dialog.setContent(html);
+
+ var feedbackTitle = $('#feedbackTitle').val();
+ var pushTitle = $('#pushTitle').val();
+ if (options.isValidation) {
+ $('input[name="name"]').attr("placeholder", feedbackTitle);
+ }else {
+ $('input[name="name"]').attr("placeholder", pushTitle);
+ }
+
+ $('input[name="name"]', $dialog.getDomElement()).val($('input[name="name"]', $FeedBackForm).val());
+ $('textarea[name="message"]', $dialog.getDomElement()).val($('textarea[name="message"]', $FeedBackForm).val());
+ $('.' + $this.Context, $dialog.getDomElement()).show();
+
+ $('form', $dialog.getDomElement()).submit(function () {
+ return false;
+ });
+ });
+
+ $('.user_content .badges', this.container).disableSelection();
+
+
+ // toggle download feature for users
+ this.container.on('click', '.user_content .badges .badge .toggle', function (event) {
+ var $this = $(this);
+
+ $this.toggleClass('status_off status_on');
+
+ $this.find('input').val($this.hasClass('status_on') ? '1' : '0');
+
+ return false;
+ });
+
+ this.container.on('mouseenter', '#info-box-trigger', function(event) {
+ $('#info-box').show();
+ });
+
+ this.container.on('mouseleave', '#info-box-trigger', function(event) {
+ $('#info-box').hide();
+ });
+
+ // toggle feature state of selected users
+ this.container.on('click', '.general_togglers .general_toggler', function (event) {
+ var feature = $(this).attr('feature');
+
+ var $badges = $('.user_content .badge.selected', this.container);
+
+ var toggles = $('.status_off.toggle_' + feature, $badges);
+
+ if (toggles.length === 0) {
+ toggles = $('.status_on.toggle_' + feature, $badges);
+ }
+ if (toggles.length === 0) {
+ humane.info('No user selected');
+ }
+
+ toggles.trigger('click');
+ return false;
+ });
+
+ this.container.on('click', '.user_content .badges .badge .deleter', function (event) {
+ var $elem = $(this).closest('.badge');
+ $elem.fadeOut(function () {
+ $elem.remove();
+ });
+ return false;
+ });
+
+ this.container.on('click', '.list_manager', function (event) {
+ $('#PushBox').hide();
+ $('#ListManager').show();
+ return false;
+ });
+
+ this.container.on('click', 'a.list_push_loader', function (event) {
+ var url = $(this).attr('href');
+
+ var callbackList = function (list) {
+ for (let i in list.entries) {
+ this.selectUser(list.entries[i].User);
+ }
+ };
+
+ $this.loadList(url, callbackList);
+
+ return false;
+ });
+
+
+ $('form.list_saver', this.container).bind('submit', () => {
+ var $form = $(event.currentTarget);
+ var $input = $('input[name="name"]', $form);
+
+ var users = this.getUsers();
+
+ if (users.length === 0) {
+ humane.error('No users');
+ return false;
+ }
+
+ // appEvents.emit('push.createList', {name: $input.val(), collection: users});
+ $this.createList({ name: $input.val(), collection: users });
+ $input.val('');
+ /*
+ p4.Lists.create($input.val(), function (list) {
+ $input.val('');
+ list.addUsers(users);
+ });*/
+
+ return false;
+ });
+
+ $('input[name="users-search"]', this.container).autocomplete({
+ minLength: 2,
+ source: function (request, response) {
+ $.ajax({
+ url: `${url}prod/push/search-user/`,
+ dataType: 'json',
+ data: {
+ query: request.term
+ },
+ success: function (data) {
+ response(data);
+ }
+ });
+ },
+ focus: function (event, ui) {
+ // $('input[name="users-search"]').val(ui.item.label);
+ },
+ select: function (event, ui) {
+ if (ui.item.type === 'USER') {
+ $this.selectUser(ui.item);
+ } else if (ui.item.type === 'LIST') {
+ for (let e in ui.item.entries) {
+ $this.selectUser(ui.item.entries[e].User);
+ }
+ }
+ return false;
+ }
+ })
+ .data('ui-autocomplete')._renderItem = function (ul, item) {
+ var html = '';
+
+ if (item.type === 'USER') {
+ html = _.template($('#list_user_tpl').html())({
+ item: item
+ });
+
+ if ($this.Context === 'Push') {
+ setTimeout(() => {
+ $('.ui-menu .ui-menu-item a').css('box-shadow', 'inset 0 -1px #2196f3');
+ $('img[src="/assets/common/images/icons/user-orange.png"]').attr('src', '/assets/common/images/icons/user-blue.png');
+ }, 100);
+ }
+ else if ($this.Context === 'Feedback') {
+ setTimeout(() => {
+ $('.ui-menu .ui-menu-item a').css('box-shadow', 'inset 0 -1px #8bc34a');
+ $('img[src="/assets/common/images/icons/user-orange.png"]').attr('src', '/assets/common/images/icons/user-green.png');
+ }, 100);
+ }
+ }
+ else if (item.type === 'LIST') {
+ html = _.template($('#list_list_tpl').html())({
+ item: item
+ });
+ }
+
+ return $(html).data('ui-autocomplete-item', item).appendTo(ul);
+ };
+
+ return this;
+};
+
+Feedback.prototype = {
+ selectUser: function (user) {
+ if (typeof user !== 'object') {
+ if (window.console) {
+ console.log('trying to select a user with wrong datas');
+ }
+ }
+ if ($('.badge_' + user.usr_id, this.container).length > 0) {
+ humane.info('User already selected');
+ return;
+ }
+
+ var html = _.template($('#' + this.Context.toLowerCase() + '_badge_tpl').html())({
+ user: user
+ });
+
+ // p4.Feedback.appendBadge(html);
+ this.appendBadge(html);
+ },
+ loadUser: function (usr_id, callback) {
+ var $this = this;
+ $.ajax({
+ type: 'GET',
+ url: `${this.url}prod/push/user/${usr_id}/`,
+ dataType: 'json',
+ data: {
+ usr_id: usr_id
+ },
+ success: function (data) {
+ if (typeof callback === 'function') {
+ callback.call($this, data);
+ }
+ }
+ });
+ },
+ createList: function (options) {
+ let { name, collection } = options;
+
+ this.userList.create(name, function (list) {
+ list.addUsers(collection);
+ });
+ },
+ loadList: function (url, callback) {
+ var $this = this;
+
+ $.ajax({
+ type: 'GET',
+ url: url,
+ dataType: 'json',
+ success: function (data) {
+ if (typeof callback === 'function') {
+ callback.call($this, data);
+ }
+ }
+ });
+ },
+ appendBadge: function (badge) {
+ $('.user_content .badges', this.container).append(badge);
+ },
+ addUser: function (options) {
+ let {$userForm, callback} = options;
+ var $this = this;
+ $.ajax({
+ type: 'POST',
+ url: `${this.url}prod/push/add-user/`,
+ dataType: 'json',
+ data: $userForm.serializeArray(),
+ success: function (data) {
+ if (data.success) {
+ humane.info(data.message);
+ $this.selectUser(data.user);
+ callback;
+ } else {
+ humane.error(data.message);
+ }
+ }
+ });
+ },
+ getSelection: function () {
+ return this.selection;
+ },
+ getUsers: function () {
+ return $('.user_content .badge', this.container).map(function () {
+ return $('input[name="id"]', $(this)).val();
+ });
+ }
+};
+
+
+export default Feedback;
diff --git a/Phraseanet-production-client/src/components/record/recordPush/index.js b/Phraseanet-production-client/src/components/record/recordPush/index.js
new file mode 100644
index 0000000000..7b30c03490
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/recordPush/index.js
@@ -0,0 +1,101 @@
+import $ from 'jquery';
+import Feedback from './feedback';
+import ListManager from './../../list/listManager';
+import dialog from './../../../phraseanet-common/components/dialog';
+const pushRecord = (services) => {
+ const {configService, localeService, appEvents} = services;
+ let feedbackInstance = null;
+ let listManagerInstance = null;
+
+ const initialize = (options) => {
+ let {feedback, listManager} = options;
+ if ($('#PushBox').length > 0) {
+ feedbackInstance = new Feedback(services, feedback);
+ listManagerInstance = new ListManager(services, listManager);
+ } else {
+ $('.close-dialog-action').on('click', () => dialog.close('1'))
+ }
+ };
+
+ function reloadBridge(url) {
+ var options = $('#dialog_publicator form[name="current_datas"]').serializeArray();
+ var dialog = dialog.get(1);
+ dialog.load(url, 'POST', options);
+ }
+
+ function createList(listOptions) {
+ listManagerInstance.createList(listOptions);
+ }
+
+ function addUser(userOptions) {
+ feedbackInstance.addUser(userOptions);
+ }
+
+ function setActiveList() {
+
+ }
+
+ function removeList(listObj) {
+ var makeDialog = function (box) {
+
+ var buttons = {};
+
+ buttons[localeService.t('valider')] = function () {
+
+ var callbackOK = function () {
+ $('.list-container ul.list').children().each(function() {
+ if($(this).data('list-id') == listObj.list_id) {
+ $(this).remove();
+ }
+ });
+ dialog.get(2).close();
+ };
+
+ listManagerInstance.removeList(listObj.list_id, callbackOK);
+ };
+
+ var options = {
+ title: localeService.t('Delete the list'),
+ cancelButton: true,
+ buttons: buttons,
+ size: 'Alert'
+ };
+
+ const $dialog = dialog.create(services, options, 2);
+ if(listObj.container === '#ListManager') {
+ $dialog.getDomElement().closest('.ui-dialog').addClass('dialog_delete_list_listmanager');
+ }
+ $dialog.getDomElement().closest('.ui-dialog').addClass('dialog_container dialog_delete_list')
+ .find('.ui-dialog-buttonset button')
+ .each( function() {
+ var self = $(this).children();
+ if(self.text() === 'Validate') self.text('Yes')
+ else self.text('No');
+ });
+ $dialog.setContent(box);
+ };
+
+ var html = _.template($('#list_editor_dialog_delete_tpl').html());
+
+ makeDialog(html);
+ }
+
+ appEvents.listenAll({
+ // 'push.doInitialize': initialize,
+ 'push.addUser': addUser,
+ 'push.setActiveList': setActiveList,
+ 'push.createList': createList,
+ 'push.reload': reloadBridge,
+ 'push.removeList': removeList
+ });
+
+ return {
+ initialize,
+ // Feedback: Feedback,
+ // ListManager: ListManager,
+ reloadBridge: reloadBridge,
+ };
+
+};
+
+export default pushRecord;
diff --git a/Phraseanet-production-client/src/components/record/removeFromBasket.js b/Phraseanet-production-client/src/components/record/removeFromBasket.js
new file mode 100644
index 0000000000..bf2de6ff67
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/removeFromBasket.js
@@ -0,0 +1,20 @@
+import $ from 'jquery';
+
+const removeFromBasket = (services) => {
+ const { configService, localeService, appEvents } = services;
+ let $container = null;
+ const initialize = () => {
+ $container = $('body');
+ $container.on('click', '.record-remove-from-basket-action', (event) => {
+ event.preventDefault();
+ appEvents.emit('workzone.doRemoveFromBasket', {
+ event: event.currentTarget,
+ confirm: false
+ });
+ });
+ };
+
+ return { initialize };
+};
+
+export default removeFromBasket;
diff --git a/Phraseanet-production-client/src/components/record/share.js b/Phraseanet-production-client/src/components/record/share.js
new file mode 100644
index 0000000000..193389543b
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/share.js
@@ -0,0 +1,78 @@
+import $ from 'jquery';
+import dialog from './../../phraseanet-common/components/dialog';
+const shareRecord = (services) => {
+ const { configService, localeService, appEvents } = services;
+ const url = configService.get('baseUrl');
+ let $container = null;
+ const initialize = (options) => {
+ let {$container} = options;
+ $container.on('click', '.share-record-action', function (event) {
+ event.preventDefault();
+ let $el = $(event.currentTarget);
+ let db = $el.data('db');
+ let recordId = $el.data('record-id');
+
+ doShare(db, recordId);
+ });
+ };
+
+ const doShare = (bas, rec) => {
+ var $dialog = dialog.create(services, {
+ size: 'Medium',
+ title: localeService.t('share')
+ });
+
+ $.ajax({
+ type: 'GET',
+ url: `${url}prod/share/record/${bas}/${rec}/`,
+ //dataType: 'html',
+ success: function (data) {
+ $dialog.setContent(data);
+ _onShareReady();
+ }
+ });
+
+ return true;
+ };
+
+ const _onShareReady = () => {
+ $('input.ui-state-default').hover(
+ function () {
+ $(this).addClass('ui-state-hover');
+ },
+ function () {
+ $(this).removeClass('ui-state-hover');
+ }
+ );
+
+ $('#permalinkUrlCopy').on('click', function (event) {
+ event.preventDefault();
+ return copyElContentClipboard('permalinkUrl');
+ });
+
+ $('#permaviewUrlCopy').on('click', function (event) {
+ event.preventDefault();
+ return copyElContentClipboard('permaviewUrl');
+ });
+
+ $('#embedCopy').on('click', function (event) {
+ event.preventDefault();
+ return copyElContentClipboard('embedRecordUrl');
+ });
+
+ var copyElContentClipboard = function (elId) {
+ var copyEl = document.getElementById(elId);
+ copyEl.select();
+ try {
+ var successful = document.execCommand('copy');
+ var msg = successful ? 'successful' : 'unsuccessful';
+ } catch (err) {
+ console.log('unable to copy');
+ }
+ }
+ }
+
+ return {initialize};
+};
+
+export default shareRecord;
diff --git a/Phraseanet-production-client/src/components/record/tools/index.js b/Phraseanet-production-client/src/components/record/tools/index.js
new file mode 100644
index 0000000000..8343e2a825
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/tools/index.js
@@ -0,0 +1,110 @@
+import $ from 'jquery';
+import dialog from './../../../phraseanet-common/components/dialog';
+import sharingManager from './sharingManager';
+import * as Rx from 'rx';
+
+const humane = require('humane-js');
+
+const recordToolsModal = (services, datas, activeTab = false) => {
+ const {configService, localeService, appEvents} = services;
+ const url = configService.get('baseUrl');
+ let $dialog = null;
+ let toolsStream = new Rx.Subject();
+
+ toolsStream.subscribe((params) => {
+ switch (params.action) {
+ case 'refresh':
+ openModal.apply(null, params.options);
+ break;
+ default:
+ }
+ })
+ const openModal = (datas, activeTab) => {
+ $dialog = dialog.create(services, {
+ size: 'Custom',
+ customWidth: 770,
+ customHeight: 650,
+ title: localeService.t('toolbox'),
+ loading: true
+ });
+
+ return $.get(`${url}prod/tools/`
+ , datas
+ , function (data) {
+ $dialog.setContent(data);
+ $dialog.setOption('contextArgs', datas);
+ _onModalReady(data, window.toolsConfig, activeTab);
+ return;
+ }
+ );
+ };
+
+
+ const _onModalReady = (template, data, activeTab) => {
+
+ var $scope = $('#prod-tool-box');
+ var tabs = $('#tool-tabs', $scope).tabs();
+ if (activeTab !== false) {
+ tabs.tabs('option', 'active', activeTab);
+ }
+
+ $('.iframe_submiter', $scope).bind('click', function () {
+ var form = $(this).closest('form');
+ form.submit();
+ form.find('.load').empty().html(localeService.t('loading') + ' ...');
+ $('#uploadHdsub').contents().find('.content').empty();
+ $('#uploadHdsub').load(function () {
+ form.find('.load').empty();
+ var iframeContent = $('#uploadHdsub').contents().find('.content').html();
+ form.closest('div').find('.resultAction').empty().append(iframeContent);
+ });
+ });
+
+ $('.action_submiter', $scope).bind('click', function () {
+ var $this = $(this);
+ var form = $(this).closest('form');
+ $('.confirm_block').removeClass('hide');
+ $.ajax({
+ url: form.attr('action'),
+ type: form.attr('method'),
+ dataType: 'json',
+ data: form.serializeArray(),
+ beforeSend: function () {
+ $this.prop('disabled', true);
+ setTimeout(function(){ dialog.get(1).close(); }, 1500);
+ },
+ success: function (data) {
+ if (!data.success) {
+ humane.error(data.message);
+ } else {
+ console.log('sub-definitions recreated');
+ }
+ },
+ complete: function () {
+ $this.prop('disabled', false);
+ }
+ });
+
+ return false;
+ });
+
+ $('.action_cancel', $scope).bind('click', function () {
+ dialog.get(1).close();
+
+ return false;
+ });
+
+
+ // available if only 1 record is selected:
+ if (data.selectionLength === 1) {
+ sharingManager({configService, localeService, toolsStream}).initialize({
+ $container: $dialog, data, tabs,
+ dialogParams: $dialog.getOption('contextArgs')
+ });
+ }
+ };
+
+ return {openModal};
+};
+
+export default recordToolsModal;
diff --git a/Phraseanet-production-client/src/components/record/tools/sharingManager.js b/Phraseanet-production-client/src/components/record/tools/sharingManager.js
new file mode 100644
index 0000000000..b90afef8de
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/tools/sharingManager.js
@@ -0,0 +1,52 @@
+import $ from 'jquery';
+
+const sharingManager = (services, datas, activeTab = false) => {
+ const {configService, localeService, toolsStream} = services;
+ const url = configService.get('baseUrl');
+ let $container = null;
+ let dialogParams = {};
+ const initialize = (params) => {
+ //let {$container, data, tabs, dialogParams} = params;
+ $container = params.$container;
+ dialogParams = params.dialogParams;
+ console.log('>>>>', dialogParams)
+
+ if (params.data.selectionLength === 1) {
+ _onUniqueSelection(params.data.databaseId, params.data.records[0].id, params.tabs);
+ }
+ }
+
+ const _onUniqueSelection = (databaseId, recordId, tabs) => {
+
+ $('#tools-sharing .stateChange_button').bind('click', function (event) {
+ const $btn = $(event.currentTarget);
+ let state = true;
+
+ // inverse state
+ if ($btn.data('state') === 1) {
+ state = false;
+ }
+
+ // submit changes
+ $.post(`tools/sharing-editor/${databaseId}/${recordId}/`, {
+ name: $btn.data('name'),
+ state: state
+ }).done(function (data) {
+ // self reload tab with current active tab:
+ activeTab = tabs.tabs('option', 'active');
+ toolsStream.onNext({
+ action: 'refresh',
+ options: [dialogParams, activeTab]
+ });
+ }).error(function (err) {
+ alert('forbidden action');
+ });
+ return false;
+ });
+ };
+ return {
+ initialize
+ }
+}
+
+export default sharingManager;
diff --git a/Phraseanet-production-client/src/components/record/videoEditor/index.js b/Phraseanet-production-client/src/components/record/videoEditor/index.js
new file mode 100644
index 0000000000..df3c662a29
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/videoEditor/index.js
@@ -0,0 +1,94 @@
+require('./style/main.scss');
+import $ from 'jquery';
+import dialog from './../../../phraseanet-common/components/dialog';
+import videoScreenCapture from './videoScreenCapture';
+import videoRangeCapture from './videoRangeCapture';
+import videoSubtitleCapture from './videoSubtitleCapture';
+import * as Rx from 'rx';
+
+const humane = require('humane-js');
+
+const recordVideoEditorModal = (services, datas, activeTab = false) => {
+ const {configService, localeService, appEvents} = services;
+ const url = configService.get('baseUrl');
+ let $dialog = null;
+ let toolsStream = new Rx.Subject();
+
+ var initialize = function initialize() {
+
+ $(document).on('click', '.video-tools-record-action', function (event) {
+ event.preventDefault();
+ var $el = $(event.currentTarget);
+ var idLst = $el.data("idlst");
+ var datas = {}
+ var key = "lst";
+ datas[key] = idLst;
+ openModal(datas, activeTab);
+ });
+ };
+ initialize();
+
+ toolsStream.subscribe((params) => {
+ switch (params.action) {
+ case 'refresh':
+ openModal.apply(null, params.options);
+ break;
+ default:
+ }
+ })
+ const openModal = (datas, activeTab) => {
+ $dialog = dialog.create(services, {
+ size: 'Custom',
+ customWidth: 1100,
+ customHeight: 700,
+ title: localeService.t('videoEditor'),
+ loading: true
+ });
+
+ return $.get(`${url}prod/tools/videoEditor`
+ , datas
+ , function (data) {
+ $dialog.setContent(data);
+ $dialog.setOption('contextArgs', datas);
+ $dialog.getDomElement().closest('.ui-dialog').addClass('videoEditor_dialog')
+ _onModalReady(data, window.toolsConfig, activeTab);
+ return;
+ }
+ );
+ };
+
+
+ const _onModalReady = (template, data, activeTab) => {
+
+ var $scope = $('#prod-tool-box');
+ var tabs = $('#tool-tabs', $scope).tabs();
+ if (activeTab !== false) {
+ tabs.tabs('option', 'active', activeTab);
+ }
+
+ // available if only 1 record is selected:
+ if (data.isVideo === "true") {
+ videoScreenCapture(services).initialize({$container: $scope, data});
+ videoRangeCapture(services).initialize({$container: $('.video-range-editor-container'), data, services});
+ videoSubtitleCapture(services).initialize({$container: $('.video-subtitle-editor-container'), data, services});
+ }else {
+ let confirmationDialog = dialog.create(services, {
+ size: 'Alert',
+ title: localeService.t('warning'),
+ closeOnEscape: true
+ }, 3);
+
+ let content = $('
').css({
+ 'text-align': 'center',
+ width: '100%',
+ 'font-size': '14px'
+ }).append(localeService.t('error video editor'));
+ confirmationDialog.setContent(content);
+ $dialog.close();
+ }
+ };
+
+ return {openModal};
+};
+
+export default recordVideoEditorModal;
diff --git a/Phraseanet-production-client/src/components/record/videoEditor/style/main.scss b/Phraseanet-production-client/src/components/record/videoEditor/style/main.scss
new file mode 100644
index 0000000000..4addfebe51
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/videoEditor/style/main.scss
@@ -0,0 +1,26 @@
+#rangeExtractor {
+ // overflow: none;
+ position: absolute;
+ min-width: 1020px;
+ overflow-y: auto;
+ bottom: 0px;
+ left: 0px;
+ right: 0px;
+ top: 31px;
+ .main_title {
+
+ margin: 10px 15px 10px 10px;
+ }
+}
+
+.vjs-button .fa-circle {
+ color: transparent;
+ border: 1px solid #aa46bb;
+ width: 20px;
+ height: 20px;
+ border-radius: 10px;
+}
+
+.fa-info {
+ color: #fff;
+}
diff --git a/Phraseanet-production-client/src/components/record/videoEditor/videoRangeCapture.js b/Phraseanet-production-client/src/components/record/videoEditor/videoRangeCapture.js
new file mode 100644
index 0000000000..39d565915b
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/videoEditor/videoRangeCapture.js
@@ -0,0 +1,71 @@
+import Flash from 'videojs-flash';
+import FieldCollection from './../recordEditor/models/fieldCollection';
+
+const videoRangeCapture = (services, datas, activeTab = false) => {
+ const {configService, localeService, appEvents} = services;
+ let $container = null;
+ let videojs = {};
+ let initData = {};
+ let options = {
+ playbackRates: [],
+ fluid: true
+ };
+ let rangeCapture;
+ const initialize = (params) => {
+ $container = params.$container;
+ initData = params.data;
+ let aspectRatio = configService.get('resource.aspectRatio');
+
+
+ if (configService.get('resource.aspectRatio') !== null) {
+ options.aspectRatio = configService.get('resource.aspectRatio');
+ }
+
+ if (configService.get('resource.playbackRates') !== null) {
+ options.playbackRates = configService.get('resource.playbackRates');
+ }
+
+ if (initData.videoEditorConfig !== null) {
+ options.seekBackwardStep = initData.videoEditorConfig.seekBackwardStep;
+ options.seekForwardStep = initData.videoEditorConfig.seekForwardStep;
+ options.playbackRates = initData.videoEditorConfig.playbackRates === undefined ? [1, 2, 3] : initData.videoEditorConfig.playbackRates;
+ options.vttFieldValue = false;
+ options.ChapterVttFieldName = initData.videoEditorConfig.ChapterVttFieldName === undefined ? false : initData.videoEditorConfig.ChapterVttFieldName;
+ }
+
+ options.techOrder = ['html5', 'flash'];
+ options.autoplay = false;
+ options.recordId = initData.recordId;
+ options.record = initData.records[0];
+ options.databoxId = initData.databoxId;
+ options.translations = initData.translations;
+ options.services = params.services;
+ options.preferences = initData.preferences;
+
+ // get default videoTextTrack value
+ if (options.ChapterVttFieldName !== false) {
+ var fieldCollection = new FieldCollection(initData.T_fields);
+ let vttField = fieldCollection.getFieldByName(options.ChapterVttFieldName);
+ if (vttField !== false) {
+ if(vttField._value.VideoTextTrackChapters != undefined) {
+ options.vttFieldValue = vttField._value.VideoTextTrackChapters[0];
+ }
+ options.meta_struct_id = vttField.id;
+ }
+ }
+
+ require.ensure([], () => {
+ // load videoJs lib
+ //require('../../videoEditor/style/main.scss');
+ rangeCapture = require('../../videoEditor/rangeCapture').default;
+ let rangeCaptureInstance = rangeCapture(services);
+ rangeCaptureInstance.initialize(params, options);
+ //render(initData);
+ });
+
+ }
+
+ return {initialize}
+}
+
+export default videoRangeCapture;
diff --git a/Phraseanet-production-client/src/components/record/videoEditor/videoScreenCapture.js b/Phraseanet-production-client/src/components/record/videoEditor/videoScreenCapture.js
new file mode 100644
index 0000000000..5c23957d17
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/videoEditor/videoScreenCapture.js
@@ -0,0 +1,327 @@
+import $ from 'jquery';
+import dialog from './../../../phraseanet-common/components/dialog';
+import ScreenCapture from '../../videoEditor/screenCapture';
+
+const videoScreenCapture = (services, datas, activeTab = false) => {
+ const {configService, localeService, appEvents} = services;
+ const url = configService.get('baseUrl');
+ const initialize = (params) => {
+ let {$container, data} = params;
+ var ThumbEditor = new ScreenCapture('thumb_video', 'thumb_canvas', {
+ altCanvas: $('#alt_canvas_container .alt_canvas')
+ });
+
+ if (ThumbEditor.isSupported()) {
+
+ var $gridContainer = $('#grid', $container);
+
+ $gridContainer.on('mousedown', '.grid-wrapper', function () {
+ $('.selected', $gridContainer).removeClass('selected');
+ $(this).addClass('selected');
+
+ $container.find('.canvas-wrap').css('max-height','210px').css('width','auto');
+ $container.find('#thumb_canvas').removeAttr('style').removeAttr('height');
+
+ var $self = this;
+ var selectedScreenId = $self.getAttribute('id').split('_').pop();
+ var screenshots = ThumbEditor.store.get(selectedScreenId);
+
+ ThumbEditor.copy(screenshots.getDataURI(), screenshots.getAltScreenShots());
+ });
+
+ $gridContainer.on('mouseup', '.grid-wrapper', function () {
+ if ($container.find('#thumb_canvas').height() >= 210) {
+ $container.find('#thumb_canvas').css('height', '210px');
+ }
+
+ });
+
+ $container.on('click', '#thumb_download_button', function() {
+ downloadThumbnail($gridContainer.find('.selected'), $container);
+ });
+
+ $container.on('click', '#thumb_delete_button', function () {
+ deleteThumbnail($gridContainer.find('.selected'), $container, ThumbEditor);
+ });
+
+ $container.on('click', '.close_action_frame', function () {
+ $(this).closest('.action_frame').hide();
+ });
+
+
+ $container.on('click', '#thumb_camera_button', function () {
+ $('#videotools-spinner').removeClass('hidden');
+ setTimeout(launch_thumb_camera_button, 10);
+ });
+ function launch_thumb_camera_button() {
+ /** set current time on real video capture**/
+ var realVideoCurrent = document.getElementById('thumb_video_A').currentTime;
+ document.getElementById('thumb_video').currentTime = realVideoCurrent;
+
+ $('#thumb_delete_button', $container).show();
+ $('#thumb_download_button', $container).show();
+
+ var screenshot = '';
+ /**screenshot at the real currentTime**/
+ function getScreenShot() {
+ var screenshot = ThumbEditor.screenshot();
+
+ if($container.find('#thumb_canvas').height() >= 210) {
+ $container.find('#thumb_canvas').css('height', '210px');
+ $container.find('#grid').css('min-height', '210px');
+ }
+ $container.find('.frame_canva').css('width', $container.find('#thumb_canvas').width());
+ $container.find('.canvas-wrap').css('overflow','hidden').css('width', $container.find('#thumb_canvas').width());
+
+ $('.selected', $gridContainer).removeClass('selected');
+ var grid_wrapper = document.createElement('div');
+ $(grid_wrapper)
+ .addClass('grid-wrapper')
+ .addClass('selected')
+ .attr('id', 'working_' + screenshot.getId())
+ .append('
')
+ .append('
');
+ var img = $(' ');
+ img.attr('src', screenshot.getDataURI())
+ .attr('alt', screenshot.getVideoTime())
+ .appendTo($(grid_wrapper));
+
+ var grid_item = document.createElement('div');
+ $(grid_item).addClass('grid-item').append($(grid_wrapper)).appendTo($gridContainer);
+ $('#videotools-spinner').addClass('hidden');
+ }
+ setTimeout(getScreenShot, 1000);
+ };
+
+ $container.on('mouseup', '#thumb_camera_button', function () {
+ $container.find('#thumb_canvas').removeAttr('style');
+ });
+
+ $gridContainer.on('click', '#small_thumb_download_button', function () {
+ downloadThumbnail($(this).parent(), $container);
+ return false;
+ });
+
+ $gridContainer.on('click', '#small_thumb_delete_button', function () {
+ deleteThumbnail($(this).parent(), $container, ThumbEditor);
+ return false;
+ });
+
+ $('#thumb_canvas').on('tool_event', function () {
+ var thumbnail = $('.selected', $gridContainer);
+
+ if (thumbnail.length === 0) {
+ console.error('No image selected');
+
+ return;
+ }
+
+ thumbnail.attr('src', ThumbEditor.getCanvaImage());
+
+ });
+ $container.on('click', '#thumb_validate_button', function () {
+ var thumbnail = $('.selected', $gridContainer);
+ let content = '';
+ if (thumbnail.length === 0) {
+ let confirmationDialog = dialog.create(services, {
+ size: 'Custom',
+ customWidth: 360,
+ customHeight: 160,
+ title: data.translations.alertTitle,
+ closeOnEscape: true
+ }, 3);
+
+ confirmationDialog.getDomElement().closest('.ui-dialog').addClass('screenCapture_validate_dialog');
+
+ content = $('
').css({
+ 'text-align': 'center',
+ width: '100%',
+ 'font-size': '14px'
+ }).append(data.translations.noImgSelected);
+ confirmationDialog.setContent(content);
+
+ return false;
+ } else {
+
+ var buttons = {};
+
+ var record_id = $('input[name=record_id]').val();
+ var sbas_id = $('input[name=sbas_id]').val();
+
+ var selectedScreenId = thumbnail.attr('id').split('_').pop();
+ var screenshots = ThumbEditor.store.get(selectedScreenId);
+
+
+ let screenData = screenshots.getAltScreenShots();
+ let subDefs = [];
+
+ for (let i = 0; i < screenData.length; i++) {
+ subDefs.push({
+ name: screenData[i].name,
+ src: screenData[i].dataURI
+
+ });
+ }
+
+ buttons = [
+ {
+ text: localeService.t('cancel'),
+ click: function(){
+ $(this).dialog('close');
+ }
+ },
+ {
+ text: localeService.t('valider'),
+ click: function () {
+ let confirmDialog = dialog.get(2);
+ var buttonPanel = confirmDialog.getDomElement().closest('.ui-dialog').find('.ui-dialog-buttonpane');
+ var loadingDiv = buttonPanel.find('.info-div');
+
+ if (loadingDiv.length === 0) {
+ loadingDiv = $('
').css({
+ width: '120px',
+ height: '40px',
+ float: 'left',
+ 'line-height': '40px',
+ 'padding-left': '40px',
+ 'text-align': 'left',
+ 'background-position': 'left center'
+ }).attr('class', 'info-div').prependTo(buttonPanel);
+ }
+
+ $.ajax({
+ type: 'POST',
+ url: `${url}prod/tools/thumb-extractor/apply/`,
+ data: {
+ sub_def: subDefs,
+ record_id: record_id,
+ sbas_id: sbas_id
+ },
+ beforeSend: function () {
+ disableConfirmButton(confirmDialog);
+ loadingDiv.empty().addClass('loading').append(data.translations.processing);
+ },
+ success: function (data) {
+ loadingDiv.empty().removeClass('loading');
+
+ if (data.success) {
+ confirmDialog.close();
+ dialog.get(1).close();
+ } else {
+ loadingDiv.append(content);
+ enableConfirmButton(confirmDialog);
+ }
+ }
+ });
+ },
+ }
+ ];
+
+ // show confirm box, content is loaded here /prod/tools/thumb-extractor/confirm-box/
+ var validationDialog = dialog.create(services, {
+ size: 'Custom',
+ customWidth: 360,
+ customHeight: 285,
+ title: data.translations.thumbnailTitle,
+ cancelButton: true,
+ buttons: buttons
+ }, 2);
+
+ validationDialog.getDomElement().closest('.ui-dialog').addClass('screenCapture_validate_dialog')
+
+ var datas = {
+ image: $('.selected', $gridContainer).find('img').attr('src'),
+ sbas_id: sbas_id,
+ record_id: record_id
+ };
+
+ return $.ajax({
+ type: 'POST',
+ url: `${url}prod/tools/thumb-extractor/confirm-box/`,
+ data: datas,
+ success: function (data) {
+
+ if (data.error) {
+ content = $('
').css({
+ 'font-size': '16px',
+ 'text-align': 'center'
+ }).append(data.datas);
+ validationDialog.setContent(content);
+ disableConfirmButton(validationDialog);
+ } else {
+ validationDialog.setContent(data.datas);
+ }
+ }
+ });
+ }
+ });
+ } else {
+ // not supported
+ $('#thumbExtractor').empty().append(localeService.t('browserFeatureSupport'));
+ }
+ }
+
+ const downloadThumbnail = (element, $container) => {
+ var imageInBase64 = element.find('img').attr('src');
+ var mimeInfo = base64MimeType(imageInBase64);
+ var ext = mimeInfo.split('/').pop();
+ var filename = "preview" + element.find('img').attr('alt') + "." + ext;
+ download(imageInBase64, filename, mimeInfo);
+
+ }
+
+ const deleteThumbnail = (element, $container, ThumbEditor) => {
+ var imgWrapper = element;
+ var id = imgWrapper.attr('id').split('_').pop();
+ var previous = imgWrapper.parent().prev();
+ var next = imgWrapper.parent().next();
+
+ if (previous.length > 0) {
+ previous.find('.grid-wrapper').trigger('mousedown');
+ previous.find('.grid-wrapper').trigger('mouseup');
+ } else if (next.length > 0) {
+ next.find('.grid-wrapper').trigger('mousedown');
+ next.find('.grid-wrapper').trigger('mouseup');
+ } else {
+ $('#thumb_delete_button', $container).hide();
+ $('#thumb_download_button', $container).hide();
+ $('#thumb_canvas').attr('width',0);
+ $('#thumb_canvas').attr('height',0);
+ $('.frame_canva').removeAttr('style');
+ }
+
+ imgWrapper.parent().remove();
+ ThumbEditor.store.remove(id);
+ }
+
+ const disableConfirmButton = (dialog) => {
+ dialog.getDomElement().closest('.ui-dialog').find('.ui-dialog-buttonpane button').filter(function () {
+ return $(this).text() === localeService.t('valider');
+ }).addClass('ui-state-disabled').attr('disabled', true);
+ }
+
+
+ const enableConfirmButton = (dialog) => {
+ dialog.getDomElement().closest('.ui-dialog').find('.ui-dialog-buttonpane button').filter(function () {
+ return $(this).text() === localeService.t('valider');
+ }).removeClass('ui-state-disabled').attr('disabled', false);
+ }
+
+ const base64MimeType = (encoded) => {
+ let result = null;
+ if (typeof encoded !== 'string') {
+ return result;
+ }
+ let mime = encoded.match(/data:([a-zA-Z0-9]+\/[a-zA-Z0-9-.+]+).*,.*/);
+ if (mime && mime.length) {
+ result = mime[1];
+ }
+ return result;
+ }
+
+ return {
+ initialize
+ }
+}
+
+export default videoScreenCapture;
diff --git a/Phraseanet-production-client/src/components/record/videoEditor/videoSubtitleCapture.js b/Phraseanet-production-client/src/components/record/videoEditor/videoSubtitleCapture.js
new file mode 100644
index 0000000000..9d73890ee1
--- /dev/null
+++ b/Phraseanet-production-client/src/components/record/videoEditor/videoSubtitleCapture.js
@@ -0,0 +1,437 @@
+import $ from 'jquery';
+const humane = require('humane-js');
+;
+
+const videoSubtitleCapture = (services, datas, activeTab = false) => {
+ const {configService, localeService, appEvents} = services;
+ const url = configService.get('baseUrl');
+ const initialize = (params, userOptions) => {
+ let {$container, data} = params;
+ var initialData = data;
+ var videoSource = "/embed/?url=/datafiles/" + initialData.databoxId + "/" + initialData.recordId + "/preview/%3Fetag";
+
+ function loadVideo() {
+ $('.video-subtitle-right .video-subtitle-wrapper').html('');
+ if (initialData.records[0].sources.length > 0) {
+ var prevWidth = initialData.records[0].sources[0].width;
+ var prevHeight = initialData.records[0].sources[0].height;
+ var prevRatio = initialData.records[0].sources[0].ratio;
+ $('.video-subtitle-right .video-subtitle-wrapper').append("");
+ resizeVideoPreview();
+ } else {
+ $('.video-subtitle-right .video-subtitle-wrapper').append(" ");
+ }
+
+ }
+
+ function resizeVideoPreview() {
+
+ var $sel = $('.video-subtitle-wrapper');
+ var $Iframe = $('.video-subtitle-wrapper iframe');
+ // V is for "video" ; K is for "container" ; N is for "new"
+ var VW = $Iframe.data('width');
+ var VH = $Iframe.data('height');
+ var KW = $('#prod-tool-box').width() / 2;
+ var KH = $('.video-subtitle-left-inner').closest('#tool-tabs').height() - 100;
+
+ var NW, NH;
+ if ((NH = VH / VW * (NW = KW)) > KH) {
+ // try to fit exact horizontally, adjust vertically
+ // too bad... new height overflows container height
+ NW = VW / VH * (NH = KH); // so fit exact vertically, adjust horizontally
+ }
+ // (0, _jquery2.default)($Iframe).css('width', NW).css('height', NH);
+ $($Iframe).attr('width', NW).css('width', NW);
+ $($Iframe).attr('height', NH).css('height', NH);
+ }
+
+ loadVideo();
+ setTimeout(function () {
+ resizeVideoPreview()
+ }, 2000);
+
+ $('.subtitleEditortoggle').on('click', function (e) {
+ resizeVideoPreview();
+ });
+
+ $container.on('click', '.add-subtitle-vtt', function (e) {
+ e.preventDefault();
+ addSubTitleVtt();
+ setDiffTime();
+
+ });
+ let startVal = 0;
+ let endVal = 0;
+ let diffVal = 0;
+ let leftHeight = 300;
+
+ // Set height of left block
+ leftHeight = $('.video-subtitle-left-inner').closest('#tool-tabs').height();
+ $('.video-subtitle-left-inner').css('height', leftHeight - 147);
+ $('.video-request-left-inner').css('height', leftHeight);
+ $('.video-subtitle-right .video-subtitle-wrapper').css('height', leftHeight - 100);
+
+
+ $('.endTime').on('keyup change', function (e) {
+ setDefaultStartTime();
+ endVal = stringToseconde($(this).val());
+ startVal = stringToseconde($(this).closest('.video-subtitle-item').find('.startTime').val());
+ diffVal = millisecondeToTime(endVal - startVal);
+ $(this).closest('.video-subtitle-item').find('.showForTime').val(diffVal);
+ });
+ $('.startTime').on('keyup change', function (e) {
+ setDefaultStartTime();
+ startVal = stringToseconde($(this).val());
+ endVal = stringToseconde($(this).closest('.video-subtitle-item').find('.endTime').val());
+ diffVal = millisecondeToTime(endVal - startVal);
+ $(this).closest('.video-subtitle-item').find('.showForTime').val(diffVal);
+ });
+ function setDefaultStartTime(e) {
+
+ var DefaultStartT = $('.video-subtitle-item:last .endTime').val();
+ DefaultStartT = stringToseconde(DefaultStartT) + 1;
+ DefaultStartT = millisecondeToTime(DefaultStartT);
+
+ var DefaultEndT = stringToseconde(DefaultStartT) + 2000;
+ DefaultEndT = millisecondeToTime(DefaultEndT);
+
+ $('#defaultStartValue').val(DefaultStartT);
+ $('#defaultEndValue').val(DefaultEndT);
+
+ }
+
+ function setDiffTime(e) {
+ $('.endTime').on('keyup change', function (e) {
+ setDefaultStartTime();
+ endVal = stringToseconde($(this).val());
+ startVal = stringToseconde($(this).closest('.video-subtitle-item').find('.startTime').val());
+ diffVal = millisecondeToTime(endVal - startVal);
+ $(this).closest('.video-subtitle-item').find('.showForTime').val(diffVal);
+ });
+ $('.startTime').on('keyup change', function (e) {
+ setDefaultStartTime();
+ startVal = stringToseconde($(this).val());
+ endVal = stringToseconde($(this).closest('.video-subtitle-item').find('.endTime').val());
+ diffVal = millisecondeToTime(endVal - startVal);
+ $(this).closest('.video-subtitle-item').find('.showForTime').val(diffVal);
+
+ });
+ }
+
+ function stringToseconde(time) {
+ let tt = time.split(":");
+ let sec = tt[0] * 3600 + tt[1] * 60 + tt[2] * 1;
+ return sec * 1000;
+ }
+
+ function millisecondeToTime(duration) {
+ var milliseconds = parseInt((duration % 1000 / 100) * 100),
+ seconds = parseInt((duration / 1000) % 60),
+ minutes = parseInt((duration / (1000 * 60)) % 60),
+ hours = parseInt((duration / (1000 * 60 * 60)) % 24);
+
+ hours = (hours < 10) ? "0" + hours : hours;
+ minutes = (minutes < 10) ? "0" + minutes : minutes;
+ seconds = (seconds < 10) ? "0" + seconds : seconds;
+ // if(isNaN(hours) && isNaN(minutes) && isNaN(seconds) && isNaN(milliseconds) ) {
+ return hours + ":" + minutes + ":" + seconds + "." + milliseconds;
+ //}
+
+ }
+
+ $container.on('click', '.remove-item', function (e) {
+ e.preventDefault();
+ if ($(this).closest('.editing').length > 0) {
+ $(this).closest('.editing').remove();
+ } else {
+ $(this).closest('.video-subtitle-item').remove();
+ }
+ });
+
+ $('#submit-subtitle').on('click', function (e) {
+ e.preventDefault();
+ buildCaptionVtt('save');
+ });
+
+ $('#copy-subtitle').on('click', function (event) {
+ event.preventDefault();
+ buildCaptionVtt('copy');
+ });
+
+ function buildCaptionVtt(btn) {
+ try {
+ let allData = $('#video-subtitle-list').serializeArray();
+ allData = JSON.parse(JSON.stringify(allData));
+ allData = JSON.parse(JSON.stringify(allData));
+ let metaStructId = $('#metaStructId').val();
+
+ let countSubtitle = $('.video-subtitle-item').length;
+ if (allData) {
+ var i = 0;
+ var j = 0;
+ var captionText = "WEBVTT - with cue identifier\n\n";
+ while (i <= countSubtitle * 3) {
+ j= j +1;
+ captionText += j + "\n" + allData[i].value + " --> " + allData[i + 1].value + "\n" + allData[i + 2].value + "\n\n";
+ i = i + 3;
+ if (i == (countSubtitle * 3) - 3) {
+ $('#record-vtt').val(captionText);
+ console.log(captionText);
+ if (btn == 'save') {
+ //send data
+ $.ajax({
+ type: 'POST',
+ url: url + 'prod/tools/metadata/save/',
+ dataType: 'json',
+ data: {
+ databox_id: data.databoxId,
+ record_id: data.recordId,
+ meta_struct_id: metaStructId,
+ value: captionText
+ },
+ success: function success(data) {
+ if (!data.success) {
+ humane.error(localeService.t('prod:videoeditor:subtitletab:messsage:: error'));
+ } else {
+ humane.info(localeService.t('prod:videoeditor:subtitletab:messsage:: success'));
+ loadVideo();
+ }
+ }
+ });
+ }
+ if (btn == 'copy') {
+ return copyElContentClipboard('record-vtt');
+ }
+ }
+ }
+ ;
+ }
+
+ } catch (err) {
+ return;
+ }
+ }
+
+ var copyElContentClipboard = function copyElContentClipboard(elId) {
+ var copyEl = document.getElementById(elId);
+ copyEl.select();
+ try {
+ var successful = document.execCommand('copy');
+ var msg = successful ? 'successful' : 'unsuccessful';
+ } catch (err) {
+ console.log('unable to copy');
+ }
+ };
+
+
+ const addSubTitleVtt = () => {
+ let countSubtitle = $('.video-subtitle-item').length;
+ if ($('.alert-wrapper').length) {
+ $('.alert-wrapper').remove();
+ }
+ if (countSubtitle > 1) {
+ setDefaultStartTime();
+ }
+ let item = $('#default-item').html();
+ $('.fields-wrapper').append(item);
+ $('.video-subtitle-item:last .time').attr('pattern', '[0-9][0-9]:[0-9][0-9]:[0-9][0-9].[0-9]{3}$');
+ $('.video-subtitle-item:last .startTime').attr('name', 'startTime' + countSubtitle).addClass('startTime' + countSubtitle);
+ $('.video-subtitle-item:last .endTime').attr('name', 'endTime' + countSubtitle).addClass('endTime' + countSubtitle);
+ $('.video-subtitle-item:last .number').html(countSubtitle);
+ if (countSubtitle > 1) {
+ $('.video-subtitle-item:last .startTime').val($('#defaultStartValue').val());
+ $('.video-subtitle-item:last .endTime').val($('#defaultEndValue').val());
+
+ }
+ //setDiffTime();
+ };
+
+
+ // Edit subtitle
+ var fieldvalue = '';
+ var ResValue = '';
+ var captionValue = '';
+ var captionLength = '';
+ var timeValue = '';
+
+ //Show default caption to edit
+ fieldvalue = $('#caption_' + $('#metaStructId').val()).val();
+ editCaptionByLanguage(fieldvalue);
+
+
+ $('#metaStructId').on('keyup change', function (e) {
+ fieldvalue = $('#caption_' + $(this).val()).val();
+ editCaptionByLanguage(fieldvalue);
+ $('.editing > .caption-label').click(function (e) {
+ $(this).next('.video-subtitle-item').toggleClass('active');
+ $(this).toggleClass('caption_active');
+ })
+ });
+
+ $('.editing > .caption-label').click(function (e) {
+ $(this).next('.video-subtitle-item').toggleClass('active');
+ $(this).toggleClass('caption_active');
+ })
+
+ function editCaptionByLanguage(fieldvalue) {
+ $('.fields-wrapper').html('');
+ var item = $('#default-item').html();
+
+ if (fieldvalue != '' && fieldvalue!= undefined) {
+ var withCueId = false;
+ //var fieldType = fieldvalue.split("WEBVTT");
+ var fieldType = fieldvalue.split("\n\n");
+ if (fieldType[0] === 'WEBVTT - with cue identifier') {
+ // with cue
+ ResValue = fieldvalue.split("WEBVTT - with cue identifier\n\n");
+ captionValue = ResValue[1].split("\n\n");
+ captionLength = captionValue.length;
+ console.log(captionValue);
+ for (var i = 0; i < captionLength - 1; i++) {
+
+ // Regex blank line
+ var ResValueItem = captionValue[i].replace(/\n\r/g, "\n")
+ .replace(/\r/g, "\n")
+ .split(/\n{2,}/g);
+
+ var captionValueItem = ResValueItem[0].split("\n");
+ var captionNumber = captionValueItem[0];
+ var timing = captionValueItem[1];
+ var text1 = captionValueItem.slice(2);
+ if (text1.length > 1) {
+ var text = text1.join('\n');
+ } else {
+ var text = text1;
+ }
+
+ var timeValue = timing.split(" --> ");
+ var startTimeLabel = timeValue[0];
+ $('.fields-wrapper').append('
')
+ $('.fields-wrapper .item_' + i + '').append('' + captionNumber + ' -->
');
+ $('.fields-wrapper .item_' + i + '').append(item);
+ $('.item_' + i + ' .video-subtitle-item ').find('.number').remove();
+
+ //Re-Build StartTime
+ $('.item_' + i + ' .video-subtitle-item ').closest('.editing').find('.start-label').text(startTimeLabel);
+ $('.item_' + i + ' .video-subtitle-item ').find('.startTime').val(startTimeLabel);
+
+ startVal = stringToseconde(timeValue[0]);
+ //Re-Build EndTime
+ timeValue = timeValue [1].split("\n")
+ $('.item_' + i + ' .video-subtitle-item ').closest('.editing').find('.end-label').text(timeValue[0]);
+ $('.item_' + i + ' .video-subtitle-item ').find('.endTime').val(timeValue[0]);
+ endVal = stringToseconde(timeValue[0]);
+
+ //Re-build Duration
+ diffVal = millisecondeToTime(endVal - startVal);
+ $('.item_' + i + ' .video-subtitle-item ').closest('.editing').find('.duration').text(diffVal);
+ $('.item_' + i + ' .video-subtitle-item ').find('.showForTime').val(diffVal);
+
+ //Re-build caption text
+ var textTrimed = text && text.length > length ? text.substring(0, 30) + '...' : text;
+ if (timeValue[1] != '') {
+ $('.item_' + i + ' .video-subtitle-item ').closest('.editing').find('.text-label').text(textTrimed);
+ $('.item_' + i + ' .video-subtitle-item ').find('.captionText').val(text);
+ }
+ //end with cue number
+ }
+
+ } else {
+ ResValue = fieldvalue.split("WEBVTT\n\n");
+ captionValue = ResValue[1].split("\n\n");
+ captionLength = captionValue.length - 1;
+
+ var captionNumber;
+ for (var i = 0; i < captionLength; i++) {
+ captionNumber = i + 1;
+ timeValue = captionValue[i].split(" --> ");
+ var startTimeLabel = timeValue[0];
+ $('.fields-wrapper').append('
')
+ $('.fields-wrapper .item_' + i + '').append('' + captionNumber + ' -->
');
+ $('.fields-wrapper .item_' + i + '').append(item);
+ $('.item_' + i + ' .video-subtitle-item ').find('.number').remove();
+
+ //Re-Build StartTime
+ $('.item_' + i + ' .video-subtitle-item ').closest('.editing').find('.start-label').text(startTimeLabel);
+ $('.item_' + i + ' .video-subtitle-item ').find('.startTime').val(startTimeLabel);
+
+ startVal = stringToseconde(timeValue[0]);
+ //Re-Build EndTime
+ timeValue = timeValue [1].split("\n")
+ $('.item_' + i + ' .video-subtitle-item ').closest('.editing').find('.end-label').text(timeValue[0]);
+ $('.item_' + i + ' .video-subtitle-item ').find('.endTime').val(timeValue[0]);
+ endVal = stringToseconde(timeValue[0]);
+
+ //Re-build Duration
+ diffVal = millisecondeToTime(endVal - startVal);
+ $('.item_' + i + ' .video-subtitle-item ').closest('.editing').find('.duration').text(diffVal);
+ $('.item_' + i + ' .video-subtitle-item ').find('.showForTime').val(diffVal);
+
+ //Re-build caption text
+ var textTrimed = timeValue[1] && timeValue[1].length > length ? timeValue[1].substring(0, 30) + '...' : timeValue[1];
+ if (timeValue[1] != '') {
+ var text = timeValue.slice(1);
+ text = text.join('\n');
+ $('.item_' + i + ' .video-subtitle-item ').closest('.editing').find('.text-label').text(textTrimed);
+ $('.item_' + i + ' .video-subtitle-item ').find('.captionText').val(text);
+ }
+
+ }
+ }
+
+
+ setDiffTime();
+ } else {
+ var errorMsg = $('#no_caption').val();
+ $('.fields-wrapper').append('' + errorMsg + '
');
+ }
+ }
+
+ //Subtitle Request Tab
+ $('#submit-subtitle-request').on('click', function (e) {
+ e.preventDefault();
+ try {
+ var requestData = $('#video-subtitle-request').serializeArray();
+ requestData = JSON.parse(JSON.stringify(requestData));
+ console.log(requestData)
+
+ } catch (err) {
+ return;
+ }
+ });
+ }
+
+ /* const render = (initData) => {
+ let record = initData.records[0];
+ if (record.type !== 'video') {
+ return;
+ }
+ options.frameRates = {};
+ options.ratios = {};
+ const coverUrl = '';
+ let generateSourcesTpl = (record) => {
+ let recordSources = [];
+ _.each(record.sources, (s, i) => {
+ recordSources.push(``)
+ options.frameRates[s.src] = s.framerate;
+ options.ratios[s.src] = s.ratio;
+ });
+
+ return recordSources.join(' ');
+ };
+ let sources = generateSourcesTpl(record);
+ $('.video-subtitle-right .video-subtitle-wrapper').html('');
+ $('.video-subtitle-right .video-subtitle-wrapper').append(
+ `${sources}
+
+ `);
+ };*/
+
+ return {
+ initialize
+ }
+}
+
+
+export default videoSubtitleCapture;
diff --git a/Phraseanet-production-client/src/components/search/advSearch/searchAdvancedForm.js b/Phraseanet-production-client/src/components/search/advSearch/searchAdvancedForm.js
new file mode 100644
index 0000000000..54cf60b143
--- /dev/null
+++ b/Phraseanet-production-client/src/components/search/advSearch/searchAdvancedForm.js
@@ -0,0 +1,634 @@
+import * as Rx from 'rx';
+import $ from 'jquery';
+import _ from 'underscore';
+import user from './../../../phraseanet-common/components/user';
+
+const searchAdvancedForm = (services) => {
+ const {configService, localeService, appEvents} = services;
+ const url = configService.get('baseUrl');
+ let $container = null;
+ /**
+ * add "field" zone on advsearch
+ *
+ * @returns {jQuery|HTMLElement}
+ * @constructor
+ */
+ function AdvSearchAddNewTerm() {
+ var block_template = $('#ADVSRCH_FIELDS_ZONE DIV.term_select_wrapper_template');
+ var last_block = $('#ADVSRCH_FIELDS_ZONE DIV.term_select_wrapper:last');
+ if (last_block.length === 0) {
+ last_block = block_template;
+ }
+ last_block = block_template.clone(true).insertAfter(last_block); // true: clone event handlers
+ last_block.removeClass('term_select_wrapper_template').addClass('term_select_wrapper').show();
+ last_block.css('background-color', '');
+
+ return last_block;
+ }
+
+ const initialize = (options) => {
+ let initWith = {$container} = options;
+ let previousVal;
+ const multi_term_select_html = $('.term_select_wrapper').html();
+
+
+ // advanced
+ $container.on('click', '.toggle-collection', (event) => {
+ let $el = $(event.currentTarget);
+ toggleCollection($el, $($el.data('toggle-content')));
+ });
+
+ $container.on('click', '.toggle-database', (event) => {
+ let $el = $(event.currentTarget);
+ let state = $el.data('state') || false;
+ toggleAllDatabase(state);
+ });
+
+ $container.on('change', '.select-database', (event) => {
+ let $el = $(event.currentTarget);
+ let collectionId = $el.data('database');
+
+ selectDatabase($el, collectionId);
+ });
+
+ $container.on('change', '.check-filters', (event) => {
+ let $el = $(event.currentTarget);
+ let shouldSave = $el.data('save') || false;
+
+ checkFilters(shouldSave);
+ });
+
+ $('.field_switch').on('change', function (event) {
+ checkFilters(true);
+ });
+ $container.on('click', '.search-reset-action', () => {
+ resetSearch();
+ });
+ $container.on('click', '.reload-search', () => {
+ resetSearch();
+ $('#searchForm').submit();
+
+ });
+
+ $(document).on('focus', 'select.term_select_field', (event) => {
+ previousVal = $(event.currentTarget).val();
+ });
+ $(document).on('change', 'select.term_select_field', (event) => {
+ const $this = $(event.currentTarget);
+
+ // if option is selected
+ if ($this.val()) {
+ $this.siblings().prop('disabled', false);
+
+ $('.term_select_multiple option').each((index, el) => {
+ let $el = $(el);
+ if ($this.val() === $el.val()) {
+ $el.prop('selected', true);
+ } else if (previousVal === $el.val()) {
+ $el.prop('selected', false);
+ }
+ });
+ } else {
+ $this.siblings().prop('disabled', 'disabled');
+
+ $('.term_select_multiple option').each((index, el) => {
+ let $el = $(el);
+ if (previousVal === $el.val()) {
+ $el.prop('selected', false);
+ }
+ });
+ }
+ $this.blur();
+ checkFilters(true);
+ });
+
+ $(document).on('click', '.term_deleter', (event) => {
+ event.preventDefault();
+ let $this = $(event.currentTarget);
+ $this.closest('.term_select_wrapper').remove();
+ checkFilters(true);
+ });
+
+ $('.add_new_term').on('click', (event) => {
+ event.preventDefault();
+ AdvSearchAddNewTerm(1);
+ });
+
+ // @TODO - check if usefull
+ /**
+ * inform global app for state
+ * @TODO refactor
+ */
+ $('#EDIT_query').bind('focus', function () {
+ $(this).addClass('focused');
+ }).bind('blur', function () {
+ $(this).removeClass('focused');
+ });
+ };
+
+ /**
+ * adv search : check/uncheck all the collections (called by the buttons "all"/"none")
+ *
+ * @param bool
+ */
+ const toggleAllDatabase = (bool) => {
+ $('form.phrasea_query .sbas_list').each(function () {
+
+ var sbas_id = $(this).find('input[name=reference]:first').val();
+ if (bool) {
+ $(this).find(':checkbox').prop('checked', true);
+ } else {
+ $(this).find(':checkbox').prop('checked', false);
+ }
+ });
+
+ checkFilters(true);
+ };
+
+ const toggleCollection = ($el, $elContent) => {
+ if ($el.hasClass('deployer_opened')) {
+ $el.removeClass('deployer_opened').addClass('deployer_closed');
+ $elContent.hide();
+ } else {
+ $el.removeClass('deployer_closed').addClass('deployer_opened');
+ $elContent.show();
+ }
+ };
+
+ const selectDatabase = ($el, sbas_id) => {
+ var bool = $el.prop('checked');
+ $.each($('.sbascont_' + sbas_id + ' :checkbox'), function () {
+ this.checked = bool;
+ });
+
+ checkFilters(true);
+ };
+ const activateDatabase = (databaseCollection) => {
+ // disable all db,
+ toggleAllDatabase(false);
+ // then enable only provided
+ _.each(databaseCollection, (databaseId) => {
+ _.each($('.sbascont_' + databaseId + ' :checkbox'), (checkbox) => {
+ $(checkbox).prop('checked', true);
+ });
+ });
+
+ };
+
+ $('#ADVSRCH_DATE_SELECTORS input').change(function () {
+ checkFilters(true);
+ });
+
+ const checkFilters = (save) => {
+ var danger = false;
+ var search = {
+ bases: {},
+ fields: [],
+ dates: {},
+ status: [],
+ elasticSort: {}
+
+ };
+
+ var adv_box = $('form.phrasea_query .adv_options');
+ var container = $('#ADVSRCH_OPTIONS_ZONE');
+ var fieldsSort = $('#ADVSRCH_SORT_ZONE select[name=sort]', container);
+ var fieldsSortOrd = $('#ADVSRCH_SORT_ZONE select[name=ord]', container);
+ var fieldsSelect = $('#ADVSRCH_FIELDS_ZONE select.term_select_multiple', container);
+ var fieldsSelectFake = $('#ADVSRCH_FIELDS_ZONE select.term_select_field', container);
+ var statusField = $('#ADVSRCH_FIELDS_ZONE .danger_indicator', container);
+ var statusFilters = $('#ADVSRCH_SB_ZONE .status-section-title .danger_indicator', container);
+ var dateFilterSelect = $('#ADVSRCH_DATE_ZONE select', container);
+ var scroll = fieldsSelect.scrollTop();
+
+ // hide all the fields in the "sort by" select, so only the relevant ones will be shown again
+ $('option.dbx', fieldsSort).hide().prop('disabled', true); // dbx is for "field of databases"
+
+ // hide all the fields in the "fields" select, so only the relevant ones will be shown again
+ $('option.dbx', fieldsSelect).hide().prop('disabled', true); // option[0] is "all fields"
+ $('option.dbx', fieldsSelectFake).hide().prop('disabled', true);
+
+ // disable the whole select
+ $('#ADVSRCH_FIELDS_ZONE .term_select_wrapper select.term_select_field', container).prop('disabled', true);
+ $('#ADVSRCH_FIELDS_ZONE .term_select_wrapper select.term_select_op', container).prop('disabled', true);
+ $('#ADVSRCH_FIELDS_ZONE .term_select_wrapper input.term_select_value', container).prop('disabled', true);
+
+ // hide all the fields in the "date field" select, so only the relevant ones will be shown again
+ $('option.dbx', dateFilterSelect).hide().prop('disabled', true); // dbx = all "field" entries in the select = all except the firstt
+
+ statusFilters.removeClass('danger');
+ $.each($('#ADVSRCH_SB_ZONE .field_switch'), function (index, el) {
+ if ($(el).prop('checked') === true) {
+ danger = true;
+ statusFilters.addClass('danger');
+ }
+ });
+ // enable also the select if the first option ("choose:") was selected
+ statusField.removeClass('danger');
+ fieldsSelectFake.each(function (e) {
+ var $this = $(this);
+ if ($this.val() !== '') {
+ danger = true;
+ statusField.addClass('danger');
+ }
+ });
+ var nbTotalSelectedColls = 0;
+ // if one coll is not checked, show danger for ADVSRCH_SBAS_ZONE
+ $('#ADVSRCH_SBAS_ZONE').each(function () {
+ var $this = (0, $)(this);
+ var nbSelectedColls = 0;
+ $this.find('.checkbas').each(function (idx, el) {
+ if ($(this).prop('checked') === false) {
+ nbSelectedColls++;
+ }
+ });
+ if (nbSelectedColls > 0) {
+ $('#ADVSRCH_SBAS_ZONE').addClass('danger');
+ danger = true;
+ } else {
+ $('#ADVSRCH_SBAS_ZONE').removeClass('danger');
+
+ }
+ });
+ $.each($('.sbascont', adv_box), function () {
+ var $this = $(this);
+
+ var sbas_id = $this.parent().find('input[name="reference"]').val();
+ search.bases[sbas_id] = [];
+
+ var nbCols = 0;
+ var nbSelectedColls = 0;
+ $this.find('.checkbas').each(function (idx, el) {
+ nbCols++;
+ if ($(this).prop('checked')) {
+ nbSelectedColls++;
+ nbTotalSelectedColls++;
+ search.bases[sbas_id].push($(this).val());
+ }
+ });
+
+ // display the number of selected colls for the databox
+ if (nbSelectedColls === nbCols) {
+ $('.infos_sbas_' + sbas_id).empty().append(nbCols);
+ $(this).siblings('.clksbas').removeClass('danger');
+ $(this).siblings('.clksbas').find('.custom_checkbox_label input').prop('checked', 'checked');
+ } else {
+ $('.infos_sbas_' + sbas_id).empty().append('' + nbSelectedColls + ' / ' + nbCols);
+ $(this).siblings('.clksbas').addClass('danger');
+ danger = true;
+ }
+
+ // if one coll is not checked, show danger
+ if (nbSelectedColls !== nbCols) {
+ $('#ADVSRCH_SBAS_ZONE').addClass('danger');
+ danger = true;
+ } else if (nbSelectedColls === nbCols && danger === false) {
+ $('#ADVSRCH_SBAS_ZONE').removeClass('danger');
+
+ }
+
+ if (nbSelectedColls === 0) {
+ // no collections checked for this databox
+ // hide the status bits
+ $('#ADVSRCH_SB_ZONE_' + sbas_id, container).hide();
+ // uncheck
+ $('#ADVSRCH_SB_ZONE_' + sbas_id + ' input:checkbox', container).prop('checked', false);
+ } else {
+ // at least one coll checked for this databox
+ // show again the relevant fields in "sort by" select
+ $('.db_' + sbas_id, fieldsSort).show().prop('disabled', false);
+ // show again the relevant fields in "from fields" select
+ $('.db_' + sbas_id, fieldsSelect).show().prop('disabled', false);
+ $('.db_' + sbas_id, fieldsSelectFake).show().prop('disabled', false);
+ // show the sb
+ $('#ADVSRCH_SB_ZONE_' + sbas_id, container).show();
+ // show again the relevant fields in "date field" select
+ $('.db_' + sbas_id, dateFilterSelect).show().prop('disabled', false);
+ }
+ });
+
+ // enable also the select if the first option ("choose:") was selected
+ statusField.removeClass('danger');
+ fieldsSelectFake.each(function(e) {
+ var $this = $(this);
+ var term_ok = $('option:selected:enabled', $this).closest(".term_select_wrapper");
+ $("select.term_select_field", term_ok).prop('disabled', false);
+ if($this.val() !== "") {
+ $("select.term_select_op", term_ok).prop('disabled', false);
+ $("input.term_select_value", term_ok).prop('disabled', false);
+ danger = true;
+ statusField.addClass('danger');
+ }
+ });
+
+ if (nbTotalSelectedColls === 0) {
+ // no collections checked at all
+ // hide irrelevant filters
+ $('#ADVSRCH_OPTIONS_ZONE').hide();
+ } else {
+ // at least one collection checked
+ // show relevant filters
+ $('#ADVSRCH_OPTIONS_ZONE').show();
+ }
+
+ // --------- sort --------
+
+ // if no field is selected for sort, select the default option
+ if ($('option:selected:enabled', fieldsSort).length === 0) {
+ $('option.default-selection', fieldsSort).prop('selected', true);
+ $('option.default-selection', fieldsSortOrd).prop('selected', true);
+ }
+
+ search.elasticSort.by = $('option:selected:enabled', fieldsSort).val();
+ search.elasticSort.order = $('option:selected:enabled', fieldsSortOrd).val();
+
+ // --------- from fields filter ---------
+
+ // unselect the unavailable fields (or all fields if "all" is selected)
+ var optAllSelected = false;
+ $('option', fieldsSelect).each(
+ function (idx, opt) {
+ if (idx === 0) {
+ // nb: unselect the "all" field, so it acts as a button
+ optAllSelected = $(opt).is(':selected');
+ }
+ if (idx === 0 || optAllSelected || $(opt).is(':disabled') || $(opt).css('display') === 'none') {
+ $(opt).prop('selected', false);
+ }
+ }
+ );
+
+
+ // --------- status bits filter ---------
+
+ // here only the relevant sb are checked
+ const availableDb = search.bases;
+ for (let sbas_id in availableDb) {
+
+ var n_checked = 0;
+ var n_unchecked = 0;
+ $('#ADVSRCH_SB_ZONE_' + sbas_id + ' :checkbox', container).each(function (k, o) {
+ var n = $(this).data('sb');
+ if ($(o).attr('checked')) {
+ search.status[n] = $(this).val().split('_');
+ n_checked++;
+ } else {
+ n_unchecked++;
+ }
+ });
+ if (n_checked === 0) {
+ $('#ADVSRCH_SB_ZONE_' + sbas_id, container).removeClass('danger');
+ } else {
+ $('#ADVSRCH_SB_ZONE_' + sbas_id, container).addClass('danger');
+ danger = true;
+ }
+ }
+
+ // --------- dates filter ---------
+
+ // if no date field is selected for filter, select the first option
+ $('#ADVSRCH_DATE_ZONE', adv_box).removeClass('danger');
+ if ($('option:selected:enabled', dateFilterSelect).length === 0) {
+ $('option:eq(0)', dateFilterSelect).prop('selected', true);
+ }
+ if ($('option:selected', dateFilterSelect).val() !== '') {
+ $('#ADVSRCH_DATE_SELECTORS', container).show();
+ search.dates.minbound = $('#ADVSRCH_DATE_ZONE input[name=date_min]', adv_box).val();
+ search.dates.maxbound = $('#ADVSRCH_DATE_ZONE input[name=date_max]', adv_box).val();
+ search.dates.field = $('#ADVSRCH_DATE_ZONE select[name=date_field]', adv_box).val();
+ if ($.trim(search.dates.minbound) || $.trim(search.dates.maxbound)) {
+ danger = true;
+ $('#ADVSRCH_DATE_ZONE', adv_box).addClass('danger');
+ }
+ } else {
+ $('#ADVSRCH_DATE_SELECTORS', container).hide();
+ $('#ADVSRCH_DATE_ZONE input[name=date_min]').val("");
+ $('#ADVSRCH_DATE_ZONE input[name=date_max]').val("");
+ }
+
+ fieldsSelect.scrollTop(scroll);
+
+
+ // if one filter shows danger, show it on the query
+ /* if (danger) {*/
+ if ($('#ADVSRCH_DATE_ZONE', adv_box).hasClass('danger') || $('#ADVSRCH_SB_ZONE .danger_indicator', adv_box).hasClass('danger') || $('#ADVSRCH_FIELDS_ZONE', adv_box).hasClass('danger') || $('#ADVSRCH_SBAS_ZONE', adv_box).hasClass('danger')) {
+ $('#EDIT_query').addClass('danger');
+ } else {
+ $('#EDIT_query').removeClass('danger');
+ }
+
+ if (save === true) {
+ user.setPref('search', JSON.stringify(search));
+ }
+ };
+
+ const saveHiddenFacetsList = (hiddenFacetsList) => {
+ user.setPref('hiddenFacetsList', JSON.stringify(hiddenFacetsList));
+ }
+
+ function findClauseBy_ux_zone(clause, ux_zone) {
+ // console.log('find clause' + ux_zone);
+ if (typeof clause._ux_zone != 'undefined' && clause._ux_zone === ux_zone) {
+ return clause;
+ }
+ if (clause.type === "CLAUSES") {
+ for (var i = 0; i < clause.clauses.length; i++) {
+ var r = findClauseBy_ux_zone(clause.clauses[i], ux_zone);
+ if (r != null) {
+ return r;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * add "field" zone on advsearch
+ *
+ * @returns {jQuery|HTMLElement}
+ * @constructor
+ */
+ function AdvSearchFacetAddNewTerm() {
+ var block_template = $('#ADVSRCH_FIELDS_ZONE DIV.term_select_wrapper_template');
+ var last_block = $('#ADVSRCH_FIELDS_ZONE DIV.term_select_wrapper:last');
+ if (last_block.length === 0) {
+ last_block = block_template;
+ }
+ last_block = block_template.clone(true).insertAfter(last_block); // true: clone event handlers
+ last_block.removeClass('term_select_wrapper_template').addClass('term_select_wrapper').show();
+ last_block.css('background-color', '');
+ return last_block;
+ }
+
+ function restoreJsonQuery(args) {
+ var jsq = args.jsq;
+ var submit = args.submit;
+
+ var clause;
+
+ // restore the "fulltext" input-text
+ clause = findClauseBy_ux_zone(jsq.query, "FULLTEXT");
+ if (clause) {
+ $('#EDIT_query').val(clause.value);
+ }
+
+ // restore the "bases" checkboxes
+ if(! _.isUndefined(jsq.bases)) {
+ $('#ADVSRCH_SBAS_ZONE .sbas_list .checkbas').prop('checked', false);
+ if (jsq.bases.length > 0) {
+ for (var k = 0; k < jsq.bases.length; k++) {
+ $('#ADVSRCH_SBAS_ZONE .sbas_list .checkbas[value="' + jsq.bases[k] + '"]').prop('checked', true);
+ }
+ } else {
+ // special case : EMPTY array ==> since it's a nonsense, check ALL bases
+ $('#ADVSRCH_SBAS_ZONE .sbas_list .checkbas').prop('checked', true);
+ }
+ }
+
+ // restore the status-bits (for now dual checked status are restored unchecked)
+ if(! _.isUndefined(jsq.statuses)) {
+ $('#ADVSRCH_SB_ZONE INPUT:checkbox').prop('checked', false);
+ _.each(jsq.statuses, function (db_statuses) {
+ var db = db_statuses.databox;
+ _.each(db_statuses.status, function (sb) {
+ var i = sb.index;
+ var v = sb.value ? '1' : '0';
+ $("#ADVSRCH_SB_ZONE INPUT[name='status[" + db_statuses.databox + '][' + sb.index + "]'][value=" + v + ']').prop('checked', true);
+ });
+ });
+ }
+
+ // restore the "records/stories" radios
+ if(! _.isUndefined(jsq.phrasea_recordtype)) {
+ $('#searchForm INPUT[name=search_type][value="' + (jsq.phrasea_recordtype == 'STORY' ? '1' : '0') + '"]').prop('checked', true); // check one radio will uncheck siblings
+ }
+
+ // restore the "record type" menu (image, video, audio, ...)
+ if(! _.isUndefined(jsq.phrasea_mediatype)) {
+ $('#searchForm SELECT[name=record_type] OPTION[value="' + jsq.phrasea_mediatype.toLowerCase() + '"]').prop('selected', true);
+ }
+
+ // restore the "use truncation" checkbox
+ if(! _.isUndefined(jsq.phrasea_mediatype) && jsq.phrasea_mediatype == 'true') {
+ $('#ADVSRCH_USE_TRUNCATION').prop('checked', jsq.phrasea_mediatype);
+ }
+
+ // restore the "sort results" menus
+ if(! _.isUndefined(jsq.sort)) {
+ if(! _.isUndefined(jsq.sort.field)) {
+ $('#ADVSRCH_SORT_ZONE SELECT[name=sort] OPTION[value="' + jsq.sort.field + '"]').prop('selected', true);
+ }
+ if(! _.isUndefined(jsq.sort.order)) {
+ $('#ADVSRCH_SORT_ZONE SELECT[name=ord] OPTION[value="' + jsq.sort.order + '"]').prop('selected', true);
+ }
+ }
+
+ // restore the multiples "fields" (field-menu + op-menu + value-input)
+ clause = findClauseBy_ux_zone(jsq.query, "FIELDS");
+ if (clause) {
+ $('#ADVSRCH_FIELDS_ZONE INPUT[name=must_match][value="' + clause.must_match + '"]').attr('checked', true);
+ $('#ADVSRCH_FIELDS_ZONE DIV.term_select_wrapper').remove();
+ for (var j = 0; j < clause.clauses.length; j++) {
+ var wrapper = AdvSearchFacetAddNewTerm(); // div.term_select_wrapper
+ var f = $(".term_select_field", wrapper);
+ var o = $(".term_select_op", wrapper);
+ var v = $(".term_select_value", wrapper);
+
+ f.data('fieldtype', clause.clauses[j].type);
+ $('option[value="' + clause.clauses[j].field + '"]', f).prop('selected', true);
+ $('option[value="' + clause.clauses[j].operator + '"]', o).prop('selected', true);
+ o.prop('disabled', false);
+ v.val(clause.clauses[j].value).prop('disabled', false);
+ }
+ }
+
+ // restore the "date field" (field-menu + from + to)
+ clause = findClauseBy_ux_zone(jsq.query, "DATE-FIELD");
+ if (clause) {
+ $("#ADVSRCH_DATE_ZONE SELECT[name=date_field] option[value='" + clause.field + "']").prop('selected', true);
+ $("#ADVSRCH_DATE_ZONE INPUT[name=date_min]").val(clause.from);
+ $("#ADVSRCH_DATE_ZONE INPUT[name=date_max]").val(clause.to);
+ if ($("#ADVSRCH_DATE_ZONE SELECT[name=date_field]").val() !== '') {
+ $("#ADVSRCH_DATE_SELECTORS").show();
+ // $('#ADVSRCH_DATE_ZONE').addClass('danger');
+ }
+ }
+
+ // restore the selected facets (whole saved as custom property)
+ if(! _.isUndefined(jsq._selectedFacets)) {
+ appEvents.emit('facets.setSelectedFacets', jsq._selectedFacets);
+ //(0, _index2.default)(services).setSelectedFacets(jsq._selectedFacets);
+ // selectedFacets = jsq._selectedFacets;
+ }
+
+ // the ux is restored, finish the job (hide unavailable fields/status etc, display "danger" where needed)
+ appEvents.emit('searchAdvancedForm.checkFilters');
+ //loadFacets([]); // useless, facets will be restored after the query is sent
+
+ if(submit) {
+ appEvents.emit('search.doRefreshState');
+ }
+ }
+
+ var resetSearch = function resetSearch() {
+ var jsq = {
+ "sort":{
+ "field":"created_on",
+ "order":"desc"
+ },
+ "use_truncation":false,
+ "phrasea_recordtype":"RECORD",
+ "phrasea_mediatype":"",
+ "bases":[ ],
+ "statuses":[ ],
+ "query":{
+ "_ux_zone":"PROD",
+ "type":"CLAUSES",
+ "must_match":"ALL",
+ "enabled":true,
+ "clauses":[
+ {
+ "_ux_zone":"FIELDS",
+ "type":"CLAUSES",
+ "must_match":"ALL",
+ "enabled":false,
+ "clauses":[ ]
+ },
+ {
+ "_ux_zone":"DATE-FIELD",
+ "type":"DATE-FIELD",
+ "field":"",
+ "from":"",
+ "to":"",
+ "enabled":false
+ },
+ {
+ "_ux_zone":"AGGREGATES",
+ "type":"CLAUSES",
+ "must_match":"ALL",
+ "enabled":false,
+ "clauses":[ ]
+ }
+ ]
+ },
+ "_selectedFacets":{ }
+ };
+
+ restoreJsonQuery({'jsq':jsq, 'submit':false});
+ };
+
+ appEvents.listenAll({
+ 'searchAdvancedForm.checkFilters': checkFilters,
+ 'searchAdvancedForm.selectDatabase': selectDatabase,
+ 'searchAdvancedForm.activateDatabase': function (params) {
+ return activateDatabase(params.databases);
+ },
+ 'searchAdvancedForm.toggleCollection': toggleCollection,
+ 'searchAdvancedForm.saveHiddenFacetsList': saveHiddenFacetsList,
+ 'searchAdvancedForm.restoreJsonQuery': restoreJsonQuery
+ });
+
+ return { initialize: initialize };
+};
+
+export default searchAdvancedForm;
diff --git a/Phraseanet-production-client/src/components/search/geoSearch/searchGeoForm.js b/Phraseanet-production-client/src/components/search/geoSearch/searchGeoForm.js
new file mode 100644
index 0000000000..baa593ae72
--- /dev/null
+++ b/Phraseanet-production-client/src/components/search/geoSearch/searchGeoForm.js
@@ -0,0 +1,200 @@
+import * as Rx from 'rx';
+import $ from 'jquery';
+import dialog from './../../../phraseanet-common/components/dialog';
+
+import leafletMap from '../../geolocalisation/providers/mapbox';
+import _ from 'underscore';
+
+const searchGeoForm = (services) => {
+ const {configService, localeService, appEvents} = services;
+ const url = configService.get('baseUrl');
+ let $container = null;
+ let $dialog;
+ let mapBoxService;
+ let searchQuery;
+ let drawnItems;
+ let $geoSearchBtn;
+ const mapContainerName = 'geo-search-map-container';
+
+ const openModal = (options) => {
+ options = _.extend({
+ size: (window.bodySize.x - 120) + 'x' + (window.bodySize.y - 120),
+ loading: false,
+ title: localeService.t('title-map-dialog'),
+ }, options);
+
+ $dialog = dialog.create(services, options);
+ $dialog.setContent(renderModal());
+ $container = $dialog.getDomElement();
+ $container.closest('.ui-dialog').addClass('map_search_dialog');
+ onModalReady(options)
+
+ };
+
+ const onModalReady = (options) => {
+
+ $container.on('click', '.submit-geo-search-action', (event) => {
+ event.preventDefault();
+ updateSearchValue();
+
+ // searchQuery
+ $dialog.close();
+ });
+ mapBoxService = leafletMap({configService, localeService, eventEmitter: appEvents});
+ mapBoxService.initialize({
+ $container: $container.find(`#${mapContainerName}`),
+ parentOptions: {},
+ drawable: true,
+ drawnItems: options.drawnItems || false,
+ mapOptions: {}
+ });
+ mapBoxService.appendMapContent({selection: []});
+
+ $('.map-geo-btn').on('click', event => {
+ event.preventDefault();
+ if($('#map-zoom-to-setting').val()!= '') {
+ savePreferences(
+ {map_zoom : parseFloat($('#map-zoom-to-setting').val())}
+ );
+ $('#map-zoom-from-setting').val(parseFloat($('#map-zoom-to-setting').val()));
+ }
+ if($('#map-position-to-setting').val()!= '') {
+ var centerRes = $('#map-position-to-setting').val();
+ centerRes = centerRes.split('[');
+ centerRes = centerRes[1].split(']');
+ centerRes = centerRes[0].split(',');
+
+ var lng = centerRes[0].split('"');
+ lng= lng[1];
+ var lat = centerRes[1].split('"');
+ lat= lat[1];
+ var res = [lng, lat];
+ savePreferences(
+ { map_position: res });
+ $('#map-position-from-setting').val('["' + lng + '","' + lat + '"]');
+ }
+ });
+ }
+
+ const updateSearchValue = () => {
+ appEvents.emit('searchForm.updateSearchValue', {
+ searchValue: searchQuery,
+ reset: true,
+ submit: true
+ });
+ }
+
+ const renderModal = () => {
+ // @TODO cleanup styles
+ return `
+
+
+
${localeService.t('Valider')}
+
`;
+ };
+
+ const updateCircleGeo = (params) => {
+ let {shapes} = params;
+ searchQuery = buildCircularSearchQuery(shapes);
+ let circleObjCollection = _.map(params.drawnItems, function (circleObj) {
+ var obj = {};
+ obj['center'] = circleObj.getCenter();
+ obj['radius'] = circleObj.getRadius();
+ return obj;
+ });
+
+ savePreferences({drawnItems: circleObjCollection});
+ }
+
+ const onShapeCreated = (params) => {
+ let {shapes} = params;
+ searchQuery = buildSearchQuery(shapes);
+ savePreferences({drawnItems: params.drawnItems});
+ };
+
+ const onShapeEdited = (params) => {
+ let {shapes} = params;
+ searchQuery = buildSearchQuery(shapes);
+ savePreferences({drawnItems: params.drawnItems});
+ };
+
+ const onShapeDeleted = (params) => {
+ let {shapes} = params;
+ searchQuery = buildSearchQuery(shapes);
+ savePreferences({drawnItems: params.drawnItems});
+ };
+
+ const buildCircularSearchQuery = (shapes) => {
+ let queryTerms = [];
+ _.each(shapes, (shape) => {
+ let terms = [];
+
+ var distanceInKM = parseFloat(shape.getRadius()) / 1000;
+ terms.push(`geolocation="${shape.getCenter().lat} ${shape.getCenter().lng} ${distanceInKM.toFixed(2)}km"`);
+
+ if (terms.length > 0) {
+ queryTerms.push(` (${terms.join(' AND ')}) `);
+ }
+
+ });
+ return queryTerms.join(' OR ');
+ }
+
+ const buildSearchQuery = (shapes) => {
+
+ let queryTerms = [];
+ _.each(shapes, (shape) => {
+ let terms = [];
+
+ if (shape.type === 'rectangle') {
+ let southWest = 0;
+ let northEst = 2;
+
+ for (let boundary in shape.bounds) {
+ if (shape.bounds.hasOwnProperty(boundary)) {
+
+ if (parseInt(boundary, 10) === southWest) {
+ // superior
+ for (let coordField in shape.bounds[boundary]) {
+ if (shape.bounds[boundary].hasOwnProperty(coordField)) {
+ terms.push(`${coordField}>${shape.bounds[boundary][coordField]}`);
+ }
+ }
+ } else if (parseInt(boundary, 10) === northEst) {
+ // inferior
+ for (let coordField in shape.bounds[boundary]) {
+ if (shape.bounds[boundary].hasOwnProperty(coordField)) {
+ terms.push(`${coordField}<${shape.bounds[boundary][coordField]}`);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (terms.length > 0) {
+ queryTerms.push(` (${terms.join(' AND ')}) `);
+ }
+
+ });
+ return queryTerms.join(' OR ');
+ }
+
+ const savePreferences = (obj) => {
+ //drawnItems = JSON.stringify(data);
+ appEvents.emit('searchForm.updatePreferences', obj);
+
+ }
+
+ appEvents.listenAll({
+ shapeCreated: onShapeCreated,
+ shapeEdited: onShapeEdited,
+ shapeRemoved: onShapeDeleted,
+ updateSearchValue: updateSearchValue,
+ updateCircleGeo: updateCircleGeo,
+ })
+
+ return {openModal};
+};
+
+export default searchGeoForm;
diff --git a/Phraseanet-production-client/src/components/search/index.js b/Phraseanet-production-client/src/components/search/index.js
new file mode 100644
index 0000000000..ea3baf1dda
--- /dev/null
+++ b/Phraseanet-production-client/src/components/search/index.js
@@ -0,0 +1,698 @@
+import * as Rx from 'rx';
+import $ from 'jquery';
+import dialog from './../../phraseanet-common/components/dialog';
+import merge from 'lodash.merge';
+import resultInfos from './resultInfos';
+import workzoneFacets from '../ui/workzone/facets/index';
+import Selectable from '../utils/selectable';
+let lazyload = require('jquery-lazyload');
+require('./../../phraseanet-common/components/tooltip');
+require('./../../phraseanet-common/components/vendors/contextMenu');
+
+import searchForm from './searchForm';
+
+const search = services => {
+ const { configService, localeService, appEvents } = services;
+ const url = configService.get('baseUrl');
+ let searchPromise = {};
+ let searchResult = {
+ selection: false,
+ navigation: {
+ tot: 0, // p4.tot in record preview
+ tot_options: false, // datas.form; // p4.tot_options common/tooltip
+ tot_query: false, // datas.query; // p4.tot_query
+ perPage: 0,
+ page: 0
+ }
+ };
+ let $searchForm = null;
+ let $searchResult = null;
+ let answAjaxrunning = false;
+ let resultInfoView;
+ let facets = null;
+ var lastFilterResults = [];
+ let savedHiddenFacetsList = configService.get('savedHiddenFacetsList') ? JSON.parse(configService.get('savedHiddenFacetsList')) : [];
+
+
+ const initialize = () => {
+ $searchForm = $('#searchForm');
+ searchForm(services).initialize({
+ $container: $searchForm
+ });
+
+ $searchResult = $('#answers');
+
+ resultInfoView = resultInfos(services);
+ resultInfoView.initialize({
+ $container: $('#answers_status')
+ });
+
+ searchResult.selection = new Selectable(services, $searchResult, {
+ selector: '.IMGT',
+ limit: 800,
+ selectStart: function (event, selection) {
+ $('#answercontextwrap table:visible').hide();
+ },
+ selectStop: function (event, selection) {
+ appEvents.emit('search.doRefreshSelection');
+ },
+ callbackSelection: function (element) {
+ var elements = $(element).attr('id').split('_');
+
+ return elements
+ .slice(elements.length - 2, elements.length)
+ .join('_');
+ }
+ });
+ // map events to result selection:
+ appEvents.listenAll({
+ 'search.selection.selectAll': () =>
+ searchResult.selection.selectAll(),
+ 'search.selection.unselectAll': () =>
+ searchResult.selection.empty(),
+ 'search.selection.selectByType': dataType =>
+ searchResult.selection.select(dataType.type),
+ 'search.selection.remove': data =>
+ searchResult.selection.remove(data.records)
+ });
+
+ $searchResult
+ .on('click', '.search-navigate-action', event => {
+ event.preventDefault();
+ let $el = $(event.currentTarget);
+ navigate($el.data('page'));
+ })
+ .on('keypress', '.search-navigate-input-action', event => {
+ // event.preventDefault();
+ let $el = $(event.currentTarget);
+ let inputPage = $el.val();
+ let initialPage = $el.data('initial-value');
+ let totalPages = $el.data('total-pages');
+
+ if (isNaN(inputPage)) {
+ event.preventDefault();
+ }
+ if (event.keyCode === 13) {
+ if (inputPage > 0 && inputPage <= totalPages) {
+ navigate(inputPage);
+ } else {
+ navigate(totalPages);
+ }
+ }
+ });
+
+ window.searchResult = searchResult;
+ window.dialog = dialog;
+ };
+
+ const getResultSelectionStream = () => searchResult.selection.stream;
+ let resultNavigationStream = new Rx.Subject();
+ const getResultNavigationStream = () => resultNavigationStream; //Rx.Observable.ofObjectChanges(searchResult.navigation);
+ //const getResultNavigationStream = () => Rx.Observable.ofObjectChanges(searchResult.navigation);
+
+ const newSearch = query => {
+ searchResult.selection.empty();
+
+ clearAnswers();
+ //$('#SENT_query').val(query);
+ if (query !== null) {
+ var histo = $('#history-queries ul');
+ histo.prepend('' + query + ' ');
+ var lis = $('li', histo);
+ if (lis.length > 25) {
+ $('li:last', histo).remove();
+ }
+ }
+
+ $('#idFrameC li.proposals_WZ').removeClass('active');
+ appEvents.emit('search.doRefreshState');
+ return false;
+ };
+
+ /**
+ *
+ */
+ const doRefreshState = () => {
+
+ // get the selectedFacets from the facets module
+ let selectedFacets = {};
+ appEvents.emit('facets.getSelectedFacets', function(v) {
+ selectedFacets = v;
+ });
+
+ let data = $searchForm.serializeArray();
+ // fix bug : if a sb is dual checked, both values are sent with the SAME name
+ // we can remove those since it means we don't care about this sb
+
+ // /!\ silly fixed bug : in sb[] we will test if a key exists using "_undefined()"
+ // BUT sb["sort”] EXISTS ! it is the array.sort() function !
+ // so the side effect in "_filter()" was that data["sort"] was removed.
+ // quick solution : prefix the key with "k_"
+
+ var sb = [];
+ _.each(data, function (v) {
+ var name = "k_" + v.name;
+ if (name.substr(0, 9) === "k_status[") {
+ if (_.isUndefined(sb[name])) {
+ sb[name] = 0;
+ }
+ sb[name]++; // so sb["k_x"] is the number of occurences of sb checkbox named "x"
+ }
+ });
+ // now if a sb checkbox appears 2 times, it is removed from data
+ data = _.filter(data, function (e) {
+ return (_.isUndefined(sb["k_" + e.name])) || (sb["k_" + e.name] === 1);
+ });
+ // end of sb fix
+
+ var jsonData = serializeJSON(data, selectedFacets);
+ var qry = buildQ(jsonData.query);
+
+ data.push({
+ name: 'jsQuery',
+ value: JSON.stringify(jsonData)
+ },
+ {
+ name: 'qry',
+ value: qry
+ });
+ console.log(jsonData);
+
+ let searchPromise = {};
+ searchPromise = $.ajax({
+ type: 'POST',
+ url: `${url}prod/query/`,
+ data: data,
+ dataType: 'json',
+ beforeSend: function (formData) {
+ if (answAjaxrunning && searchPromise.abort !== undefined) {
+ searchPromise.abort();
+ }
+ beforeSearch();
+ },
+ error: function () {
+ answAjaxrunning = false;
+ $searchResult.removeClass('loading');
+ },
+ timeout: function () {
+ answAjaxrunning = false;
+ $('#answers').removeClass('loading');
+ },
+ success: function (datas) {
+ $searchResult
+ .empty()
+ .append(datas.results)
+ .removeClass('loading');
+
+ $('img.lazyload', $searchResult).lazyload({
+ container: $('#answers')
+ });
+
+ //load last result collected or [] if length == 0
+ if (!datas.facets) {
+ datas.facets = [];
+ }
+
+ facets = datas.facets;
+
+ $searchResult.append(
+ ''
+ );
+
+ resultInfoView.render(
+ datas.infos,
+ searchResult.selection.length()
+ );
+ $('#tool_navigate').empty().append(datas.navigationTpl);
+
+ // @TODO refactor
+ $.each(searchResult.selection.get(), function (i, el) {
+ $('#IMGT_' + el).addClass('selected');
+ });
+
+ searchResult.navigation = merge(
+ searchResult.navigation,
+ datas.navigation,
+ {
+ tot: datas.total_answers,
+ tot_options: datas.form,
+ tot_query: datas.query
+ }
+ );
+ resultNavigationStream.onNext(searchResult.navigation);
+
+ if (datas.next_page) {
+ $('#NEXT_PAGE, #answersNext').bind('click', function () {
+ navigate(datas.next_page);
+ });
+ } else {
+ $('#NEXT_PAGE').unbind('click');
+ }
+
+ if (datas.prev_page) {
+ $('#PREV_PAGE').bind('click', function () {
+ navigate(datas.prev_page);
+ });
+ } else {
+ $('#PREV_PAGE').unbind('click');
+ }
+
+ updateHiddenFacetsListInPrefsScreen();
+ appEvents.emit('search.doAfterSearch');
+ appEvents.emit('search.updateFacetData');
+ }
+ });
+ /*script for pagination*/
+ setTimeout(function(){
+ if ($( "#tool_navigate").length) {
+ $("#tool_navigate .btn-mini").last().addClass("last");
+ }
+ }, 5000);
+
+ };
+
+ let playFirstQuery = function playFirstQuery() {
+ // if defined, play the first query
+ //
+ try {
+ var jsq = $("#FIRST_QUERY_CONTAINER");
+ if (jsq.length > 0) {
+ // there is a query to play
+ if (jsq.data('format') === "json") {
+ // json
+ jsq = JSON.parse(jsq.text());
+ // restoreJsonQuery(jsq, true);
+ appEvents.emit('searchAdvancedForm.restoreJsonQuery', {'jsq':jsq, 'submit':true});
+ }
+ else {
+ // text : do it the old way : restore only fulltext and submit
+ searchForm.trigger('submit');;
+ }
+ }
+ } catch (e) {
+ // malformed jsonquery ?
+ // no-op
+ // console.error(e);
+ }
+ }
+
+ const updateHiddenFacetsListInPrefsScreen = () => {
+ const $hiddenFacetsContainer = $('#look_box_settings').find('.hiddenFiltersListContainer');
+ if (savedHiddenFacetsList.length > 0) {
+ $hiddenFacetsContainer.empty();
+ _.each(savedHiddenFacetsList, function (value) {
+ var $html = $('' + value.title
+ + ' ');
+
+ $hiddenFacetsContainer.append($html);
+
+ $('.remove-btn').on('click', function () {
+ let name = $(this).parent().data('name');
+ savedHiddenFacetsList = _.reject(savedHiddenFacetsList, function (obj) {
+ return (obj.name === name);
+ });
+ $(this).parent().remove();
+ appEvents.emit('searchAdvancedForm.saveHiddenFacetsList', savedHiddenFacetsList);
+ updateFacetData();
+ });
+ });
+ }
+
+ };
+
+ const beforeSearch = () => {
+ if (answAjaxrunning) {
+ return;
+ }
+ answAjaxrunning = true;
+
+ clearAnswers();
+ $('#tooltip').css({
+ display: 'none'
+ });
+ $searchResult.addClass('loading').empty();
+ $('#answercontextwrap').remove();
+ };
+
+ const afterSearch = () => {
+ if ($('#answercontextwrap').length === 0) {
+ $('body').append('
');
+ }
+
+ $.each($('.contextMenuTrigger', $searchResult), function () {
+ var id = $(this)
+ .closest('.IMGT')
+ .attr('id')
+ .split('_')
+ .slice(1, 3)
+ .join('_');
+
+ $(this).contextMenu('#IMGT_' + id + ' .answercontextmenu', {
+ appendTo: '#answercontextwrap',
+ openEvt: 'click',
+ dropDown: true,
+ theme: 'vista',
+ showTransition: 'slideDown',
+ hideTransition: 'hide',
+ shadow: false
+ });
+ });
+
+ answAjaxrunning = false;
+ $searchResult.removeClass('loading');
+ $('.captionTips, .captionRolloverTips').tooltip({
+ delay: 0,
+ delayOptions: {},
+ isBrowsable: false,
+ extraClass: 'caption-tooltip-container'
+ });
+ $('.infoTips').tooltip({
+ delay: 0
+ });
+ $('.previewTips').tooltip({
+ fixable: true
+ });
+ $('.thumb .rollovable').hover(
+ function () {
+ $('.rollover-gif-hover', this).show();
+ $('.rollover-gif-out', this).hide();
+ },
+ function () {
+ $('.rollover-gif-hover', this).hide();
+ $('.rollover-gif-out', this).show();
+ }
+ );
+ $('div.IMGT', $searchResult).draggable({
+ helper: function () {
+ $('body').append(
+ '' +
+ searchResult.selection.length() +
+ '
'
+ );
+ return $('#dragDropCursor');
+ },
+ scope: 'objects',
+ distance: 20,
+ scroll: false,
+ cursorAt: {
+ top: -10,
+ left: -20
+ },
+ start: function (event, ui) {
+ if (!$(this).hasClass('selected')) {
+ return false;
+ }
+ }
+ });
+ appEvents.emit('ui.linearizeUi');
+ };
+
+ const clearAnswers = () => {
+ $('#formAnswerPage').val('');
+ $('#searchForm input[name="nba"]').val('');
+ $($searchResult, '#dyn_tool').empty();
+ };
+
+ const navigate = page => {
+ $('#searchForm input[name="sel"]').val(
+ searchResult.selection.serialize()
+ );
+ $('#formAnswerPage').val(page);
+ appEvents.emit('search.doRefreshState');
+ };
+
+ const updateFacetData = () => {
+ appEvents.emit('facets.doLoadFacets', {
+ facets: facets,
+ filterFacet: $('#look_box_settings input[name=filter_facet]').prop('checked'),
+ facetOrder: $('.look_box_settings select[name=orderFacet]').val(),
+ facetValueOrder: $('.look_box_settings select[name=facetValuesOrder]').val(),
+ hiddenFacetsList: savedHiddenFacetsList
+ });
+ };
+
+ const reloadHiddenFacetList = (hiddenFacetsList) => {
+ savedHiddenFacetsList = hiddenFacetsList;
+ updateHiddenFacetsListInPrefsScreen();
+ }
+
+ /**
+ * restore the advansearch ux from a json-query
+ * elements are restored thank's to custom properties ("_xxx") included in json.
+ * nb : for now, _ux_ facets can't be restored _before_sending_the_query_,
+ * but since "selectedFacets" (js) IS restored, sending the query WILL restore facets.
+ *
+ * @param jsq
+ * @param submit
+ */
+ function serializeJSON(data, selectedFacets) {
+
+ var json = {},
+ obj = {},
+ bases = [],
+ statuses = [],
+ fields = [],
+ aggregates = [];
+
+ $.each(data, function (i, el) {
+ obj[el.name] = el.value;
+
+ var col = parseInt(el.value);
+
+ if (el.name === 'bases[]') {
+ bases.push(col);
+ }
+ });
+
+ var _tmpStat = [];
+ $('#ADVSRCH_SB_ZONE INPUT[type=checkbox]:checked').each(function (k, o) {
+ o = $(o);
+ var b = o.data('sbas_id');
+ var i = o.data('sb');
+ var v = o.val();
+ if (_.isUndefined(_tmpStat[b])) {
+ _tmpStat[b] = [];
+ }
+ if (_.isUndefined(_tmpStat[b][i])) {
+ // first check
+ _tmpStat[b][i] = v;
+ } else {
+ // both checked
+ _tmpStat[b][i] = -1;
+ }
+ });
+ _.each(_tmpStat, function (v, sbas_id) {
+ var status = [];
+ _.each(v, function (v, sb_index) {
+ if (v !== -1) {
+ // ignore both checked
+ status.push({
+ 'index': sb_index,
+ 'value': v === '1'
+ });
+ }
+ });
+ statuses.push({
+ 'databox': sbas_id,
+ 'status': status
+ });
+ });
+
+ $('.term_select_field').each(function (i, el) {
+ if ($(el).val()) {
+ fields.push({
+ 'type': 'TEXT-FIELD',
+ 'field': $(el).val(),
+ 'operator': $(el).next().val() === ':' ? ":" : "=",
+ 'value': $(el).next().next().val(),
+ "enabled": true
+ });
+ }
+ });
+
+ _.each(selectedFacets, function(facets) {
+ _.each(facets.values, function(facetValue) {
+ aggregates.push({
+ 'type' : facetValue.value.type,
+ 'field' : facetValue.value.field,
+ 'value' : facetValue.value.raw_value,
+ 'query' : facetValue.value.query,
+ 'negated': facetValue.negated,
+ 'enabled': facetValue.enabled
+ });
+ });
+ });
+
+ var date_field = $('#ADVSRCH_DATE_ZONE select[name=date_field]', 'form.phrasea_query .adv_options').val();
+ var date_from = $('#ADVSRCH_DATE_ZONE input[name=date_min]', 'form.phrasea_query .adv_options').val();
+ var date_to = $('#ADVSRCH_DATE_ZONE input[name=date_max]', 'form.phrasea_query .adv_options').val();
+
+ json['sort'] = {
+ 'field': obj.sort,
+ 'order': obj.ord
+ };
+ json['perpage'] = parseInt($('#nperpage_value').val());
+ json['page'] = obj.pag === '' ? 1 : parseInt(obj.pag);
+ json['use_truncation'] = obj.truncation === 'on' ? true : false;
+ json['phrasea_recordtype'] = obj.search_type == 1 ? 'STORY' : 'RECORD';
+ json['phrasea_mediatype'] = obj.record_type.toUpperCase();
+ json['bases'] = bases;
+ json['statuses'] = statuses;
+ json['query'] = {
+ '_ux_zone': $('.menu-bar .selectd').text().trim().toUpperCase(),
+ 'type': 'CLAUSES',
+ 'must_match': 'ALL',
+ 'enabled': true,
+ 'clauses': [{
+ '_ux_zone': 'FULLTEXT',
+ 'type': 'FULLTEXT',
+ 'value': obj.fake_qry,
+ 'enabled': obj.fake_qry !== ''
+ }, {
+ '_ux_zone': 'FIELDS',
+ 'type': 'CLAUSES',
+ 'must_match': obj.must_match,
+ 'enabled': true,
+ 'clauses': fields
+ }, {
+ '_ux_zone': 'DATE-FIELD',
+ 'type': 'DATE-FIELD',
+ 'field': date_field,
+ 'from': date_from,
+ 'to': date_to,
+ "enabled": true
+ }, {
+ '_ux_zone': 'AGGREGATES',
+ 'type': 'CLAUSES',
+ 'must_match': 'ALL',
+ 'enabled': true,
+ 'clauses': aggregates
+ }]
+ };
+ json['_selectedFacets'] = selectedFacets;
+
+ return json;
+ }
+
+ var _ALL_Clause_ = "created_on>0";
+
+ function pjoin(glue, a)
+ {
+ var r = a.join(glue);
+ return a.length===1 ? r : ('('+r+')');
+ }
+
+ function buildQ(clause) {
+ if (clause.enabled === false) {
+ return "";
+ }
+ switch (clause.type) {
+ case "CLAUSES":
+ var t_pos = [];
+ var t_neg = [];
+ for (var i = 0; i < clause.clauses.length; i++) {
+ var _clause = clause.clauses[i];
+ var _sub_q = buildQ(_clause);
+ if (_sub_q !== "()" && _sub_q !== "") {
+ if (_clause.negated === true) {
+ t_neg.push(_sub_q);
+ } else {
+ t_pos.push(_sub_q);
+ }
+ }
+ }
+ if (t_pos.length > 0) {
+ // some "yes" clauses
+ if (t_neg.length > 0) {
+ // some "yes" and and some "neg" clauses
+ if (clause.must_match === "ONE") {
+ // some "yes" and and some "neg" clauses, one is enough to match
+ var neg = "(" + _ALL_Clause_ + " EXCEPT " + pjoin(" OR ", t_neg) + ")";
+ t_pos.push(neg);
+ return "(" + t_pos.join(" OR ") + ")";
+ } else {
+ // some "yes" and and some "neg" clauses, all must match
+ return "(" + pjoin(" AND ", t_pos) + " EXCEPT " + pjoin(" OR ", t_neg) + ")";
+ }
+ } else {
+ // only "yes" clauses
+ return pjoin(clause.must_match=="ONE" ? " OR " : " AND ", t_pos);
+ }
+ } else {
+ // no "yes" clauses
+ if (t_neg.length > 0) {
+ // only "neg" clauses
+ return "(" + _ALL_Clause_ + " EXCEPT " + pjoin(clause.must_match == "ALL" ? " OR " : " AND ", t_neg) + ")";
+ } else {
+ // no clauses at all
+ return "";
+ }
+ }
+ case "FULLTEXT":
+ return clause.value ? "(" + clause.value + ")" : "";
+
+ case "DATE-FIELD":
+ var t = "";
+ if (clause.from) {
+ t = clause.field + ">=" + clause.from;
+ }
+ if (clause.to) {
+ t += (t ? " AND " : "") + clause.field + "<=" + clause.to;
+ }
+ return (clause.from && clause.to) ? ("(" + t + ")") : t;
+
+ case "TEXT-FIELD":
+ return clause.field + clause.operator + "\"" + clause.value + "\"";
+
+ case "GEO-DISTANCE":
+ return clause.field + "=\"" + clause.lat + " " + clause.lon + " " + clause.distance + "\"";
+/*
+ case "STRING-AGGREGATE":
+ return clause.field + ":\"" + clause.value + "\"";
+
+ case "DATE-AGGREGATE":
+ return clause.field + ":\"" + clause.value + "\"";
+
+ case "COLOR-AGGREGATE":
+ return clause.field + ":\"" + clause.value + "\"";
+
+ case "NUMBER-AGGREGATE":
+ return clause.field + "=" + clause.value;
+
+ case "BOOL-AGGREGATE":
+ return clause.field + "=" + (clause.value ? "1" : "0");
+*/
+ case "STRING-AGGREGATE":
+ case "DATE-AGGREGATE":
+ case "COLOR-AGGREGATE":
+ case "NUMBER-AGGREGATE":
+ case "BOOLEAN-AGGREGATE":
+ return clause.query;
+
+ default:
+ console.error("Unknown clause type \"" + clause.type + "\"");
+ return null;
+ }
+ }
+
+ appEvents.listenAll({
+ 'search.doRefreshState': doRefreshState,
+ 'search.doNewSearch': newSearch,
+ 'search.doAfterSearch': afterSearch,
+ 'search.doClearSearch': clearAnswers,
+ 'search.doNavigate': navigate,
+ 'search.updateFacetData': updateFacetData,
+ 'search.reloadHiddenFacetList': reloadHiddenFacetList,
+ 'search.playFirstQuery': playFirstQuery
+ });
+
+ return {
+ initialize: initialize,
+ getResultSelectionStream: getResultSelectionStream,
+ getResultNavigationStream: getResultNavigationStream
+ };
+};
+
+
+export default search;
diff --git a/Phraseanet-production-client/src/components/search/resultInfos.js b/Phraseanet-production-client/src/components/search/resultInfos.js
new file mode 100644
index 0000000000..c1b70742a5
--- /dev/null
+++ b/Phraseanet-production-client/src/components/search/resultInfos.js
@@ -0,0 +1,82 @@
+/**
+ * triggered via workzone > Basket > context menu
+ */
+import $ from 'jquery';
+import dialog from './../../phraseanet-common/components/dialog';
+import merge from 'lodash.merge';
+
+const resultInfos = (services) => {
+ const { configService, localeService, appEvents } = services;
+ const url = configService.get('baseUrl');
+ let searchSelectionSerialized = '0';
+ appEvents.listenAll({
+ 'broadcast.searchResultSelection': (selection) => {
+ updateSelectionCounter(selection.asArray.length);
+ }
+ });
+
+ const initialize = (options) => {
+ let {$container} = options;
+ updateSelectionCounter(0);
+ $container.on('click', '.search-display-info', (event) => {
+ event.preventDefault();
+ const $el = $(event.currentTarget);
+ let dialogOptions = {};
+
+ if ($el.attr('title') !== undefined) {
+ dialogOptions.title = $el.html;
+ }
+
+ let dialogContent = $el.data('infos');
+
+ openModal(dialogOptions, dialogContent);
+ });
+ };
+ const render = (template, selectionCount) => {
+ $('#tool_results').empty().append(template);
+ updateSelectionCounter(selectionCount);
+ }
+
+ function number_format (number, decimals, dec_point, thousands_sep) {
+ number = (number + '').replace(/[^0-9+\-Ee.]/g, '');
+ var n = !isFinite(+number) ? 0 : +number,
+ prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
+ sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
+ dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
+ s = '',
+ toFixedFix = function (n, prec) {
+ var k = Math.pow(10, prec);
+ return '' + Math.round(n * k) / k;
+ };
+ s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');
+ if (s[0].length > 3) {
+ s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
+ }
+ if ((s[1] || '').length < prec) {
+ s[1] = s[1] || '';
+ s[1] += new Array(prec - s[1].length + 1).join('0');
+ }
+ return s.join(dec);
+ }
+
+ const updateSelectionCounter = (selectionLength) => {
+ $('#nbrecsel').empty().append(number_format(selectionLength, null, null, " "));
+ }
+
+ const openModal = (options = {}, content) => {
+ const url = configService.get('baseUrl');
+
+ let dialogOptions = merge({
+ size: '600x600',
+ loading: false
+ }, options);
+
+ const $dialog = dialog.create(services, dialogOptions, 1);
+
+ $dialog.setContent(content);
+ };
+
+ return {initialize, render};
+};
+
+export default resultInfos;
diff --git a/Phraseanet-production-client/src/components/search/searchForm.js b/Phraseanet-production-client/src/components/search/searchForm.js
new file mode 100644
index 0000000000..92b26ba875
--- /dev/null
+++ b/Phraseanet-production-client/src/components/search/searchForm.js
@@ -0,0 +1,165 @@
+import * as Rx from 'rx';
+import $ from 'jquery';
+import _ from 'underscore';
+import resultInfos from './resultInfos';
+import user from './../../phraseanet-common/components/user';
+import dialog from './../../phraseanet-common/components/dialog';
+import Selectable from '../utils/selectable';
+import searchAdvancedForm from './advSearch/searchAdvancedForm';
+import searchGeoForm from './geoSearch/searchGeoForm';
+
+const searchForm = (services) => {
+ const {configService, localeService, appEvents} = services;
+ let $container = null;
+ let $searchValue = null;
+ let $sentValue = null;
+ let isAdvancedDialogOpen = false;
+ let $dialog = null;
+ let geoForm;
+ let searchPreferences = {};
+ let $geoSearchTriggerImg;
+ const initialize = (options) => {
+ let initWith = {$container} = options;
+ $searchValue = $('#EDIT_query');
+
+ /*Remove space on 1st and last char*/
+ $searchValue.on('change', function (event) {
+ $sentValue = $searchValue.val();
+
+ while ($sentValue.charAt(0) === ' ') {
+ $sentValue = $sentValue.slice(1);
+
+ }
+ while ($sentValue.charAt($sentValue.length - 1) === ' ') {
+ $sentValue = $sentValue.slice(0, -1);
+ }
+ $searchValue.val($sentValue);
+ });
+
+
+ searchAdvancedForm(services).initialize({
+ $container: $container
+ });
+ geoForm = searchGeoForm(services);
+
+ $container.on('click', '.adv_search_button', (event) => {
+ event.preventDefault();
+ openAdvancedForm();
+ });
+
+ toggleSearchState();
+ appEvents.emit('searchAdvancedForm.checkFilters');
+
+ $container.on('click', '.geo-search-action-btn', (event) => {
+ event.preventDefault();
+ geoForm.openModal({
+ drawnItems: searchPreferences.drawnItems || false,
+ });
+ });
+
+
+ $container.on('click', 'input[name=search_type]', (event) => {
+ let $el = $(event.currentTarget);
+ let $record_types = $('#recordtype_sel');
+
+ if ($el.hasClass('mode_type_reg')) {
+ $record_types.css('display', 'none'); // better than hide because does not change layout
+ $('#recordtype_sel select').find('option').removeAttr('selected');
+ } else {
+ $record_types.css('display', 'inline-block');
+ }
+ });
+
+ $container.on('submit', (event) => {
+ if (isAdvancedDialogOpen === true) {
+ $dialog.close();
+ isAdvancedDialogOpen = false;
+ }
+ /*appEvents.emit('facets.doResetSelectedFacets');*/
+ appEvents.emit('search.doNewSearch', $searchValue.val())
+ return false;
+ });
+ };
+
+ const toggleSearchState = () => {
+ $geoSearchTriggerImg = $('.geo-search-action-btn').find('img');
+ $geoSearchTriggerImg.attr('src', '/assets/common/images/icons/map.png');
+ if (searchPreferences.drawnItems !== undefined) {
+ if (!_.isEmpty(searchPreferences.drawnItems)) {
+ $geoSearchTriggerImg.attr('src', '/assets/common/images/icons/map-active.png');
+ }
+
+ }
+ }
+
+ const updateSearchValue = (params) => {
+ let {searchValue} = params;
+ let reset = params.reset !== undefined ? params.reset : false;
+ let submit = params.submit !== undefined ? params.submit : false;
+ $searchValue.val(searchValue);
+
+ // toogle states:
+ toggleSearchState();
+
+
+ if (submit === true) {
+ if (reset === true) {
+ appEvents.emit('search.doNewSearch', $searchValue.val())
+ } else {
+ appEvents.emit('search.doRefreshState');
+ }
+ }
+
+ return searchValue;
+ }
+
+ const updatePreferences = (preferences) => {
+ for (let prefKey in preferences) {
+ if (preferences.hasOwnProperty(prefKey)) {
+ searchPreferences[prefKey] = preferences[prefKey];
+ user.setPref(prefKey, JSON.stringify(preferences[prefKey]));
+ }
+ }
+ }
+
+ /**
+ * Move entire search form into dialog
+ */
+ const openAdvancedForm = () => {
+ let $searchFormContainer = $container.parent();
+
+ var options = {
+ title: $('#advanced-search-title').val(),
+ size: (window.bodySize.x - 120) + 'x' + (window.bodySize.y - 120),
+ loading: false,
+ closeCallback: function (dialog) {
+ // move back search form
+ $container.appendTo($searchFormContainer);
+
+ // toggle advanced search options
+ $('.adv_trigger', $container).show();
+ $('.adv_options', $container).hide();
+ isAdvancedDialogOpen = false;
+ }
+ };
+
+ $dialog = dialog.create(services, options);
+ $dialog.getDomElement().closest('.ui-dialog').addClass('advanced_search_dialog_container');
+
+ // move all content into dialog:
+ $dialog.getDomElement().append($container);
+
+ // toggle advanced search options
+ $dialog.getDomElement().find('.adv_options').show();
+ $dialog.getDomElement().find('.adv_trigger').hide();
+ isAdvancedDialogOpen = true;
+
+ }
+ appEvents.listenAll({
+ 'searchForm.updateSearchValue': updateSearchValue,
+ 'searchForm.updatePreferences': updatePreferences
+ })
+ return {initialize};
+};
+
+export default searchForm;
diff --git a/Phraseanet-production-client/src/components/story/create.js b/Phraseanet-production-client/src/components/story/create.js
new file mode 100644
index 0000000000..c9017fd7b1
--- /dev/null
+++ b/Phraseanet-production-client/src/components/story/create.js
@@ -0,0 +1,105 @@
+/**
+ * triggered via workzone > Basket > context menu
+ */
+import $ from 'jquery';
+import dialog from './../../phraseanet-common/components/dialog';
+import merge from 'lodash.merge';
+
+const storyCreate = (services) => {
+ const { configService, localeService, appEvents } = services;
+ const url = configService.get('baseUrl');
+ let searchSelectionSerialized = '';
+
+ appEvents.listenAll({
+ 'broadcast.searchResultSelection': (selection) => {
+ searchSelectionSerialized = selection.serialized;
+ }
+ });
+
+ const initialize = () => {
+ $('body').on('click', '.story-create-action', (event) => {
+ event.preventDefault();
+ const $el = $(event.currentTarget);
+ let dialogOptions = {};
+
+ if ($el.attr('title') !== undefined) {
+ dialogOptions.title = $el.attr('title');
+ }
+
+ openModal(dialogOptions);
+ });
+ };
+
+ const openModal = (options = {}) => {
+
+ let dialogOptions = merge({
+ size: 'Small',
+ loading: false
+ }, options);
+ const $dialog = dialog.create(services, dialogOptions);
+
+ return $.get(`${url}prod/story/create/`, function (data) {
+ $dialog.setContent(data);
+ _onDialogReady();
+ return;
+ });
+ };
+
+ const _onDialogReady = () => {
+ var $dialog = dialog.get(1);
+ var $dialogBox = $dialog.getDomElement();
+
+ $('input[name="lst"]', $dialogBox).val(searchSelectionSerialized);
+
+ var buttons = $dialog.getOption('buttons');
+
+ buttons[localeService.t('create')] = function () {
+ $('form', $dialogBox).trigger('submit');
+ };
+
+ $dialog.setOption('buttons', buttons);
+
+ $('form', $dialogBox).bind('submit', function (event) {
+
+ var $form = $(this);
+ var $dialog = $dialogBox.closest('.ui-dialog');
+ var buttonPanel = $dialog.find('.ui-dialog-buttonpane');
+
+ $.ajax({
+ type: $form.attr('method'),
+ url: $form.attr('action'),
+ data: $form.serializeArray(),
+ dataType: 'json',
+ beforeSend: function () {
+ $(":button:contains('" + localeService.t('create') + "')", buttonPanel)
+ .attr('disabled', true).addClass('ui-state-disabled');
+ },
+ success: function (data) {
+
+ appEvents.emit('workzone.refresh', {
+ basketId: data.WorkZone,
+ sort: '',
+ scrolltobottom: true,
+ type: 'story'
+ });
+ dialog.close(1);
+
+ return;
+ },
+ error: function () {
+ $(":button:contains('" + localeService.t('create') + "')", buttonPanel)
+ .attr('disabled', false).removeClass('ui-state-disabled');
+ },
+ timeout: function () {
+
+ }
+ });
+
+ return false;
+ });
+ };
+
+ return {initialize};
+};
+
+export default storyCreate;
diff --git a/Phraseanet-production-client/src/components/story/reorderContent.js b/Phraseanet-production-client/src/components/story/reorderContent.js
new file mode 100644
index 0000000000..7b60847975
--- /dev/null
+++ b/Phraseanet-production-client/src/components/story/reorderContent.js
@@ -0,0 +1,265 @@
+/**
+ * triggered via workzone > Basket > context menu
+ */
+import $ from 'jquery';
+import * as _ from 'underscore';
+import dialog from './../../phraseanet-common/components/dialog';
+import Selectable from '../utils/selectable';
+import merge from 'lodash.merge';
+
+const storyReorderContent = (services) => {
+ const { configService, localeService, appEvents } = services;
+ const url = configService.get('baseUrl');
+
+ const initialize = () => {
+ $('body').on('click', '.story-reorder-content-action', (event) => {
+ event.preventDefault();
+ const $el = $(event.currentTarget);
+ let dialogOptions = {};
+
+ if ($el.attr('title') !== undefined) {
+ dialogOptions.title = $el.attr('title');
+ }
+
+ openModal($el.data('db-id'), $el.data('record-id'), dialogOptions);
+ });
+ };
+
+ const openModal = (dbId, recordId, options = {}) => {
+
+ let dialogOptions = merge({
+ size: 'Medium',
+ loading: false
+ }, options);
+ const $dialog = dialog.create(services, dialogOptions);
+// /prod/story/1/62/reorder/
+ return $.get(`${url}prod/story/${dbId}/${recordId}/reorder/`, function (data) {
+ $dialog.setContent(data);
+ _onDialogReady();
+ return;
+ });
+ };
+
+ const _onDialogReady = () => {
+ var optionsContainer = $('#reorder_options');
+ var container = $('#reorder_box');
+
+ $('button.autoorder', optionsContainer).bind('click', function () {
+ autoorder();
+
+ return false;
+ });
+
+ $('button.reverseorder', optionsContainer).bind('click', function () {
+ reverse_order();
+
+ return false;
+ });
+
+ function autoorder() {
+ var val = $.trim($('#auto_order').val());
+
+ if (val === '') {
+ return;
+ }
+
+ var diapos = [];
+ $('#reorder_box .diapo form').each(function (i, n) {
+ diapos.push({
+ title: $('input[name=title]', n).val(),
+ order: parseInt($('input[name=default]', n).val(), 10),
+ id: $('input[name=id]', n).val(),
+ date_created: new Date($('input[name=date_created]', n).val()),
+ date_updated: new Date($('input[name=date_updated]', n).val()),
+ });
+ });
+
+ var elements = [];
+ var sorterCallback;
+
+ if (val === 'default') {
+ sorterCallback = function (diapo) {
+ return diapo.order;
+ };
+ elements = sorting(sorterCallback, diapos, false);
+ } else if(val === 'date_updated' || val === 'date_created'){
+ sorterCallback = function(diapo) {
+ if(val === 'date_created') {
+ return diapo.date_created;
+ }
+ return diapo.date_updated;
+ };
+ elements = sorting(sorterCallback, diapos, true);
+ } else {
+ sorterCallback = function(diapo) {return diapo.title.toLowerCase();};
+ elements = sorting(sorterCallback, diapos, false);
+ }
+
+ $('#reorder_box .elements').append(elements);
+ }
+
+ function sorting(sorterCallback, diapos, reverse) {
+ var elements = [];
+ if(reverse == true) {
+ _.chain(diapos)
+ .sortBy(sorterCallback)
+ .reverse()
+ .each(function(diapo) {
+ elements.push($('#ORDER_'+ diapo.id));
+ });
+ }else {
+ _.chain(diapos)
+ .sortBy(sorterCallback)
+ .each(function(diapo) {
+ elements.push($('#ORDER_'+ diapo.id));
+ });
+ }
+ return elements;
+ }
+
+ function reverse_order() {
+ var $container = $('#reorder_box .elements');
+ $('#reorder_box .diapo').each(function () {
+ $(this).prependTo($container);
+ });
+ }
+
+ ('.elements div', container).bind('click', function(){
+ $(this).addClass("selected").siblings().removeClass("selected");
+ return false;
+ });
+
+ $('.elements', container).sortable({
+ appendTo: container,
+ placeholder: 'diapo ui-sortable-placeholder',
+ distance: 20,
+ cursorAt: {
+ top: 10,
+ left: -20
+ },
+ items: 'div.diapo',
+ scroll: true,
+ scrollSensitivity: 40,
+ scrollSpeed: 30,
+ start: function (event, ui) {
+ var selected = $('.selected', container);
+
+ selected.each(function (i, n) {
+ $(n).attr('position', i);
+ });
+
+ var n = selected.length - 1;
+
+ $('.selected:visible', container).hide();
+
+ while (n > 0) {
+ $('
').after($('.diapo.ui-sortable-placeholder', container));
+ n--;
+ }
+ },
+ stop: function (event, ui) {
+
+ $('.diapo.ui-sortable-placeholderfollow', container).remove();
+
+ var main_id = $(ui.item[0]).attr('id');
+
+ var selected = $('.selected', container);
+ var sorter = [];
+
+
+ selected.each(function (i, n) {
+
+ var position = parseInt($(n).attr('position'), 10);
+
+ if (position !== '') {
+ sorter[position] = $(n);
+ }
+
+ var id = $(n).attr('id');
+ if (id === main_id) {
+ return;
+ }
+
+ });
+
+ var before = true;
+ var last_moved = $(ui.item[0]);
+ $(sorter).each(function (i, n) {
+ $(n).show().removeAttr('position');
+ if ($(n).attr('id') === main_id) {
+ before = false;
+ } else {
+ if (before) {
+ $(n).before($(ui.item[0]));
+ } else {
+ $(n).after($(last_moved));
+ }
+
+ }
+ last_moved = sorter[i];
+ });
+
+ },
+ change: function () {
+ $('.diapo.ui-sortable-placeholderfollow', container).remove();
+
+ var n = OrderSelection.length() - 1;
+ while (n > 0) {
+ $('
').after($('.diapo.ui-sortable-placeholder', container));
+ n--;
+ }
+ }
+
+ }).disableSelection();
+
+ var OrderSelection = new Selectable(services, $('.elements', container), {
+ selector: '.CHIM'
+ });
+
+
+ $('form[name="reorder"] .btn').bind('click', function (event) {
+ var $form = $(this).closest('form');
+
+ $('.elements form', container).each(function (i, el) {
+ var id = $('input[name="id"]', $(el)).val();
+ $('input[name="element[' + id + ']"]', $form).val(i + 1);
+ });
+
+ $.ajax({
+ type: $form.attr('method'),
+ url: $form.attr('action'),
+ data: $form.serializeArray(),
+ dataType: 'json',
+ beforeSend: function () {
+
+ },
+ success: function (data) {
+ if (!data.success) {
+ alert(data.message);
+ }
+ appEvents.emit('workzone.refresh', {
+ basketId: 'current',
+ sort: null,
+ scrolltobottom: false,
+ type: 'story'
+ });
+ dialog.get(1).close();
+
+ return;
+ },
+ error: function () {
+
+ },
+ timeout: function () {
+
+ }
+ });
+
+ return false;
+ });
+ };
+
+ return {initialize};
+};
+
+export default storyReorderContent;
diff --git a/Phraseanet-production-client/src/components/thesaurus/index.js b/Phraseanet-production-client/src/components/thesaurus/index.js
new file mode 100644
index 0000000000..8cd76bc935
--- /dev/null
+++ b/Phraseanet-production-client/src/components/thesaurus/index.js
@@ -0,0 +1,1370 @@
+import $ from 'jquery';
+import _ from 'underscore';
+import { sprintf } from 'sprintf-js';
+import * as AppCommons from './../../phraseanet-common';
+import dialog from './../../phraseanet-common/components/dialog';
+require('./../../phraseanet-common/components/vendors/contextMenu');
+
+const thesaurusService = services => {
+ const { configService, localeService, appEvents } = services;
+ let options = {};
+ let config = {};
+ let sbas;
+ let bas2sbas;
+ let trees; // @TODO remove global
+ const initialize = params => {
+ let { $container } = params;
+
+ config = configService.get('thesaurusConfig');
+ // set up thlist:
+ options.thlist = {};
+ options.tabs = null;
+ for (let db in config.availableDatabases) {
+ if (config.availableDatabases.hasOwnProperty(db)) {
+ let curDb = config.availableDatabases[db];
+ options.thlist['s' + curDb.id] = new ThesauThesaurusSeeker(
+ curDb.id
+ );
+ }
+ }
+
+ startThesaurus();
+ let cclicks = 0;
+ const cDelay = 350;
+ let cTimer = null;
+ /* unknown usefullness:*/
+ /*let bclicks = 0, bDelay = 350, bTimer = null;
+ $('body')
+ .on('click', '.thesaurus-from-facets-action', (event) => {
+ event.preventDefault();
+ bclicks++;
+
+ if(bclicks === 1) {
+ bTimer = setTimeout(function() {
+ thesau_clickThesaurus(event);
+ bclicks = 0;
+ }, bDelay);
+
+ } else {
+ console.log('double click')
+ clearTimeout(bTimer);
+ thesau_dblclickThesaurus(event);
+ bclicks = 0;
+ }
+ })*/
+
+ $container
+ .on('click', '.thesaurus-branch-action', event => {
+ let $el = $(event.currentTarget);
+ event.preventDefault();
+ cclicks++;
+
+ if (cclicks === 1) {
+ cTimer = setTimeout(function () {
+ Xclick(event);
+ cclicks = 0;
+ }, cDelay);
+ } else {
+ clearTimeout(cTimer);
+
+ if ($el.data('context') === 'thesaurus') {
+ TXdblClick(event);
+ } else {
+ CXdblClick(event);
+ }
+ cclicks = 0;
+ }
+ })
+ .on('dblclick', '.thesaurus-branch-action', event => {
+ // dbl is handled by click event
+ event.preventDefault();
+ })
+ .on('click', '.thesaurus-cancel-wizard-action', event => {
+ // dbl is handled by click event
+ event.preventDefault();
+ thesauCancelWizard();
+ })
+ .on('keyup', '.thesaurus-filter-suggest-action', event => {
+ event.preventDefault();
+ searchValue($(event.currentTarget).val());
+ })
+ .on('submit', '.thesaurus-filter-submit-action', event => {
+ event.preventDefault();
+ T_Gfilter(event.currentTarget);
+ });
+
+ searchValue = _.debounce(searchValue, 300);
+ };
+
+ function show() {
+ // first show of thesaurus
+ if (options.currentWizard === '???') {
+ thesauShowWizard('wiz_0', false);
+ }
+ }
+
+ function thesauCancelWizard() {
+ thesauShowWizard('wiz_0', true);
+ }
+
+ function thesauShowWizard(wizard, refreshFilter) {
+ var offsetTabHeight = $('#THPD_tabs .ui-tabs-nav')[0].offsetHeight;
+ if (wizard !== options.currentWizard) {
+ $('#THPD_WIZARDS DIV.wizard', options.tabs).hide();
+ $('#THPD_WIZARDS .' + wizard, options.tabs).show();
+ $('#THPD_T', options.tabs).css(
+ 'top',
+ $('#THPD_WIZARDS', options.tabs).height() + offsetTabHeight
+ );
+ $('#THPD_C', options.tabs).css(
+ 'top',
+ $('#THPD_WIZARDS', options.tabs).height() + offsetTabHeight
+ );
+
+ options.currentWizard = wizard;
+
+ if (refreshFilter) {
+ searchValue(
+ $('#THPD_WIZARDS .gform', options.tabs).eq(0).val()
+ );
+ }
+ // browse
+ if (wizard === 'wiz_0') {
+ $('#THPD_WIZARDS .th_cancel', options.tabs).hide();
+ } else {
+ $('#THPD_WIZARDS .th_cancel', options.tabs).show();
+ }
+ // accept
+ if (wizard === 'wiz_1') {
+ $('#THPD_WIZARDS .th_ok', options.tabs).hide();
+ } else {
+ $('#THPD_WIZARDS .th_ok', options.tabs).show();
+ }
+
+ $('#THPD_WIZARDS FORM :text')[0].focus();
+ }
+ }
+
+ // here when the 'filter' forms is submited with key or button
+ // force immediate search
+ function T_Gfilter(o) {
+ var f;
+ if (o.nodeName === 'FORM') {
+ f = $(o).find('input[name=search_value]').val();
+ } else if (o.nodeName === 'INPUT') {
+ f = $(o).val();
+ }
+
+ searchValue(f);
+
+ switch (options.currentWizard) {
+ case 'wiz_0': // browse
+ break;
+ case 'wiz_1': // accept
+ break;
+ case 'wiz_2': // replace
+ T_replaceBy2(f);
+ break;
+ default:
+ break;
+ }
+ }
+
+ // here when a key is pressed in the 'filter' form
+ let searchValue = f => {
+ switch (options.currentWizard) {
+ case 'wiz_0': // browse
+ searchValueByMode(f, 'ALL');
+ break;
+ case 'wiz_1': // accept
+ searchValueByMode(f, 'CANDIDATE');
+ break;
+ case 'wiz_2': // replace
+ searchValueByMode(f, 'CANDIDATE');
+ break;
+ default:
+ break;
+ }
+ };
+
+ function T_replaceBy2(f) {
+ if (trees.C._selInfos.n !== 1) {
+ return;
+ }
+ let term = trees.C._selInfos.sel.eq(0).find('span span').html();
+ let cid = trees.C._selInfos.sel[0].getAttribute('id').split('.');
+ cid.shift();
+ let sbas = cid.shift();
+ cid = cid.join('.');
+
+ trees.C._toReplace = { sbas: sbas, cid: cid, replaceby: f };
+
+ let msg = sprintf(config.replaceMessage, { from: term, to: f });
+
+ let confirmBox = dialog.create(services, {
+ size: 'Alert',
+ closeOnEscape: true,
+ cancelButton: true,
+ buttons: {
+ Ok: function () {
+ confirmBox.close();
+ T_replaceCandidates_OK();
+ }
+ }
+ });
+ confirmBox.setContent(msg);
+ }
+
+ function searchValueByMode(f, mode) {
+ if (mode === 'ALL') {
+ let type;
+ let id;
+ let z = '';
+ if (
+ $('.ui-tabs-nav li.ui-state-active a', options.tabs).attr(
+ 'href'
+ ) === '#THPD_T'
+ ) {
+ //thesaurus
+ type = 'TH';
+ id = 'T';
+ } else {
+ //candidate
+ type = 'CT';
+ id = 'C';
+ }
+ // search in every base, everywhere
+ for (let i in sbas) {
+ let zurl =
+ '/xmlhttp/search_term_prod.j.php' +
+ '?sbid=' +
+ sbas[i].sbid +
+ '&typ=' +
+ type +
+ '&id=' +
+ id +
+ '&t=' +
+ encodeURIComponent(f);
+ $('#THPD_T_treeBox').addClass('loading');
+ sbas[i].seeker = $.ajax({
+ url: zurl,
+ type: 'POST',
+ data: [],
+ dataType: 'json',
+ success: function (j) {
+ var z = '#TX_P\\.' + j.parm.sbid + '\\.T';
+ if (type === 'TH') {
+ z = '#TX_P\\.' + j.parm.sbid + '\\.' + id;
+ } else {
+ z = '#CX_P\\.' + j.parm.sbid + '\\.' + id;
+ }
+
+ var o = $(z);
+ var isLast = o.hasClass('last');
+
+ o.replaceWith(j.html);
+
+ if (isLast) {
+ $(z).addClass('last');
+ }
+ },
+ complete: function () {
+ $('#THPD_T_treeBox').removeClass('loading');
+ }
+ });
+ }
+ } else if (mode === 'CANDIDATE') {
+ // search only on the good base and the good branch(es)
+ for (let i in sbas) {
+ var zurl =
+ '/xmlhttp/search_term_prod.j.php?sbid=' +
+ sbas[i].sbid +
+ '&typ=TH' +
+ '&id=T';
+
+ $('#THPD_T_treeBox').addClass('loading');
+ if (sbas[i].sbid === trees.C._selInfos.sbas) {
+ zurl +=
+ '&t=' +
+ encodeURIComponent(f) +
+ '&field=' +
+ encodeURIComponent(trees.C._selInfos.field);
+ }
+ sbas[i].seeker = $.ajax({
+ url: zurl,
+ type: 'POST',
+ data: [],
+ dataType: 'json',
+ success: function (j) {
+ var z = '#TX_P\\.' + j.parm.sbid + '\\.T';
+
+ var o = $(z);
+ var isLast = o.hasClass('last');
+
+ o.replaceWith(j.html);
+
+ if (isLast) {
+ $(z).addClass('last');
+ }
+ },
+ complete: function () {
+ $('#THPD_T_treeBox').removeClass('loading');
+ }
+ });
+ }
+ }
+ }
+
+ // ======================================================================================================
+
+ function T_replaceCandidates_OK() {
+ var replacingBox = dialog.create(services, {
+ size: 'Alert'
+ });
+ replacingBox.setContent(config.replaceInProgressMsg);
+
+ var parms = {
+ url: '/xmlhttp/replacecandidate.j.php',
+ data: {
+ 'id[]': trees.C._toReplace.sbas + '.' + trees.C._toReplace.cid,
+ t: trees.C._toReplace.replaceby,
+ debug: '0'
+ },
+ async: false,
+ cache: false,
+ dataType: 'json',
+ timeout: 10 * 60 * 1000, // 10 minutes !
+ success: function (result, textStatus) {
+ trees.C._toReplace = null;
+ thesauShowWizard('wiz_0', false);
+
+ replacingBox.close();
+
+ if (result.msg !== '') {
+ var alert = dialog.create(services, {
+ size: 'Alert',
+ closeOnEscape: true,
+ closeButton: true
+ });
+ alert.setContent(result.msg);
+ }
+
+ for (let i in result.ctermsDeleted) {
+ var cid =
+ '#CX_P\\.' +
+ result.ctermsDeleted[i].replace(
+ new RegExp('\\.', 'g'),
+ '\\.'
+ ); // escape les '.' pour jquery
+ $(cid).remove();
+ }
+ },
+ _ret: null // private alchemy
+ };
+
+ $.ajax(parms);
+ }
+
+ function T_acceptCandidates_OK() {
+ let same_sbas = true;
+ let acceptingBox = dialog.create(services, {
+ size: 'Alert'
+ });
+ acceptingBox.setContent(config.acceptMsg);
+
+ let t_ids = [];
+ let dst = trees.C._toAccept.dst.split('.');
+ dst.shift();
+ let sbid = dst.shift();
+ dst = dst.join('.');
+ // obviously the candidates and the target already complies (same sbas, good tbranch)
+ trees.C._selInfos.sel.each(function () {
+ var x = this.getAttribute('id').split('.');
+ x.shift();
+ if (x.shift() !== sbid) {
+ same_sbas = false;
+ }
+ t_ids.push(x.join('.'));
+ });
+
+ if (!same_sbas) {
+ return;
+ }
+
+ var parms = {
+ url: '/xmlhttp/acceptcandidates.j.php',
+ data: {
+ // "debug": false,
+ sbid: sbid,
+ tid: dst,
+ 'cid[]': t_ids,
+ typ: trees.C._toAccept.type,
+ piv: trees.C._toAccept.lng
+ },
+ async: false,
+ cache: false,
+ dataType: 'json',
+ success: function (result, textStatus) {
+ for (let i in result.refresh) {
+ var zurl =
+ '/xmlhttp/openbranch_prod.j.php' +
+ '?type=' +
+ result.refresh[i].type +
+ '&sbid=' +
+ result.refresh[i].sbid +
+ '&sortsy=1' +
+ '&id=' +
+ encodeURIComponent(result.refresh[i].id);
+
+ $.get(
+ zurl,
+ [],
+ function (j) {
+ var z =
+ '#' +
+ j.parm.type +
+ 'X_P\\.' +
+ j.parm.sbid +
+ '\\.' +
+ j.parm.id.replace(
+ new RegExp('\\.', 'g'),
+ '\\.'
+ ); // escape les '.' pour jquery
+
+ $(z).children('ul').eq(0).replaceWith(j.html);
+ },
+ 'json'
+ );
+ }
+ trees.C._toAccept = null;
+ thesauShowWizard('wiz_0', false);
+ acceptingBox.close();
+ },
+ error: function () {
+ acceptingBox.close();
+ },
+ timeout: function () {
+ acceptingBox.close();
+ },
+ _ret: null // private alchemy
+ };
+
+ $.ajax(parms);
+ }
+
+ function C_deleteCandidates_OK() {
+ var deletingBox = dialog.create(services, {
+ size: 'Alert'
+ });
+ deletingBox.setContent(config.deleteMsg);
+
+ var t_ids = [];
+ var lisel = trees.C.tree.find('LI .selected');
+ trees.C.tree.find('LI .selected').each(function () {
+ var x = this.getAttribute('id').split('.');
+ x.shift();
+ t_ids.push(x.join('.'));
+ });
+ var parms = {
+ url: '/xmlhttp/replacecandidate.j.php',
+ data: { 'id[]': t_ids },
+ async: false,
+ cache: false,
+ dataType: 'json',
+ timeout: 10 * 60 * 1000, // 10 minutes !
+ success: function (result, textStatus) {
+ deletingBox.close();
+
+ if (result.msg !== '') {
+ var alert = dialog.create(services, {
+ size: 'Alert',
+ closeOnEscape: true,
+ closeButton: true
+ });
+ alert.setContent(result.msg);
+ }
+
+ for (let i in result.ctermsDeleted) {
+ var cid =
+ '#CX_P\\.' +
+ result.ctermsDeleted[i].replace(
+ new RegExp('\\.', 'g'),
+ '\\.'
+ ); // escape les '.' pour jquery
+ $(cid).remove();
+ }
+ },
+ _ret: null
+ };
+
+ $.ajax(parms);
+ }
+
+ // menu option T:accept as...
+ function T_acceptCandidates(menuItem, menu, type) {
+ var lidst = trees.T.tree.find('LI .selected');
+ if (lidst.length !== 1) {
+ return;
+ }
+
+ var lisel = trees.C.tree.find('LI .selected');
+ if (lisel.length === 0) {
+ return;
+ }
+
+ var msg;
+
+ if (lisel.length === 1) {
+ var term = lisel.eq(0).find('span span').html();
+ msg = sprintf(config.candidateUniqueMsg, term);
+ } else {
+ msg = sprintf(config.candidateManyMsg, lisel.length);
+ }
+
+ trees.C._toAccept.type = type;
+ trees.C._toAccept.dst = lidst.eq(0).attr('id');
+
+ var confirmBox = dialog.create(services, {
+ size: 'Alert',
+ closeOnEscape: true,
+ cancelButton: true,
+ buttons: {
+ Ok: function () {
+ confirmBox.close();
+ T_acceptCandidates_OK();
+ }
+ }
+ });
+ confirmBox.setContent(msg);
+ }
+
+ // menu option T:search
+ function T_search(menuItem, menu, cmenu, e, label) {
+ if (!menu._li) {
+ return;
+ }
+ var tcids = menu._li.attr('id').split('.');
+ tcids.shift();
+ var sbid = tcids.shift();
+ var term = menu._li.find('span span').html();
+
+ doThesSearch('T', sbid, term, null);
+ }
+
+ function C_MenuOption(menuItem, menu, option, parm) {
+ // nothing selected in candidates ?
+ if (!trees.C._selInfos) {
+ return;
+ }
+
+ trees.C._toAccept = null; // cancel previous 'accept' action anyway
+ trees.C._toReplace = null; // cancel previous 'replace' action anyway
+ // display helpful message into the thesaurus box...
+ let msg;
+ let term;
+ switch (option) {
+ case 'ACCEPT':
+ // glue selection to the tree
+ trees.C._toAccept = { lng: parm.lng };
+
+ if (trees.C._selInfos.n === 1) {
+ msg = sprintf(
+ config.acceptCandidateUniqueMsg,
+ menu._srcElement.find('span').html()
+ );
+ } else {
+ msg = sprintf(
+ config.acceptCandidateManyMsg,
+ trees.C._selInfos.n
+ );
+ }
+
+ // set the content of the wizard
+ $('#THPD_WIZARDS .wiz_1 .txt').html(msg);
+ // ... and switch to the thesaurus tab
+ options.tabs.tabs('option', 'active', 0);
+ thesauShowWizard('wiz_1', true);
+
+ break;
+
+ case 'REPLACE':
+ if (trees.C._selInfos.n === 1) {
+ term = trees.C._selInfos.sel.eq(0).find('span span').html();
+ msg = sprintf(config.replaceCandidateUniqueMsg, term);
+ } else {
+ msg = sprintf(
+ config.replaceCandidateManyMsg,
+ trees.C._selInfos.n
+ );
+ }
+
+ options.tabs.tabs('option', 'active', 0);
+
+ // set the content of the wizard
+ $('#THPD_WIZARDS .wiz_2 .txt').html(msg);
+ // ... and switch to the thesaurus tab
+ thesauShowWizard('wiz_2', true);
+
+ break;
+
+ case 'DELETE':
+ $('#THPD_WIZARDS DIV', options.tabs).hide();
+
+ if (trees.C._selInfos.n === 1) {
+ term = trees.C._selInfos.sel.eq(0).find('span span').html();
+ msg = sprintf(config.deleteCandidateUniqueMsg, term);
+ } else {
+ msg = sprintf(
+ config.deleteCandidateManyMsg,
+ trees.C._selInfos.n
+ );
+ }
+
+ let confirmBox = dialog.create(services, {
+ size: 'Alert',
+ closeOnEscape: true,
+ cancelButton: true,
+ buttons: {
+ Ok: function () {
+ confirmBox.close();
+ C_deleteCandidates_OK();
+ }
+ }
+ });
+ confirmBox.setContent(msg);
+
+ break;
+ default:
+ }
+ }
+
+ function Xclick(e) {
+ let x = e.srcElement ? e.srcElement : e.target;
+ let li = $(x).closest('li');
+ let tids = li.attr('id').split('.');
+ let type;
+ switch (x.nodeName) {
+ case 'DIV': // +/-
+ var tid = tids.shift();
+ var sbid = tids.shift();
+ type = tid.substr(0, 1);
+ // TX_P ou CX_P
+ if (
+ (type === 'T' || type === 'C') &&
+ tid.substr(1, 4) === 'X_P'
+ ) {
+ var ul = li.children('ul').eq(0);
+ if (
+ ul.css('display') === 'none' ||
+ AppCommons.utilsModule.is_ctrl_key(e)
+ ) {
+ if (AppCommons.utilsModule.is_ctrl_key(e)) {
+ ul.text(config.loadingMsg);
+ li.removeAttr('loaded');
+ }
+
+ ul.show();
+
+ if (!li.attr('loaded')) {
+ var zurl =
+ '/xmlhttp/openbranch_prod.j.php?type=' +
+ type +
+ '&sbid=' +
+ sbid +
+ '&id=' +
+ encodeURIComponent(tids.join('.'));
+ if (li.hasClass('last')) {
+ zurl += '&last=1';
+ }
+ zurl += '&sortsy=1';
+
+ $.get(
+ zurl,
+ [],
+ function (j) {
+ ul.replaceWith(j.html);
+ li.attr('loaded', '1');
+ },
+ 'json'
+ );
+ }
+ } else {
+ ul.hide();
+ }
+ }
+ break;
+ case 'SPAN':
+ type = tids[0].substr(0, 1);
+ if ((type === 'T' && tids.length > 2) || tids.length === 4) {
+ tids.pop();
+ var tid3 = tids.join('.');
+ if (
+ !AppCommons.utilsModule.is_ctrl_key(e) &&
+ !AppCommons.utilsModule.is_shift_key(e)
+ ) {
+ $('LI', trees[type].tree).removeClass('selected');
+ options.lastClickedCandidate = null;
+ } else {
+ // if($("#THPD_C_treeBox")._lastClicked)
+ if (options.lastClickedCandidate !== null) {
+ if (options.lastClickedCandidate.tid3 !== tid3) {
+ $('LI', trees[type].tree).removeClass(
+ 'selected'
+ );
+ options.lastClickedCandidate = null;
+ } else {
+ if (e.shiftKey) {
+ var lip = li.parent().children('li');
+ var idx0 = lip.index(
+ options.lastClickedCandidate.item
+ );
+ var idx1 = lip.index(li);
+ if (idx0 < idx1) {
+ lip
+ .filter(function (index) {
+ return (
+ index >= idx0 &&
+ index < idx1
+ );
+ })
+ .addClass('selected');
+ } else {
+ lip
+ .filter(function (index) {
+ return (
+ index > idx1 &&
+ index <= idx0
+ );
+ })
+ .addClass('selected');
+ }
+ }
+ }
+ }
+ }
+ li.toggleClass('selected');
+ if (type === 'C') {
+ options.lastClickedCandidate = { item: li, tid3: tid3 };
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ function TXdblClick(e) {
+ let x = e.srcElement ? e.srcElement : e.target;
+ let tid = $(x).closest('li').attr('id');
+ let term;
+ switch (x.nodeName) {
+ case 'SPAN': // term
+ switch (options.currentWizard) {
+ case 'wiz_0': // simply browse
+ if (tid.substr(0, 5) === 'TX_P.') {
+ var tids = tid.split('.');
+ if (tids.length > 3) {
+ var sbid = tids[1];
+ term = $(x).hasClass('separator')
+ ? $(x).prev().text()
+ : $(x).text();
+ doThesSearch('T', sbid, term, null);
+ }
+ }
+ break;
+ case 'wiz_2': // replace by
+ if (tid.substr(0, 5) === 'TX_P.') {
+ term = $(x).text();
+ $('#THPD_WIZARDS .wiz_2 :text').val(term);
+ T_replaceBy2(term);
+ }
+ break;
+ default:
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ function CXdblClick(e) {
+ var x = e.srcElement ? e.srcElement : e.target;
+ switch (x.nodeName) {
+ case 'SPAN': // term
+ var li = $(x).closest('li');
+ var field = li.closest('[field]').attr('field');
+ if (typeof field !== 'undefined') {
+ var tid = li.attr('id');
+ if (tid.substr(0, 5) === 'CX_P.') {
+ var sbid = tid.split('.')[1];
+ var term = $(x).text();
+ doThesSearch('C', sbid, term, field);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ function doThesSearch(type, sbid, term, field) {
+ appEvents.emit('searchAdvancedForm.activateDatabase', { databases: [sbid] });
+
+ let queryString = '';
+ if (type === 'T') {
+ queryString = '[' + term + ']';
+ } else {
+ queryString = field + '="' + term + '"';
+ }
+ appEvents.emit('facets.doResetSelectedFacets');
+ $('#EDIT_query').val(queryString);
+ appEvents.emit('searchAdvancedForm.checkFilters');
+ appEvents.emit('search.doNewSearch', queryString);
+ //searchModule.newSearch(v);
+ }
+
+ /* unknown usefullness:
+ function thesau_clickThesaurus(event) // onclick dans le thesaurus
+ {
+ // on cherche ou on a clique
+ for(var e=event.srcElement ? event.srcElement : event.target; e && ((!e.tagName) || (!e.id)); e=e.parentNode)
+ ;
+ if(e)
+ {
+ switch(e.id.substr(0,4))
+ {
+ case "TH_P": // +/- de deploiement de mot
+ js = "thesau_thesaurus_ow('"+e.id.substr(5)+"')";
+ self.setTimeout(js, 10);
+ break;
+ }
+ }
+ return(false);
+ }
+
+ function thesau_dblclickThesaurus(event) // onclick dans le thesaurus
+ {
+ var err;
+ try
+ {
+ options.lastTextfocus.focus();
+ }
+ catch(err)
+ {
+ return;
+ }
+
+ // on cherche ou on a clique
+ for(var e=event.srcElement; e && ((!e.tagName) || (!e.id)); e=e.parentNode)
+ ;
+ if(e)
+ {
+ switch(e.id.substr(0,4))
+ {
+ case "GL_W": // double click sur le mot
+ var t = e.id.split(".");
+ t.shift();
+ var sbid = t.shift();
+ var thid = t.join(".");
+ var url = "/xmlhttp/getsy_prod.x.php";
+ var parms = "bid=" + sbid + "&id=" + thid;
+
+ var xmlhttp = new XMLHttpRequest();
+ xmlhttp.open("POST", url, false);
+ xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
+ xmlhttp.send(parms);
+ var ret = xmlhttp.responseXML;
+
+ result = ret.getElementsByTagName("result");
+ if(result.length==1)
+ {
+ val = result.item(0).getAttribute("t");
+ replaceEditSel(val);
+ }
+ break;
+ }
+ }
+ return(false);
+ }
+ function replaceEditSel(value)
+ {
+ if(!options.lastTextfocus || !options.lastTextfocus.selectedTerm)
+ return;
+
+ options.lastTextfocus.value = options.lastTextfocus.value.substr(0, options.lastTextfocus.selectedTerm.start) + value + options.lastTextfocus.value.substr(options.lastTextfocus.selectedTerm.end);
+ if(typeof(document.selection) != 'undefined')
+ {
+ // explorer
+ var range = options.lastTextfocus.createTextRange();
+ range.move('character', options.lastTextfocus.selectedTerm.start + value.length);
+ range.select();
+ }
+ else if(typeof(options.lastTextfocus.selectionStart) != 'undefined')
+ {
+ // gecko (safari)
+ options.lastTextfocus.selectionStart = options.lastTextfocus.selectionEnd = options.lastTextfocus.selectedTerm.start + value.length;
+ }
+ cbEditing2(options.lastTextfocus, "MOUSEUP"); // force le calcul de la nouvelle selection
+ options.lastTextfocus.focus();
+ return;
+ }
+
+
+ function thesau_thesaurus_ow(id) // on ouvre ou ferme une branche de thesaurus
+ {
+ var o = document.getElementById("TH_K."+id);
+ if(o.className=="o")
+ {
+ // on ferme
+ o.className = "c";
+ document.getElementById("TH_P."+id).innerHTML = "+";
+ document.getElementById("TH_K."+id).innerHTML = config.loadingMsg;
+ }
+ else if(o.className=="c" || o.className=="h")
+ {
+ // on ouvre
+ o.className = "o";
+ document.getElementById("TH_P."+id).innerHTML = "-";
+
+ var t_id = id.split(".");
+ var sbas_id = t_id[0];
+ t_id.shift();
+ var thid = t_id.join(".");
+ var url = "/xmlhttp/getterm_prod.x.php";
+ var parms = "bid=" + sbas_id;
+ parms += "&lng="+p4.lng;
+ parms += "&sortsy=1";
+ parms += "&id=" + thid;
+ parms += "&typ=TH";
+
+ options.thlist['s'+sbas_id].openBranch(id, thid);
+ }
+ return(false);
+ }
+
+ function cbEditing2(textarea, act)
+ {
+ var sbas_id = p4.edit.sbas_id;
+ tmpCurField = 0;
+
+ if(textarea.id=="idZTextArea")
+ {
+ tmpCurField = p4.edit.curField ;
+ }
+ else
+ {
+ if(textarea.id=="idZTextAreaReg")
+ tmpCurField = p4.edit.curFieldReg;
+ }
+
+ options.lastTextfocus = textarea;
+ textarea.selectedTerm = null;
+ var p0 = -1;
+ var p1 = -1;
+ if(typeof(document.selection) != 'undefined')
+ {
+ // ici si explorer
+ var range = document.selection.createRange();
+ var i;
+ var oldrange = range.duplicate();
+ for(i=0; i<200; i++, p0++)
+ {
+ pe = range.parentElement();
+ if(pe != textarea)
+ break;
+ range.moveStart("character", -1);
+ }
+ range = oldrange.duplicate();
+ for(i=0; i<200; i++, p1++)
+ {
+ pe = range.parentElement();
+ if(pe != textarea)
+ break;
+ range.moveEnd("character", -1);
+ }
+ }
+ else if(typeof(textarea.selectionStart) != "undefined")
+ {
+ // ici si gecko (safari)
+ p0 = textarea.selectionStart;
+ p1 = textarea.selectionEnd;
+ }
+ if(p0 != -1 && p1 != -1)
+ {
+ var c;
+ // on etend les positions a tout le keyword (entre ';')
+ t = textarea.value;
+ l = t.length;
+ for( ; p0 > 0; p0--)
+ {
+ c = t.charCodeAt(p0-1);
+ if(c==59 || c==10 || c==13) // 59==";"
+ break;
+ }
+ for( ; p1 < l; p1++)
+ {
+ c = t.charCodeAt(p1);
+ if(c==59 || c==10 || c==13)
+ break;
+ }
+ // on copie le resultat dans le textarea
+ textarea.selectedTerm = { start:p0, end:p1 };
+
+ // on cherche le terme dans le thesaurus
+ var zText = textarea.value.substr(p0, p1-p0);
+
+ if(document.forms["formSearchTH"].formSearchTHck.checked)
+ {
+ if(zText && zText.length>2 && document.forms["formSearchTH"].formSearchTHfld.value != zText)
+ {
+ document.forms["formSearchTH"].formSearchTHfld.value = zText;
+
+ document.getElementById("TH_searching").src = "/assets/common/images/icons/ftp-loader.gif";
+ options.thlist['s'+sbas_id].search(zText);
+ }
+ }
+ }
+ return(true);
+ }
+ */
+
+ function ThesauThesaurusSeeker(sbas_id) {
+ this.sbas_id = sbas_id;
+ this._ctimer = null;
+ this._xmlhttp = null;
+ this.tObj = { TH_searching: null, TH_P: null, TH_K: null };
+ this.search = function (txt) {
+ if (this._ctimer) {
+ clearTimeout(this._ctimer);
+ }
+ this._ctimer = setTimeout(() => {
+ return options.thlist['s' + this.sbas_id].search_delayed(
+ '"' + txt.replace("'", "\\'") + '"'
+ );
+ }, 100);
+ };
+ this.search_delayed = function (txt) {
+ var me = this;
+ if (
+ this._xmlttp.abort &&
+ typeof this._xmlttp.abort === 'function'
+ ) {
+ this._xmlhttp.abort();
+ }
+ var url = '/xmlhttp/openbranches_prod.x.php';
+ var parms = {
+ bid: this.sbas_id,
+ t: txt,
+ mod: 'TREE'
+ };
+
+ this._xmlhttp = $.ajax({
+ url: url,
+ type: 'POST',
+ data: parms,
+ success: function (ret) {
+ me.xmlhttpstatechanged(ret);
+ },
+ error: function () {},
+ timeout: function () {}
+ });
+
+ this._ctimer = null;
+ };
+ this.openBranch = function (id, thid) {
+ var me = this;
+ if (
+ this._xmlttp.abort &&
+ typeof this._xmlttp.abort === 'function'
+ ) {
+ this._xmlhttp.abort();
+ }
+ var url = '/xmlhttp/getterm_prod.x.php';
+ var parms = {
+ bid: this.sbas_id,
+ sortsy: 1,
+ id: thid,
+ typ: 'TH'
+ };
+
+ this._xmlhttp = $.ajax({
+ url: url,
+ type: 'POST',
+ data: parms,
+ success: function (ret) {
+ me.xmlhttpstatechanged(ret, id);
+ },
+ error: function () {},
+ timeout: function () {}
+ });
+ };
+ this.xmlhttpstatechanged = function (ret, id) {
+ try {
+ if (!this.tObj.TH_searching) {
+ this.tObj.TH_searching = document.getElementById(
+ 'TH_searching'
+ );
+ }
+ this.tObj.TH_searching.src =
+ '/assets/common/images/icons/ftp-loader-blank.gif';
+ // && (typeof(ret.parsed)=="undefined" || ret.parsed))
+ if (ret) {
+ let htmlnodes = ret.getElementsByTagName('html');
+ let htmlnode = htmlnodes.item(0).firstChild;
+ if (htmlnodes && htmlnodes.length === 1 && htmlnode) {
+ if (typeof id === 'undefined') {
+ // called from search or 'auto' : full thesaurus search
+ if (!this.tObj.TH_P) {
+ this.tObj.TH_P = document.getElementById(
+ 'TH_P.' + this.sbas_id + '.T'
+ );
+ }
+ if (!this.tObj.TH_K) {
+ this.tObj.TH_K = document.getElementById(
+ 'TH_K.' + this.sbas_id + '.T'
+ );
+ }
+ this.tObj.TH_P.innerHTML = '...';
+ this.tObj.TH_K.className = 'h';
+ this.tObj.TH_K.innerHTML = htmlnode.nodeValue;
+ } else {
+ // called from 'openBranch'
+ // var js = "document.getElementById('TH_K."+thid+"').innerHTML = \""+htmlnode.nodeValue+"\"";
+ // self.setTimeout(js, 10);
+ document.getElementById('TH_K.' + id).innerHTML =
+ htmlnode.nodeValue;
+ }
+ }
+ }
+ } catch (err) {}
+ };
+ }
+
+ function startThesaurus() {
+ options.thlist = config.thlist;
+ options.currentWizard = '???';
+
+ sbas = config.sbas;
+ bas2sbas = config.bas2sbas;
+
+ options.lastTextfocus = null;
+
+ options.lastClickedCandidate = null;
+
+ options.tabs = $('#THPD_tabs');
+ options.tabs.tabs();
+
+ trees = {
+ T: {
+ tree: $('#THPD_T_tree', options.tabs)
+ },
+ C: {
+ tree: $('#THPD_C_tree', options.tabs),
+ // may contain : {'type', 'dst', 'lng'}
+ _toAccept: null,
+ _toReplace: null,
+ // may contain : {'sel':lisel, 'field':field, 'sbas':sbas, 'n':lisel.length}
+ _selInfos: null
+ }
+ };
+
+ trees.T.tree.contextMenu(
+ [
+ {
+ label: config.searchMsg,
+ onclick: function (menuItem, menu, cmenu, e, label) {
+ T_search(menuItem, menu, cmenu, e, label);
+ }
+ },
+ {
+ label: config.acceptSpecificTermMsg,
+ onclick: function (menuItem, menu) {
+ T_acceptCandidates(menuItem, menu, 'TS');
+ }
+ },
+ {
+ label: config.acceptSynonymeMsg,
+ onclick: function (menuItem, menu) {
+ T_acceptCandidates(menuItem, menu, 'SY');
+ }
+ }
+ ],
+ {
+ className: 'THPD_TMenu',
+ beforeShow: function () {
+ var menuOptions = $(this.menu).find('.context-menu-item');
+ menuOptions.eq(1).addClass('context-menu-item-disabled');
+ menuOptions.eq(2).addClass('context-menu-item-disabled');
+
+ var x = this._showEvent.srcElement
+ ? this._showEvent.srcElement
+ : this._showEvent.target;
+ var li = $(x).closest('li');
+ this._li = null;
+ var tcids = li.attr('id').split('.');
+ if (
+ tcids.length > 2 &&
+ tcids[0] === 'TX_P' &&
+ tcids[2] !== 'T' &&
+ x.nodeName !== 'LI'
+ ) {
+ this._li = li;
+ tcids.shift();
+ var sbas = tcids.shift();
+
+ // this._srcElement = li; // private alchemy
+ if (!li.hasClass('selected')) {
+ // rclick OUTSIDE the selection : unselect all
+ trees.T.tree.find('LI').removeClass('selected');
+
+ $('li', trees.T.tree).removeClass('selected');
+ li.addClass('selected');
+ }
+
+ if (
+ trees.C._selInfos &&
+ trees.C._selInfos.sbas === sbas
+ ) {
+ // whe check if the candidates can be validated here
+ // aka does the tbranch of the field (of candidates) reaches the paste location ?
+ var parms = {
+ url:
+ '/xmlhttp/checkcandidatetarget.j.php' +
+ '?sbid=' +
+ sbas +
+ '&acf=' +
+ encodeURIComponent(
+ trees.C._selInfos.field
+ ) +
+ '&id=' +
+ encodeURIComponent(tcids.join('.')),
+ data: [],
+ async: false,
+ cache: false,
+ dataType: 'json',
+ timeout: 1000,
+ success: function (result, textStatus) {
+ this._ret = result;
+ if (result.acceptable) {
+ menuOptions
+ .eq(1)
+ .removeClass(
+ 'context-menu-item-disabled'
+ );
+ menuOptions
+ .eq(2)
+ .removeClass(
+ 'context-menu-item-disabled'
+ );
+ }
+ },
+ _ret: null // private alchemy
+ };
+
+ $.ajax(parms);
+ }
+ }
+ return true;
+ }
+ }
+ );
+
+ var contextMenu = [];
+ for (let i = 0; i < config.langContextMenu.length; i++) {
+ var langPlist = config.langContextMenu[i];
+ contextMenu.push({
+ label: langPlist.label,
+ onclick: function (menuItem, menu) {
+ C_MenuOption(menuItem, menu, 'ACCEPT', {
+ lng: langPlist.lngCode
+ });
+ }
+ });
+ }
+
+ contextMenu.push({
+ label: config.replaceWithMsg,
+ // disabled:true,
+ onclick: function (menuItem, menu) {
+ C_MenuOption(menuItem, menu, 'REPLACE', null);
+ }
+ });
+
+ contextMenu.push({
+ label: config.removeActionMsg,
+ // disabled:true,
+ onclick: function (menuItem, menu) {
+ C_MenuOption(menuItem, menu, 'DELETE', null);
+ }
+ });
+
+ trees.C.tree.contextMenu(contextMenu, {
+ beforeShow: function () {
+ var ret = false;
+
+ var x = this._showEvent.srcElement
+ ? this._showEvent.srcElement
+ : this._showEvent.target;
+ var li = $(x).closest('li');
+
+ if (!li.hasClass('selected')) {
+ // rclick OUTSIDE the selection : unselect all
+ // lisel.removeClass('selected');
+ trees.C.tree.find('LI').removeClass('selected');
+ options.lastClickedCandidate = null;
+ }
+ var tcids = li.attr('id').split('.');
+ if (
+ tcids.length === 4 &&
+ tcids[0] === 'CX_P' &&
+ x.nodeName !== 'LI'
+ ) {
+ // candidate context menu only clicking on final term
+ if (!li.hasClass('selected')) {
+ li.addClass('selected');
+ }
+ // this._cutInfos = { sbid:tcids[1], field:li.parent().attr('field') }; // private alchemy
+ this._srcElement = li; // private alchemy
+
+ // as selection changes, compute usefull info (field, sbas)
+ var lisel = trees.C.tree.find('LI .selected');
+ if (lisel.length > 0) {
+ // lisel are all from the same candidate field, so check the first li
+ var li0 = lisel.eq(0);
+ var field = li0.parent().attr('field');
+ var sbas = li0.attr('id').split('.')[1];
+
+ // glue selection info to the tree
+ trees.C._selInfos = {
+ sel: lisel,
+ field: field,
+ sbas: sbas,
+ n: lisel.length
+ };
+
+ if (lisel.length === 1) {
+ $(this.menu)
+ .find('.context-menu-item')
+ .eq(config.languagesCount)
+ .removeClass('context-menu-item-disabled');
+ } else {
+ $(this.menu)
+ .find('.context-menu-item')
+ .eq(config.languagesCount)
+ .addClass('context-menu-item-disabled');
+ }
+ } else {
+ trees.C._selInfos = null;
+ }
+
+ ret = true;
+ }
+ return ret;
+ }
+ });
+ }
+
+ return { initialize, show };
+};
+
+export default thesaurusService;
diff --git a/Phraseanet-production-client/src/components/ui/index.js b/Phraseanet-production-client/src/components/ui/index.js
new file mode 100644
index 0000000000..5c87dad81d
--- /dev/null
+++ b/Phraseanet-production-client/src/components/ui/index.js
@@ -0,0 +1,452 @@
+import $ from 'jquery';
+import * as appCommons from './../../phraseanet-common';
+import toolbar from './toolbar';
+import mainMenu from '../mainMenu';
+import keyboard from './keyboard';
+import cgu from '../cgu';
+import editRecordService from '../record/edit';
+import exportRecord from '../record/export';
+import shareRecord from '../record/share';
+import recordVideoEditorModal from '../record/videoEditor/index';
+import addToBasket from '../record/addToBasket';
+import removeFromBasket from '../record/removeFromBasket';
+import printRecord from '../record/print';
+import preferences from '../preferences';
+import order from '../order';
+import previewRecordService from '../record/recordPreview';
+import Alerts from '../utils/alert';
+import uploader from '../uploader';
+
+const ui = services => {
+ const { configService, localeService, appEvents } = services;
+ let activeZone = false;
+ let searchSelection = { asArray: [], serialized: '' };
+ let workzoneSelection = { asArray: [], serialized: '' };
+
+ const initialize = options => {
+ let { $container } = options;
+ // init state navigation
+ // records and baskets actions in global interface:
+ exportRecord(services).initialize();
+ addToBasket(services).initialize();
+ removeFromBasket(services).initialize();
+ printRecord(services).initialize();
+ shareRecord(services).initialize(options);
+ cgu(services).initialize(options);
+ preferences(services).initialize(options);
+ order(services).initialize(options);
+
+ let editRecord = editRecordService(services);
+ editRecord.initialize();
+
+ let previewRecord = previewRecordService(services);
+
+ let previewIsOpen = false;
+ previewRecord.getPreviewStream().subscribe(function (previewOptions) {
+ previewIsOpen = previewOptions.open;
+ });
+ previewRecord.initialize();
+
+ // add interface components:
+ toolbar(services).initialize();
+ mainMenu(services).initialize();
+ keyboard(services).initialize();
+ uploader(services).initialize();
+
+ // main menu > help context menu
+ $('.shortcuts-trigger').bind('click', function () {
+ keyboard(services).openModal();
+ });
+
+ $container.on('keydown', event => {
+ let specialKeyState = {
+ isCancelKey: false,
+ isShortcutKey: false
+ };
+
+ if ($('#MODALDL').is(':visible')) {
+ switch (event.keyCode) {
+ case 27:
+ // hide download
+ hideOverlay(2);
+ $('#MODALDL').css({
+ display: 'none'
+ });
+ break;
+ default:
+ }
+ } else {
+ if ($('#EDITWINDOW').is(':visible')) {
+ // access to editor instead of edit modal
+ specialKeyState = editRecord.onGlobalKeydown(event, specialKeyState);
+ } else if (previewIsOpen) {
+ specialKeyState = previewRecord.onGlobalKeydown(
+ event,
+ specialKeyState
+ );
+ } else if ($('#EDIT_query').hasClass('focused')) {
+ // if return true - nothing to do
+ } else if ($('.overlay').is(':visible')) {
+ // if return true - nothing to do
+ } else if ($('.ui-widget-overlay').is(':visible')) {
+ // if return true - nothing to do
+ } else {
+ switch (getActiveZone()) {
+ case 'rightFrame':
+ specialKeyState = _searchResultKeyDownEvent(
+ event,
+ specialKeyState
+ );
+ break;
+ case 'idFrameC':
+ specialKeyState = _workzoneKeyDownEvent(
+ event,
+ specialKeyState
+ );
+ break;
+ case 'mainMenu':
+ break;
+ case 'headBlock':
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ if (!$('#EDIT_query').hasClass('focused') && event.keyCode !== 17) {
+ if (
+ $('#keyboard-dialog.auto').length > 0 &&
+ specialKeyState.isShortcutKey
+ ) {
+ keyboard(services).openModal();
+ }
+ }
+
+ if (specialKeyState.isCancelKey) {
+ event.cancelBubble = true;
+ if (event.stopPropagation) {
+ event.stopPropagation();
+ }
+ return false;
+ }
+ return true;
+ });
+ };
+
+ // @TODO to be moved
+ const _searchResultKeyDownEvent = (event, specialKeyState) => {
+ switch (event.keyCode) {
+ case 65: // a
+ if (appCommons.utilsModule.is_ctrl_key(event)) {
+ appEvents.emit('search.selection.selectAll');
+ specialKeyState.isCancelKey = specialKeyState.isShortcutKey = true;
+ event.cancelBubble = true;
+ if (event.stopPropagation) {
+ event.stopPropagation();
+ }
+ }
+ break;
+ case 80: // P
+ if (appCommons.utilsModule.is_ctrl_key(event)) {
+ appEvents.emit(
+ 'record.doPrint',
+ 'lst=' + searchSelection.serialized
+ );
+ specialKeyState.isCancelKey = specialKeyState.isShortcutKey = true;
+ }
+ break;
+ case 69: // e
+ if (appCommons.utilsModule.is_ctrl_key(event)) {
+ // eq to: editRecord.doEdit()
+ appEvents.emit('record.doEdit', {
+ type: 'IMGT',
+ value: searchSelection.serialized
+ });
+ specialKeyState.isCancelKey = specialKeyState.isShortcutKey = true;
+ }
+ break;
+ case 40: // down arrow
+ $('#answers').scrollTop($('#answers').scrollTop() + 30);
+ specialKeyState.isCancelKey = specialKeyState.isShortcutKey = true;
+ break;
+ case 38: // down arrow
+ $('#answers').scrollTop($('#answers').scrollTop() - 30);
+ specialKeyState.isCancelKey = specialKeyState.isShortcutKey = true;
+ break;
+ case 37: // previous page
+ $('#PREV_PAGE').trigger('click');
+ specialKeyState.isShortcutKey = true;
+ break;
+ case 39: // previous page
+ $('#NEXT_PAGE').trigger('click');
+ specialKeyState.isShortcutKey = true;
+ break;
+ case 9: // tab
+ if (
+ !appCommons.utilsModule.is_ctrl_key(event) &&
+ !$('.ui-widget-overlay').is(':visible') &&
+ !$('.overlay_box').is(':visible')
+ ) {
+ document.getElementById('EDIT_query').focus();
+ specialKeyState.isCancelKey = specialKeyState.isShortcutKey = true;
+ }
+ break;
+ default:
+ }
+ return specialKeyState;
+ };
+
+ // @TODO to be moved
+ const _workzoneKeyDownEvent = (event, specialKeyState) => {
+ switch (event.keyCode) {
+ case 65: // a
+ if (appCommons.utilsModule.is_ctrl_key(event)) {
+ appEvents.emit('workzone.selection.selectAll');
+ // p4.WorkZone.Selection.selectAll();
+ specialKeyState.isCancelKey = specialKeyState.isShortcutKey = true;
+ }
+ break;
+ case 80: // P
+ if (appCommons.utilsModule.is_ctrl_key(event)) {
+ appEvents.emit(
+ 'record.doPrint',
+ 'lst=' + workzoneSelection.serialized
+ );
+ specialKeyState.isCancelKey = specialKeyState.isShortcutKey = true;
+ }
+ break;
+ case 69: // e
+ if (appCommons.utilsModule.is_ctrl_key(event)) {
+ // eq to: editRecord.doEdit()
+ appEvents.emit('record.doEdit', {
+ type: 'IMGT',
+ value: workzoneSelection.serialized
+ });
+ specialKeyState.isCancelKey = specialKeyState.isShortcutKey = true;
+ }
+ break;
+ // case 46:// del
+ // _deleteRecords(searchSelection.serialized);
+ // specialKeyState.isCancelKey = true;
+ // break;
+ case 40: // down arrow
+ $('#baskets div.bloc').scrollTop(
+ $('#baskets div.bloc').scrollTop() + 30
+ );
+ specialKeyState.isCancelKey = specialKeyState.isShortcutKey = true;
+ break;
+ case 38: // down arrow
+ $('#baskets div.bloc').scrollTop(
+ $('#baskets div.bloc').scrollTop() - 30
+ );
+ specialKeyState.isCancelKey = specialKeyState.isShortcutKey = true;
+ break;
+ case 37:// previous page
+ $('#PREV_PAGE').trigger('click');
+ break;
+ case 39:// previous page
+ $('#NEXT_PAGE').trigger('click');
+ break;
+ case 9: // tab
+ if (
+ !appCommons.utilsModule.is_ctrl_key(event) &&
+ !$('.ui-widget-overlay').is(':visible') &&
+ !$('.overlay_box').is(':visible')
+ ) {
+ document.getElementById('EDIT_query').focus();
+ specialKeyState.isCancelKey = specialKeyState.isShortcutKey = true;
+ }
+ break;
+ default:
+ }
+ return specialKeyState;
+ };
+
+ const hideOverlay = n => {
+ var div = 'OVERLAY';
+ if (typeof n !== 'undefined') {
+ div += n;
+ }
+ $('#' + div).hide().remove();
+ };
+
+ const showModal = (cas, options) => {
+ var content = '';
+ var callback = null;
+ var button = {
+ OK: function (e) {
+ hideOverlay(3);
+ $(this).dialog('close');
+ return;
+ }
+ };
+ var escape = true;
+ var onClose = function () {};
+
+ switch (cas) {
+ case 'timeout':
+ content = localeService.t('serverTimeout');
+ break;
+ case 'error':
+ content = localeService.t('serverError');
+ break;
+ case 'disconnected':
+ content = localeService.t('serverDisconnected');
+ escape = false;
+ callback = function (e) {
+ self.location.replace(self.location.href);
+ };
+ break;
+ default:
+ break;
+ }
+
+ if (typeof Alerts === 'undefined') {
+ alert(localeService.t('serverDisconnected'));
+ self.location.replace(self.location.href);
+ } else {
+ Alerts(options.title, content, callback);
+ }
+ return;
+ };
+
+ const getActiveZone = () => {
+ return activeZone;
+ };
+ const setActiveZone = zoneId => {
+ activeZone = zoneId;
+ return activeZone;
+ };
+
+ const activeZoning = () => {
+ $('#idFrameC, #rightFrame').bind('mousedown', function (event) {
+ var old_zone = getActiveZone();
+ setActiveZone($(this).attr('id'));
+ if (
+ getActiveZone() !== old_zone &&
+ getActiveZone() !== 'headBlock'
+ ) {
+ $('.effectiveZone.activeZone').removeClass('activeZone');
+ $('.effectiveZone', this).addClass('activeZone'); // .flash('#555555');
+ }
+ $('#EDIT_query').blur();
+ });
+ $('#rightFrame').trigger('mousedown');
+ };
+
+ const resizeAll = () => {
+ var body = $('body');
+ window.bodySize.y = body.height();
+ window.bodySize.x = body.width();
+
+ var headBlockH = $('#headBlock').outerHeight();
+ var bodyY = window.bodySize.y - headBlockH - 2;
+ var bodyW = window.bodySize.x - 2;
+ // $('#desktop').height(bodyY).width(bodyW);
+
+ appEvents.emit('preview.doResize');
+
+ if ($('#idFrameC').data('ui-resizable')) {
+ $('#idFrameC').resizable('option', 'maxWidth', 600);
+ $('#idFrameC').resizable('option', 'minWidth', 360);
+ }
+
+ answerSizer();
+ linearizeUi();
+ };
+ const answerSizer = () => {
+ var el = $('#idFrameC').outerWidth();
+ if (!$.support.cssFloat) {
+ // $('#idFrameC .insidebloc').width(el - 56);
+ }
+ var widthA = Math.round(window.bodySize.x - el - 10);
+ $('#rightFrame').width(widthA);
+ $('#rightFrame').css('left', $('#idFrameC').width());
+ };
+ const linearizeUi = () => {
+ const list = $('#answers .list');
+ let fllWidth = $('#answers').innerWidth();
+ let n;
+ if (list.length > 0) {
+ fllWidth -= 16;
+
+ var stdWidth = 567;
+ var diff = 28;
+ n = Math.round(fllWidth / stdWidth);
+ var w = Math.floor(fllWidth / n) - diff;
+ if (w < 567 && n > 1) {
+ w = Math.floor(fllWidth / (n - 1)) - diff;
+ }
+ $('#answers .list').width(w);
+ } else {
+ var minMargin = 5;
+ var el = $('#answers .diapo:first');
+ var diapoWidth = el.outerWidth() + minMargin * 2;
+ fllWidth -= 26;
+
+ n = Math.floor(fllWidth / diapoWidth);
+
+ let margin = Math.floor(fllWidth % diapoWidth / (2 * n));
+ margin = margin + minMargin;
+
+ $('#answers .diapo').css('margin', '5px ' + margin + 'px');
+ var answerIcons = $('#answers .bottom_actions_holder .fa-stack');
+ var answerIconsHolder = $('.bottom_actions_holder');
+ if (el.outerWidth() < 180) {
+ answerIcons.css('width', '20px');
+ answerIcons.css('font-size', '10px');
+ answerIconsHolder.addClass('twenty');
+ }
+
+ if ((el.outerWidth() >= 180) && (el.outerWidth() < 260)) {
+ answerIcons.css('width', '24px');
+ answerIcons.css('font-size', '12px');
+ answerIconsHolder.addClass('twenty-four');
+ }
+
+ if (el.outerWidth() >= 260) {
+ answerIcons.css(
+ 'width', '30px'
+ );
+ answerIcons.css(
+ 'font-size', '15px'
+ );
+ answerIcons.closest('td').css('width', '110px');
+ answerIconsHolder.css('height', '36px');
+ answerIconsHolder.addClass('thirty');
+ }
+ }
+ };
+
+ const saveWindow = () => {
+ var key = '';
+ var value = '';
+
+ if ($('#idFrameE').is(':visible') && $('#EDITWINDOW').is(':visible')) {
+ key = 'edit_window';
+ value = $('#idFrameE').outerWidth() / $('#EDITWINDOW').innerWidth();
+ } else {
+ key = 'search_window';
+ value = $('#idFrameC').outerWidth() / window.bodySize.x;
+ }
+ appCommons.userModule.setPref(key, value);
+ };
+
+ appEvents.listenAll({
+ 'broadcast.searchResultSelection': selection => {
+ searchSelection = selection;
+ },
+ 'broadcast.workzoneResultSelection': selection => {
+ workzoneSelection = selection;
+ },
+ 'ui.resizeAll': resizeAll,
+ 'ui.answerSizer': answerSizer,
+ 'ui.linearizeUi': linearizeUi,
+ 'ui.saveWindow': saveWindow
+ });
+
+ return { initialize, showModal, activeZoning, getActiveZone, resizeAll };
+};
+
+export default ui;
diff --git a/Phraseanet-production-client/src/components/ui/keyboard/index.js b/Phraseanet-production-client/src/components/ui/keyboard/index.js
new file mode 100644
index 0000000000..b232481810
--- /dev/null
+++ b/Phraseanet-production-client/src/components/ui/keyboard/index.js
@@ -0,0 +1,56 @@
+import $ from 'jquery';
+import * as appCommons from './../../../phraseanet-common';
+const keyboard = (services) => {
+ const { configService, localeService, appEvents } = services;
+
+ const initialize = () => {
+
+ };
+
+ const openModal = () => {
+ $('#keyboard-stop').bind('click', function () {
+ var display = $(this).get(0).checked ? '0' : '1';
+
+ appCommons.userModule.setPref('keyboard_infos', display);
+
+ });
+
+ var buttons = {};
+
+ buttons[localeService.t('fermer')] = function () {
+ $('#keyboard-dialog').dialog('close');
+ };
+
+ $('#keyboard-dialog').dialog({
+ closeOnEscape: false,
+ resizable: false,
+ draggable: false,
+ modal: true,
+ width: 600,
+ height: 400,
+ overlay: {
+ backgroundColor: '#000',
+ opacity: 0.7
+ },
+ open: function (event, ui) {
+ $(this).dialog('widget').css('z-index', '1999');
+ },
+ close: function () {
+ $(this).dialog('widget').css('z-index', 'auto');
+ if ($('#keyboard-stop').get(0).checked) {
+ var dialog = $('#keyboard-dialog');
+ if (dialog.data('ui-dialog')) {
+ dialog.dialog('destroy');
+ }
+ dialog.remove();
+ }
+ }
+ }).dialog('option', 'buttons', buttons).dialog('open');
+
+ $('#keyboard-dialog').scrollTop(0);
+ };
+
+ return { initialize, openModal };
+};
+
+export default keyboard;
diff --git a/Phraseanet-production-client/src/components/ui/toolbar/index.js b/Phraseanet-production-client/src/components/ui/toolbar/index.js
new file mode 100644
index 0000000000..e7b6c0ac96
--- /dev/null
+++ b/Phraseanet-production-client/src/components/ui/toolbar/index.js
@@ -0,0 +1,285 @@
+import $ from 'jquery';
+import moveRecords from '../../record/move';
+import editRecord from '../../record/edit';
+import deleteRecord from '../../record/delete';
+import exportRecord from '../../record/export';
+import propertyRecord from '../../record/property';
+import recordPushModal from '../../record/push';
+import recordPublish from '../../record/publish';
+import recordToolsModal from '../../record/tools/index';
+import printRecord from '../../record/print';
+import recordFeedbackModal from '../../record/feedback';
+import bridgeRecord from '../../record/bridge';
+import videoToolsModal from '../../record/videoEditor/index';
+import merge from 'lodash.merge';
+
+const toolbar = (services) => {
+ const {configService, localeService, appEvents} = services;
+ const $container = $('body');
+ let workzoneSelection = [];
+ let searchSelection = [];
+
+ appEvents.listenAll({
+ 'broadcast.searchResultSelection': (selection) => {
+ searchSelection = selection.serialized;
+ },
+ 'broadcast.workzoneResultSelection': (selection) => {
+ workzoneSelection = selection.serialized;
+ }
+ });
+
+ const initialize = () => {
+ _bindEvents();
+
+ return true;
+ };
+
+ /**
+ * Active group can be a Basket or story
+ */
+ const _getGroupSelection = (activeGroupId = null) => {
+ let $activeGroup = $('.SSTT.active');
+ if ($activeGroup.length > 0) {
+ activeGroupId = $activeGroup.attr('id').split('_').slice(1, 2).pop();
+ }
+ return activeGroupId;
+ };
+
+ const _getSelection = (from, originalSelection) => {
+ let newSelection = {
+ list: [],
+ group: null, //
+ type: null // story | basket
+ };
+ switch (from) {
+ case 'search-result':
+ if (searchSelection.length > 0) {
+ newSelection.list = searchSelection;
+ } else {
+ newSelection.group = _getGroupSelection();
+ }
+
+ break;
+ case 'basket':
+ if (workzoneSelection.length > 0) {
+ newSelection.list = workzoneSelection;
+ } else {
+ newSelection.group = _getGroupSelection();
+ newSelection.type = 'basket';
+ }
+ break;
+ case 'story':
+ if (workzoneSelection.length > 0) {
+ newSelection.list = workzoneSelection;
+ } else {
+ newSelection.group = _getGroupSelection();
+ newSelection.type = 'story';
+ }
+ break;
+ default:
+ newSelection.group = _getGroupSelection();
+
+ }
+ //return originalSelection.concat(newSelection);
+ return merge({}, originalSelection, newSelection);
+ };
+
+ const _prepareParams = (selection) => {
+ let params = {};
+
+ if (selection.list.length > 0) {
+ params.lst = selection.list;
+ }
+
+ if (selection.group !== null) {
+ if (selection.type === 'story') {
+ params.story = selection.group;
+ } else {
+ params.ssel = selection.group;
+ }
+ }
+
+ // require a list of records a basket group or a story
+ if (params.lst !== undefined || params.ssel !== undefined || params.story !== undefined) {
+ return params;
+ }
+ return false;
+ };
+
+ const _closeActionPanel = () => {
+ if($('.tools-accordion').hasClass('active')) {
+ $('.rotate').removeClass('down');
+ $('.tools-accordion').removeClass('active');
+ var panel = $('.tools-accordion').next();
+ panel.css('maxHeight', '');
+ }
+ }
+ const _triggerModal = (event, actionFn, nodocselected= true) => {
+ event.preventDefault();
+ const $el = $(event.currentTarget);
+ const selectionSource = $el.data('selection-source');
+
+ let selection = _getSelection(selectionSource, {});
+ let params = _prepareParams(selection);
+
+ // require a list of records a basket group or a story
+ if (params !== false) {
+ return actionFn.apply(null, [params]);
+ } else {
+ if (nodocselected != false) {
+ alert(localeService.t('nodocselected'));
+ }
+ }
+ };
+
+ const _bindEvents = () => {
+
+ /**
+ * tools > selection ALL|NONE|per type
+ */
+ $container.on('click', '.tools .answer_selector', (event) => {
+ event.preventDefault();
+ let $el = $(event.currentTarget);
+ let actionName = $el.data('action-name');
+ let state = $el.data('action-state') === true ? true : false;
+ let type = $el.data('type');
+
+ switch (actionName) {
+ case 'select-toggle':
+ if (state) {
+ appEvents.emit('search.selection.unselectAll');
+ } else {
+ appEvents.emit('search.selection.selectAll');
+ }
+ break;
+ case 'select-all':
+ appEvents.emit('search.selection.selectAll');
+ break;
+ case 'unselect-all':
+ appEvents.emit('search.selection.unselectAll');
+ break;
+ case 'select-type':
+ appEvents.emit('search.selection.selectByType', {type: type});
+ break;
+ default:
+ }
+ $el.data('action-state', !state);
+ });
+
+ /**
+ * tools > Edit > VideoEditor
+ */
+ $container.on('click', '.video-tools-record-action', function (event) {
+ _triggerModal(event, videoToolsModal(services).openModal, false);
+ });
+
+ /**
+ * tools > Edit > Move
+ */
+ $container.on('click', '.TOOL_chgcoll_btn', function (event) {
+ //let moveRecordsInstance = moveRecords(services);
+ _triggerModal(event, moveRecords(services).openModal);
+ });
+
+ /**
+ * tools > Edit > Properties
+ */
+ $container.on('click', '.TOOL_chgstatus_btn', function (event) {
+ _triggerModal(event, propertyRecord(services).openModal);
+ });
+
+ /**
+ * tools > Push
+ */
+ $container.on('click', '.TOOL_pushdoc_btn', function (event) {
+ _triggerModal(event, recordPushModal(services).openModal);
+ });
+ /**
+ * tools > Push > Feedback
+ */
+ $container.on('click', '.TOOL_feedback_btn', function (event) {
+
+ _triggerModal(event, recordFeedbackModal(services).openModal);
+ });
+ /**
+ * tools > Tools
+ */
+ $container.on('click', '.TOOL_imgtools_btn', function (event) {
+ _triggerModal(event, recordToolsModal(services).openModal);
+ });
+ /**
+ * tools > Export
+ */
+ $container.on('click', '.TOOL_disktt_btn', function (event) {
+ // can't be fully refactored
+ _triggerModal(event, exportRecord(services).openModal);
+ });
+ /**
+ * tools > Export > Print
+ */
+ $container.on('click', '.TOOL_print_btn', function (event) {
+ _triggerModal(event, printRecord(services).openModal);
+ });
+ /**
+ * tools > Push > Bridge
+ */
+ $container.on('click', '.TOOL_bridge_btn', function (event) {
+ _triggerModal(event, bridgeRecord(services).openModal);
+ });
+ /**
+ * tools > Push > Publish
+ */
+ $container.on('click', '.TOOL_publish_btn', function (event) {
+ _triggerModal(event, recordPublish(services).openModal);
+ });
+ /**
+ * tools > Delete
+ */
+ $container.on('click', '.TOOL_trash_btn', function (event) {
+ _triggerModal(event, deleteRecord(services).openModal);
+ });
+ /**
+ * tools > Edit
+ */
+ $container.on('click', '.TOOL_ppen_btn', function (event) {
+ _triggerModal(event, editRecord(services).openModal);
+ });
+ /**
+ * tools > Delete Selection
+ */
+ $container.on('click', '.TOOL_delete_selection_btn', function (event) {
+ var $diapoContainer = $(this.closest('.content'));
+ _.each($diapoContainer.find('.diapo.selected'), function(item) {
+ $(item).find('.WorkZoneElementRemover').trigger('click');
+ });
+ });
+
+ /**
+ * tools-accordion function
+ */
+ $container.on('click', '.tools-accordion', function (event) {
+ $('.rotate').toggleClass("down");
+ this.classList.toggle("active");
+
+ /* Toggle between hiding and showing the active panel */
+ var panel = this.nextElementSibling;
+ if (panel.style.maxHeight){
+ panel.style.maxHeight = null;
+ } else {
+ panel.style.maxHeight = panel.scrollHeight + "px";
+ }
+ });
+
+ $container.on('click', function (event) {
+ if ($(event.target).is('button.tools-accordion')) {
+ return;
+ } else {
+ _closeActionPanel();
+ }
+ });
+ };
+
+ return {initialize};
+};
+
+export default toolbar;
diff --git a/Phraseanet-production-client/src/components/ui/workzone/baskets/index.js b/Phraseanet-production-client/src/components/ui/workzone/baskets/index.js
new file mode 100644
index 0000000000..ae0d7e87a5
--- /dev/null
+++ b/Phraseanet-production-client/src/components/ui/workzone/baskets/index.js
@@ -0,0 +1,77 @@
+import $ from 'jquery';
+import deleteBasket from './../../../basket/delete';
+import archiveBasket from './../../../basket/archive';
+import basketCreate from './../../../basket/create';
+import storyCreate from './../../../story/create';
+import basketUpdate from './../../../basket/update';
+import basketBrowse from './../../../basket/browse';
+import basketReorderContent from './../../../basket/reorderContent';
+import storyReorderContent from './../../../story/reorderContent';
+
+const workzoneBaskets = (services) => {
+ const { configService, localeService, appEvents } = services;
+
+
+ const initialize = () => {
+ deleteBasket(services).initialize();
+ archiveBasket(services).initialize();
+ basketCreate(services).initialize();
+ storyCreate(services).initialize();
+ basketUpdate(services).initialize();
+ basketBrowse(services).initialize();
+ basketReorderContent(services).initialize();
+ storyReorderContent(services).initialize();
+
+ $( window ).on( "load", function() {
+ appEvents.emit('workzone.refresh', {
+ basketId: 'current',
+ sort: 'date'
+ });
+ });
+
+ $('body').on('click', '.basket-filter-action', (event) => {
+ event.preventDefault();
+ const $el = $(event.currentTarget);
+ if ($el.data('sort') !== '') {
+ appEvents.emit('workzone.refresh', {
+ basketId: 'current',
+ sort: $el.data('sort')
+ });
+ }
+
+ })
+ .on('click', '.basket-preferences-action', (event) => {
+ event.preventDefault();
+ openBasketPreferences();
+
+ });
+ };
+
+ function openBasketPreferences() {
+ $('#basket_preferences').dialog({
+ closeOnEscape: true,
+ resizable: false,
+ width: 450,
+ height: 500,
+ modal: true,
+ draggable: false,
+ overlay: {
+ backgroundColor: '#000',
+ opacity: 0.7
+ }
+ }).dialog('open');
+ }
+
+ appEvents.listenAll({
+ 'baskets.doOpenBasketPreferences': openBasketPreferences
+ });
+
+
+ return {
+ initialize,
+ openBasketPreferences
+
+ };
+};
+
+export default workzoneBaskets;
diff --git a/Phraseanet-production-client/src/components/ui/workzone/facets/facets.scss b/Phraseanet-production-client/src/components/ui/workzone/facets/facets.scss
new file mode 100644
index 0000000000..d955d12d0f
--- /dev/null
+++ b/Phraseanet-production-client/src/components/ui/workzone/facets/facets.scss
@@ -0,0 +1,2 @@
+@import '../../../../../node_modules/jquery.fancytree/dist/skin-win8/ui.fancytree.css'; // to inline import css file, don't put extension
+
diff --git a/Phraseanet-production-client/src/components/ui/workzone/facets/index.js b/Phraseanet-production-client/src/components/ui/workzone/facets/index.js
new file mode 100644
index 0000000000..5493d90ce6
--- /dev/null
+++ b/Phraseanet-production-client/src/components/ui/workzone/facets/index.js
@@ -0,0 +1,538 @@
+require('./facets.scss');
+
+import $ from 'jquery';
+
+require('jquery-ui');
+require('jquery.fancytree/src/jquery.fancytree');
+import * as _ from 'underscore';
+
+const workzoneFacets = services => {
+ const {configService, localeService, appEvents} = services;
+ let selectedFacets = {};
+ let facets = null;
+
+ const ORDER_BY_BCT = 'ORDER_BY_BCT';
+ const ORDER_ALPHA_ASC = 'ORDER_ALPHA_ASC';
+ const ORDER_ALPHA_DESC = 'ORDER_ALPHA_DESC';
+ const ORDER_BY_HITS = 'ORDER_BY_HITS';
+ const ORDER_BY_HITS_ASC = 'ORDER_BY_HITS_ASC';
+
+ let facetStatus = $.parseJSON(sessionStorage.getItem('facetStatus')) || [];
+ let hiddenFacetsList = [];
+
+
+ var resetSelectedFacets = function () {
+ selectedFacets = {};
+ return selectedFacets;
+ };
+
+ /**
+ * add missing selected facets fields into "facets", from "selectedFacets"
+ * why : because if we negates all values for a facet field (all red), the facet will disapear from next query->answers
+ * (not in "facets" anymore, not in ux). So we lose the posibility to delete or invert a facet value.
+ * nb : negating all facets values does not mean there will be 0 results, because the field can be empty for some records.
+ */
+ function facetsAddMissingSelected(_selectedFacets, _facets) {
+ _.each(_selectedFacets, function (v, k) {
+ var found = _.find(_facets, function (facet) {
+ return (facet.field == k);
+ });
+ if (!found) {
+ var i = _facets.push(_.clone(v)); // add a "fake" facet to facets
+ _facets[i - 1].values = []; // with no values
+ }
+ });
+ };
+
+ var loadFacets = function (data) {
+ hiddenFacetsList = data.hiddenFacetsList;
+
+ function sortIteration(i) {
+ switch (data.facetValueOrder) {
+ case ORDER_ALPHA_ASC:
+ return i.value.toString().toLowerCase();
+ break;
+ case ORDER_BY_HITS_ASC:
+ return i.count ;
+ break;;
+ case ORDER_BY_HITS:
+ return i.count * -1;
+ break;
+ }
+ }
+
+ facetsAddMissingSelected(selectedFacets, data.facets);
+
+ // Convert facets data to fancytree source format
+ var treeSource = _.map(data.facets, function (facet) {
+ // Values
+ var values = _.map(_.sortBy(facet.values, sortIteration), function (value) {
+ var type = facet.type; // todo : define a new phraseanet "color" type for fields. for now we push a "type" for every value, copied from field type
+ // patch "color" type values
+ var textLimit = 15; // cut long values (set to 0 to not cut)
+ var text = (value.value).toString();
+ var label = text;
+ var title = text;
+ var tooltip = text;
+ var match = text.match(/^(.*)\[#([0-9a-fA-F]{6})].*$/);
+ if(match && match[2] != null) {
+ // text looks like a color !
+ var colorCode = '#' + match[2];
+ // add color circle and remove color code from text;
+ var textWithoutColorCode = text.replace('[' + colorCode + ']', '');
+ if (textLimit > 0 && textWithoutColorCode.length > textLimit) {
+ textWithoutColorCode = textWithoutColorCode.substring(0, textLimit) + '…';
+ }
+ // patch
+ type = "COLOR-AGGREGATE";
+ label = textWithoutColorCode;
+ tooltip = _.escape(textWithoutColorCode);
+ title = ' ' + tooltip;
+ }
+ else {
+ // keep text as it is, just cut if too long
+ if (textLimit > 0 && text.length > textLimit) {
+ text = text.substring(0, textLimit) + '…';
+ }
+ label = text;
+ /*title = tooltip = _.escape(text);*/
+ }
+
+ return {
+ // custom data
+ query: value.query,
+ field: facet.field,
+ raw_value: value.raw_value,
+ value: value.value,
+ label: label, // displayed when selected (blue/red), escape is done later (render)
+ type: type, // todo ? define a new phraseanet "color" type for fields. for now we push a "type" for every value
+ count: value.count,
+ // jquerytree data
+ title: title + ' (' + formatNumber(value.count) + ')',
+ tooltip: tooltip + ' (' + formatNumber(value.count) + ')'
+ };
+ });
+ // Facet
+ return {
+ // custom data
+ name: facet.name,
+ field: facet.field,
+ label: facet.label,
+ type: facet.type,
+ // jquerytree data
+ title: facet.label,
+ folder: true,
+ children: values,
+ expanded: !_.some(facetStatus, function(o) { return _.has(o, facet.name)})
+ };
+
+ });
+
+ if (data.facetOrder == ORDER_ALPHA_ASC) {
+ treeSource.sort(
+ _sortFacets('title', true, function (a) {
+ return a.toUpperCase();
+ })
+ );
+
+ }
+
+ if (data.facetOrder == ORDER_ALPHA_DESC) {
+ treeSource.sort(
+ _sortFacets('title', false, function (a) {
+ return a.toUpperCase();
+ })
+ );
+
+ }
+
+ if (data.filterFacet == true) {
+ treeSource = _hideSingleValueFacet(treeSource);
+ }
+
+ if (hiddenFacetsList.length > 0) {
+ treeSource = _shouldMaskNodes(treeSource, hiddenFacetsList);
+ }
+
+ treeSource = _parseColors(treeSource);
+
+ return _getFacetsTree().reload(treeSource)
+ .done(function () {
+ _.each($('#proposals').find('.fancytree-expanded'), function (element, i) {
+ $(element).find('.fancytree-title, .fancytree-expander').css('line-height', '50px');
+ $(element).find('.mask-facets-btn, .fancytree-expander').css('height', '50px');
+
+ var li_s = $(element).next().children('li');
+ var ul = $(element).next();
+ if (li_s.length > 5) {
+ _.each(li_s, function (el, i) {
+ if (i > 4) {
+ $(el).hide();
+ }
+ });
+ ul.append('See more ');
+ }
+ });
+ $('.see_more_btn').on('click', function () {
+ $(this).closest('ul').children().show();
+ $(this).hide();
+ return false;
+ });
+ });
+ };
+
+ function _parseColors(source) {
+ _.forEach(source, function (facet) {
+ if (!_.isUndefined(facet.children) && (facet.children.length > 0)) {
+ _.forEach(facet.children, function (child) {
+ var title = child.title;
+ child.title = _formatColorText(title.toString());
+ });
+ }
+ });
+ return source;
+ }
+
+ function _formatColorText(string, textLimit = 0) {
+ //get color code from text if exist
+ var regexp = /^(.*)\[#([0-9a-fA-F]{6})].*$/;
+
+
+ var match = string.match(regexp);
+ if (match && match[2] != null) {
+ var colorCode = '#' + match[2];
+ // //add color circle and re move color code from text;
+ var textWithoutColorCode = string.replace('[' + colorCode + ']', '');
+ if (textLimit > 0 && textWithoutColorCode.length > textLimit) {
+ textWithoutColorCode = textWithoutColorCode.substring(0, textLimit) + '…';
+ }
+ return ' ' + ' ' + textWithoutColorCode;
+ } else {
+ if (textLimit > 0 && string.length > textLimit) {
+ string = string.substring(0, textLimit) + '…';
+ }
+ return string;
+ }
+ }
+
+
+ // from stackoverflow
+ // http://stackoverflow.com/questions/979256/sorting-an-array-of-javascript-objects/979325#979325
+ function _sortFacets(field, reverse, primer) {
+ var key = function (x) {
+ return primer ? primer(x[field]) : x[field];
+ };
+
+ return function (a, b) {
+ let A = key(a);
+ let B = key(b);
+ return (A < B ? -1 : A > B ? 1 : 0) * [-1, 1][+!!reverse];
+ };
+ }
+
+ function _shouldMaskNodes(source, facetsList) {
+ let filteredSource = source.slice();
+ _.each(facetsList, function (facetsValue, index) {
+ for (let i = filteredSource.length - 1; i > -1; --i) {
+ let facet = filteredSource[i];
+ if (facet['name'] !== undefined) {
+ if (facet['name'] === facetsValue.name) {
+ filteredSource.splice(i, 1);
+ }
+ }
+ }
+ });
+ return filteredSource;
+ }
+
+ /**
+ * hide facets with only one value (experimental)
+ *
+ * @param source treesource
+ * @returns {*}
+ */
+ function _hideSingleValueFacet(source) {
+ var filteredSource = [];
+ _.forEach(source, function (facet) {
+ if (!_.isUndefined(facet.children) && (facet.children.length > 1 || !_.isUndefined(selectedFacets[facet.field]))) {
+ filteredSource.push(facet);
+ }
+ });
+ source = filteredSource;
+
+ return source;
+ }
+
+ function _sortByPredefinedFacets(source, field, predefinedFieldOrder) {
+ let filteredSource = source.slice();
+ let ordered = [];
+
+ _.each(predefinedFieldOrder, function (fieldValue, index) {
+ for (let i = filteredSource.length - 1; i > -1; --i) {
+ let facet = filteredSource[i];
+ if (facet[field] !== undefined) {
+ if (facet[field] === fieldValue) {
+ ordered.push(facet);
+ // remove from filtered
+ filteredSource.splice(i, 1);
+ }
+ }
+ }
+ });
+
+ const olen = filteredSource.length;
+ // fill predefined facets with non predefined facets
+ for (let i = 0; i < olen; i++) {
+ ordered.push(filteredSource[i]);
+ }
+ return ordered;
+ }
+ /*Format number to local fr */
+ function formatNumber(number) {
+ var locale = 'fr';
+ var formatter = new Intl.NumberFormat(locale);
+ return formatter.format(number);
+ }
+
+ function _getFacetsTree() {
+ var $facetsTree = $('#proposals');
+ if (!$facetsTree.data('ui-fancytree')) {
+ $facetsTree.fancytree({
+ clickFolderMode: 2, // expand
+ icons: false,
+ source: [],
+ activate: function (event, data) {
+ var eventType = event.originalEvent;
+ //if user did not click, then no need to perform any query
+ if (eventType == null) {
+ return;
+ }
+ var facet = data.node.parent;
+ var facetData = {
+ value: data.node.data,
+ enabled: true,
+ negated: event.altKey // ,
+ // mode: event.altKey ? "EXCEPT" : "AND"
+ };
+
+ if (selectedFacets[facet.data.field] == null) {
+ selectedFacets[facet.data.field] = facet.data;
+ selectedFacets[facet.data.field].values = [];
+ }
+ selectedFacets[facet.data.field].values.push(facetData);
+ appEvents.emit('search.doRefreshState');
+ },
+ collapse: function (event, data) {
+ var dict = {};
+ dict[data.node.data.name] = "collapse";
+ if (_.findWhere(facetStatus, dict) !== undefined) {
+ facetStatus = _.without(facetStatus, _.findWhere(facetStatus, dict))
+ }
+ facetStatus.push(dict);
+ sessionStorage.setItem('facetStatus', JSON.stringify(facetStatus));
+ },
+ expand: function (event, data) {
+ var dict = {};
+ dict[data.node.data.name] = "collapse";
+ if (_.findWhere(facetStatus, dict) !== undefined) {
+ facetStatus = _.without(facetStatus, _.findWhere(facetStatus, dict))
+ }
+ sessionStorage.setItem('facetStatus', JSON.stringify(facetStatus));
+ },
+ renderNode: function (event, data) {
+ var facetFilter = "";
+ var node = data.node;
+ var $nodeSpan = $(node.span);
+
+ // check if span of node already rendered
+ if (!$nodeSpan.data('rendered')) {
+ var deleteButton = $('');
+ $nodeSpan.append(deleteButton);
+ deleteButton.hide();
+
+ $nodeSpan.hover(function () {
+ /*Dont show deleteButton if there is selected facet*/
+ if ($('.fancytree-folder', data.node.li).find('[class^="facetFilter_"]').length === 0) {
+ deleteButton.show();
+ }
+ }, function () {
+ deleteButton.hide();
+ });
+
+ deleteButton.click(function () {
+ var nodeObj = {name: node.data.name, title: node.title};
+ hiddenFacetsList.push(nodeObj);
+ node.remove();
+ appEvents.emit('searchAdvancedForm.saveHiddenFacetsList', hiddenFacetsList);
+ appEvents.emit('search.reloadHiddenFacetList', hiddenFacetsList);
+ });
+
+ // span rendered
+ $nodeSpan.data('rendered', true);
+
+ if (data.node.folder) {
+ // here we render a "fieldname" level
+ if (!_.isUndefined(selectedFacets[data.node.data.field])) {
+ // here the field already contains selected facetvalues (to be rendered blue or red)
+ if ($('.fancytree-folder', data.node.li).find('.dataNode').length == 0) {
+ var dataNode = document.createElement('div');
+ dataNode.setAttribute('class', 'dataNode');
+ $('.fancytree-folder', data.node.li).append(dataNode);
+ }
+ else {
+ //remove existing facets
+ $('.dataNode', data.node.li).empty();
+ }
+
+ _.each(selectedFacets[data.node.data.field].values, function (facetValue) {
+ var label = facetValue.value.label;
+ var facetFilter = facetValue.value.label;
+ var facetTitle = facetValue.value.value + ' ('+formatNumber(facetValue.value.count)+')';
+
+ var s_label = document.createElement('SPAN');
+ s_label.setAttribute('class', 'facetFilter-label');
+ s_label.setAttribute('title', facetTitle );
+
+
+ var f_except = $('#facet_except').val();
+ var f_and = $('#facet_and').val();
+ var f_close = $('#facet_remove').val();
+ var selected_facet_tooltip = (facetValue.negated ? f_and : f_except) + ' : ' + facetTitle;
+ var remove_facet_tooltip = f_close + ' : ' + facetTitle;
+
+
+ var length = 15;
+ var facetFilterString = _formatColorText(facetFilter.toString(), length);
+
+ _.each($.parseHTML(facetFilterString), function (elem) {
+ s_label.appendChild(elem);
+ });
+
+ var buttonsSpan = document.createElement('SPAN');
+ buttonsSpan.setAttribute('class', 'buttons-span');
+
+ var s_inverse = document.createElement('A');
+ s_inverse.setAttribute('class', 'facetFilter-inverse');
+ s_inverse.setAttribute('title', selected_facet_tooltip);
+
+ var s_closer = document.createElement('A');
+ s_closer.setAttribute('class', 'facetFilter-closer');
+ s_closer.setAttribute('title', remove_facet_tooltip);
+
+ var s_gradient = document.createElement('SPAN');
+ s_gradient.setAttribute('class', 'facetFilter-gradient');
+ s_gradient.appendChild(document.createTextNode('\u00A0'));
+
+ s_label.appendChild(s_gradient);
+
+ var s_facet = document.createElement('SPAN');
+ var s_class = 'facetFilter' + '_' + (facetValue.negated ? 'EXCEPT' : 'AND');
+ s_facet.setAttribute('class', s_class);
+ s_facet.removeAttribute('title');
+ s_facet.appendChild(s_label);
+ s_facet.appendChild(buttonsSpan);
+
+ buttonsSpan.appendChild(s_inverse);
+ buttonsSpan.appendChild(s_closer);
+
+ $(s_closer).on('click',
+ function (event) {
+ event.stopPropagation();
+ var $facet = $(this).parent().parent();
+ var facetField = $facet.data('facetField');
+ var facetLabel = $facet.data('facetLabel');
+ var facetNegated = $facet.data('facetNegated');
+ selectedFacets[facetField].values = _.reject(selectedFacets[facetField].values, function (facetValue) {
+ return (facetValue.value.label == facetLabel && facetValue.negated == facetNegated);
+ });
+
+ appEvents.emit('search.doRefreshState');
+ return false;
+ }
+ );
+
+ $(s_inverse).on('click',
+ function (event) {
+ event.stopPropagation();
+ var $facet = $(this).parent().parent();
+ var facetField = $facet.data('facetField');
+ var facetLabel = $facet.data('facetLabel');
+ var facetNegated = $facet.data('facetNegated');
+ var found = _.find(selectedFacets[facetField].values, function (facetValue) {
+ return (facetValue.value.label == facetLabel && facetValue.negated == facetNegated);
+ });
+ if (found) {
+ var s_class = "facetFilter" + '_' + (found.negated ? "EXCEPT" : "AND");
+ $facet.removeClass(s_class);
+ found.negated = !found.negated;
+ s_class = "facetFilter" + '_' + (found.negated ? "EXCEPT" : "AND");
+ $facet.addClass(s_class);
+
+ appEvents.emit('search.doRefreshState');
+
+ }
+ return false;
+ }
+ );
+
+ var newNode = document.createElement('div');
+ newNode.setAttribute('class', 'newNode');
+ s_facet = $(newNode.appendChild(s_facet));
+ s_facet.data('facetField', data.node.data.field);
+ s_facet.data('facetLabel', label);
+ s_facet.data('facetNegated', facetValue.negated);
+
+ /*add selected facet tooltip*/
+ // s_facet.attr('title', facetValue.value.value);
+
+ s_facet.hover(function () {
+ $(buttonsSpan).show();
+
+
+ }, function () {
+ $(buttonsSpan).hide();
+ });
+
+ $('.fancytree-folder .dataNode', data.node.li).append(newNode);
+
+ });
+ }
+ }
+ else {
+ // here we render a facet value
+ }
+ }
+ }
+ });
+ }
+ return $facetsTree.fancytree('getTree');
+ }
+
+ var setSelectedFacets = function setSelectedFacets(facets) {
+ if(!_.isObject(facets) || facets.length === 0) {
+ facets = {};
+ }
+ selectedFacets = facets;
+ }
+
+ var getSelectedFacets = function getSelectedFacets(cb) {
+ cb(selectedFacets);
+ }
+
+ appEvents.listenAll({
+ 'facets.doLoadFacets': loadFacets,
+ 'facets.doResetSelectedFacets': resetSelectedFacets,
+ 'facets.doAddMissingSelectedFacets': facetsAddMissingSelected,
+ 'facets.setSelectedFacets': setSelectedFacets,
+ 'facets.getSelectedFacets': getSelectedFacets,
+ });
+
+ return {
+ loadFacets: loadFacets,
+ getSelectedFacets: getSelectedFacets,
+ resetSelectedFacets: resetSelectedFacets,
+ setSelectedFacets: setSelectedFacets,
+ };
+};
+
+export default workzoneFacets;
diff --git a/Phraseanet-production-client/src/components/ui/workzone/index.js b/Phraseanet-production-client/src/components/ui/workzone/index.js
new file mode 100644
index 0000000000..9b9cad85d9
--- /dev/null
+++ b/Phraseanet-production-client/src/components/ui/workzone/index.js
@@ -0,0 +1,843 @@
+import $ from 'jquery';
+import * as appCommons from './../../../phraseanet-common';
+import workzoneThesaurus from './thesaurus/index';
+import workzoneFacets from './facets/index';
+import workzoneBaskets from './baskets/index';
+import Selectable from '../../utils/selectable';
+import Alerts from '../../utils/alert';
+const humane = require('humane-js');
+require('./../../../phraseanet-common/components/tooltip');
+require('./../../../phraseanet-common/components/vendors/contextMenu');
+
+const workzone = (services) => {
+ const {configService, localeService, appEvents} = services;
+ const url = configService.get('baseUrl');
+ let workzoneOptions = {};
+ let searchSelection = {asArray: [], serialized: ''};
+ workzoneFacets(services);
+ workzoneBaskets(services).initialize();
+ workzoneThesaurus(services).initialize();
+
+
+ var nextBasketScroll = false;
+ var warnOnRemove = true;
+ let $container;
+
+ const initialize = () => {
+ $container = $('#idFrameC');
+
+ $container.resizable({
+ handles: 'e',
+ resize: function () {
+ appEvents.emit('ui.answerSizer');
+ appEvents.emit('ui.linearizeUi');
+ },
+ stop: function () {
+
+ var el = $('.SSTT.active').next();
+ var w = el.find('div.chim-wrapper:first').outerWidth();
+ var iw = el.innerWidth();
+ var diff = $container.width() - el.outerWidth();
+ var n = Math.floor(iw / w);
+
+ $container.height('auto');
+
+ var nwidth = n * w + diff + n + 10;
+ if (isNaN(nwidth)) {
+ appEvents.emit('ui.saveWindow');
+ return;
+ }
+ if (nwidth < 247) {
+ nwidth = 247;
+ }
+ if (el.find('div.chim-wrapper:first').hasClass('valid') && nwidth < 410) {
+ nwidth = 410;
+ }
+
+
+ $container.stop().animate({
+ width: nwidth
+ },
+ 300,
+ 'linear',
+ function () {
+ appEvents.emit('ui.answerSizer');
+ appEvents.emit('ui.linearizeUi');
+ appEvents.emit('ui.saveWindow');
+ });
+ }
+ });
+
+ $('#idFrameC .ui-tabs-nav li').on('click', function (event) {
+ if ($container.attr('data-status') === 'closed') {
+ $('#retractableButton').find('i').removeClass('fa-angle-double-right').addClass('fa-angle-double-left');
+ $container.width(360);
+ $('#rightFrame').css('left', 360);
+ $('#rightFrame').width($(window).width() - 360);
+ $('#baskets, #proposals, #thesaurus_tab').hide();
+ $('.ui-resizable-handle, #basket_menu_trigger').show();
+ var IDname = $(this).attr('aria-controls');
+ $('#' + IDname).show();
+ }
+
+ $container.attr('data-status', 'open');
+ $('.WZbasketTab').css('background-position', '9px 21px');
+ $container.removeClass('closed');
+ });
+
+ var previousTab = '';
+
+ $('#idFrameC #retractableButton').bind('click', function (event) {
+
+ if ($container.attr('data-status') !== 'closed') {
+ $(this).find('i').removeClass('fa-angle-double-left').addClass('fa-angle-double-right');
+ $container.width(80);
+ $('#rightFrame').css('left', 80);
+ $('#rightFrame').width($(window).width() - 80);
+ $container.attr('data-status', 'closed');
+ $('#baskets, #proposals, #thesaurus_tab, .ui-resizable-handle, #basket_menu_trigger').hide();
+ $('#idFrameC .ui-tabs-nav li').removeClass('ui-state-active');
+ $('.WZbasketTab').css('background-position', '15px 16px');
+ $container.addClass('closed');
+ previousTab = $('#idFrameC .prod-icon-menu').find('li.ui-tabs-active');
+ } else {
+ $(this).find('i').removeClass('fa-angle-double-right').addClass('fa-angle-double-left');
+ $container.width(360);
+ $('#rightFrame').css('left', 360);
+ $('#rightFrame').width($(window).width() - 360);
+ $container.attr('data-status', 'open');
+ $('.ui-resizable-handle, #basket_menu_trigger').show();
+ $('.WZbasketTab').css('background-position', '9px 16px');
+ $container.removeClass('closed');
+ $('#idFrameC .prod-icon-menu li').last().find('a').trigger('click');
+ $('#idFrameC .prod-icon-menu li').first().find('a').trigger('click');
+ $(previousTab).find('a').trigger('click');
+ }
+
+ event.stopImmediatePropagation();
+ // workzoneOptions.close();
+ return false;
+ });
+
+ $('#basket_menu_trigger').contextMenu('#basket_menu', {
+ openEvt: 'click',
+ dropDown: true,
+ theme: 'vista',
+ showTransition: 'slideDown',
+ hideTransition: 'hide',
+ shadow: false
+ });
+
+
+ $('#basket_menu_trigger').trigger('click');
+ $('#basket_menu_trigger').trigger('click');
+
+ $('.basketTips').tooltip({
+ delay: 200,
+ extraClass: 'tooltip_flat'
+ });
+
+ $('.basket_title').tooltip({
+ extraClass: 'tooltip_flat'
+ });
+
+ $('#idFrameC .tabs').tabs({
+ activate: function (event, ui) {
+ if (ui.newTab.context.hash === '#thesaurus_tab') {
+ appEvents.emit('thesaurus.show');
+ }
+ workzoneOptions.open();
+ }
+ });
+ $('.basket_refresher').on('click', function () {
+ return workzoneOptions.refresh('current');
+ });
+ activeBaskets();
+
+ $('body').on('click', 'a.story_unfix', (event) => {
+ event.preventDefault();
+ let $el = $(event.currentTarget);
+ unfix($el.attr('href'));
+
+ return false;
+ });
+
+ workzoneOptions = {
+ selection: new Selectable(services, $('#baskets'), {selector: '.CHIM'}),
+ refresh: refreshBaskets,
+ addElementToBasket: function (options) {
+ let {sbas_id, record_id, event, singleSelection} = options;
+ singleSelection = !!singleSelection || false;
+
+ if ($('#baskets .SSTT.active').length === 1) {
+ return dropOnBask(event, $('#IMGT_' + sbas_id + '_' + record_id), $('#baskets .SSTT.active'), singleSelection);
+ } else {
+ humane.info(localeService.t('noActiveBasket'));
+ }
+ },
+ removeElementFromBasket: WorkZoneElementRemover,
+ reloadCurrent: function () {
+ var sstt = $('#baskets .content:visible');
+ if (sstt.length > 0) {
+ getContent(sstt.prev());
+ }
+ },
+ close: function () {
+ const frame = $container;
+ const that = this;
+
+ if (!frame.hasClass('closed')) {
+ // hide tabs content
+ $('#idFrameC .tabs > .ui-tabs-panel').hide();
+
+ frame.data('openwidth', frame.width());
+ frame.animate({width: 100},
+ 300,
+ 'linear',
+ function () {
+ appEvents.emit('ui.answerSizer');
+ appEvents.emit('ui.linearizeUi');
+ $('#answers').trigger('resize');
+ });
+ frame.addClass('closed');
+ $('.escamote', frame).hide();
+ frame.unbind('click.escamote').bind('click.escamote', function () {
+ that.open();
+ });
+ }
+ },
+ open: function () {
+ var frame = $container;
+
+ if (frame.hasClass('closed')) {
+ var width = frame.data('openwidth') ? frame.data('openwidth') : 300;
+ frame.css({width: width});
+ appEvents.emit('ui.answerSizer');
+ appEvents.emit('ui.linearizeUi');
+ frame.removeClass('closed');
+ $('.escamote', frame).show();
+ frame.unbind('click.escamote');
+ // show tabs content
+ var activeTabIdx = $('#idFrameC .tabs').tabs('option', 'active');
+ $('#idFrameC .tabs > div:eq(' + activeTabIdx + ')').show();
+ }
+ }
+ };
+ filterBaskets();
+
+ };
+
+ const getResultSelectionStream = () => workzoneOptions.selection.stream;
+
+ /*left filter basket*/
+ function filterBaskets() {
+ $('#feedback-list input').click(function () {
+ $('.feedbacks-block').toggleClass('hidden');
+ });
+ $('#push-list input').click(function () {
+ $('.pushes-block').toggleClass('hidden');
+ });
+ $('#basket-list input').click(function () {
+ $('.baskets-block').toggleClass('hidden');
+ });
+ $('#story-list input').click(function () {
+ $('.stories-block').toggleClass('hidden');
+ });
+ }
+
+ function refreshBaskets(options) {
+ let {basketId = false, sort, scrolltobottom, type} = options || {};
+ type = typeof type === 'undefined' ? 'basket' : type;
+
+ var active = $('#baskets .SSTT.ui-state-active');
+ if (basketId === 'current' && active.length > 0) {
+ basketId = active.attr('id').split('_').slice(1, 2).pop();
+ }
+ sort = ($.inArray(sort, ['date', 'name']) >= 0) ? sort : '';
+
+ scrolltobottom = typeof scrolltobottom === 'undefined' ? false : scrolltobottom;
+
+ $.ajax({
+ type: 'GET',
+ url: `${url}prod/WorkZone/`,
+ data: {
+ id: basketId,
+ sort: sort,
+ type: type
+ },
+ beforeSend: function () {
+ $('#basketcontextwrap').remove();
+ },
+ success: function (data) {
+ var cache = $('#idFrameC #baskets');
+
+ if ($('.SSTT', cache).data('ui-droppable')) {
+ $('.SSTT', cache).droppable('destroy');
+ }
+ if ($('.bloc', cache).data('ui-droppable')) {
+ $('.bloc', cache).droppable('destroy');
+ }
+ if (cache.data('ui-accordion')) {
+ cache.accordion('destroy').empty().append(data);
+ }
+
+ activeBaskets();
+ filterBaskets();
+ $('.basketTips').tooltip({
+ delay: 200
+ });
+ cache.disableSelection();
+
+ if (!scrolltobottom) {
+ return;
+ }
+
+ nextBasketScroll = true;
+ return;
+ }
+ });
+ }
+
+ function setTemporaryPref(name, value) {
+ $.ajax({
+ type: 'POST',
+ url: '/user/preferences/temporary/',
+ data: {
+ prop: name,
+ value: value
+ },
+ success: function (data) {
+ return;
+ }
+ });
+ }
+
+ $('#baskets div.content select[name=valid_ord]').on('change', function () {
+ var active = $('#baskets .SSTT.ui-state-active');
+ if (active.length === 0) {
+ return;
+ }
+
+ var order = $(this).val();
+
+ getContent(active, order);
+ });
+
+ function WorkZoneElementRemover(el, confirm) {
+ var context = el.data('context');
+
+ if (confirm !== true && $(el).hasClass('groupings') && warnOnRemove) {
+ var buttons = {};
+
+ buttons[localeService.t('valider')] = function () {
+ $('#DIALOG-baskets').dialog('close').remove();
+ WorkZoneElementRemover(el, true);
+ };
+
+ buttons[localeService.t('annuler')] = function () {
+ $('#DIALOG-baskets').dialog('close').remove();
+ };
+
+ var texte = '' + localeService.t('confirmRemoveReg') + '
' + localeService.t('hideMessage') + '
';
+ $('body').append('
');
+ $('#DIALOG-baskets').attr('title', localeService.t('removeTitle'))
+ .empty()
+ .append(texte)
+ .dialog({
+ autoOpen: false,
+ closeOnEscape: true,
+ resizable: false,
+ draggable: false,
+ modal: true,
+ buttons: buttons,
+ overlay: {
+ backgroundColor: '#000',
+ opacity: 0.7
+ }
+ }).dialog('open');
+ return false;
+ } else {
+
+ let id = $(el).attr('id').split('_').slice(2, 4).join('_');
+
+ return $.ajax({
+ type: 'POST',
+ url: $(el).attr('href'),
+ dataType: 'json',
+ beforeSend: function () {
+ $('.wrapCHIM_' + id).find('.CHIM').fadeOut();
+ },
+ success: function (data) {
+ if (data.success) {
+ humane.info(data.message);
+ workzoneOptions.selection.remove(id);
+
+ if ($('.wrapCHIM_' + id).find('.CHIM').data('ui-draggable')) {
+ $('.wrapCHIM_' + id).find('.CHIM').draggable('destroy');
+ }
+
+ $('.wrapCHIM_' + id).remove();
+
+ if (context === 'reg_train_basket') {
+ var carousel = $('#PREVIEWCURRENTCONT');
+ var carouselItemLength = $('li', carousel).length;
+ var selectedItem = $('li.prevTrainCurrent.selected', carousel);
+ var selectedItemIndex = $('li', carousel).index(selectedItem);
+
+ // item is first and list has at least 2 items
+ if (selectedItemIndex === 0 && carouselItemLength > 1) {
+ // click next item
+ selectedItem.next().find('img').trigger('click');
+ // item is last item and list has at least 2 items
+ } else if (carouselItemLength > 1 && selectedItemIndex === (carouselItemLength - 1)) {
+ // click previous item
+ selectedItem.prev().find('img').trigger('click');
+ // Basket is empty
+ } else if (carouselItemLength > 1) {
+ // click next item
+ selectedItem.next().find('img').trigger('click');
+ } else {
+ appEvents.emit('preview.close');
+ }
+
+ selectedItem.remove();
+ } else {
+ return workzoneOptions.reloadCurrent();
+ }
+ } else {
+ humane.error(data.message);
+ $('.wrapCHIM_' + id).find('.CHIM').fadeIn();
+ }
+ }
+ });
+ }
+
+ }
+
+
+ function activeBaskets() {
+ var cache = $('#idFrameC #baskets');
+
+ cache.accordion({
+ active: 'active',
+ heightStyle: 'content',
+ collapsible: true,
+ header: 'div.header',
+ activate: function (event, ui) {
+ var b_active = $('#baskets .SSTT.active');
+ if (nextBasketScroll) {
+ nextBasketScroll = false;
+
+ if (!b_active.next().is(':visible')) {
+ return;
+ }
+
+ var t = $('#baskets .SSTT.active').position().top + b_active.next().height() - 200;
+
+ t = t < 0 ? 0 : t;
+
+ $('#baskets .bloc').stop().animate({
+ scrollTop: t
+ });
+ }
+
+ var uiactive = $(this).find('.ui-state-active');
+ b_active.not('.ui-state-active').removeClass('active');
+
+ if (uiactive.length === 0) {
+ return;
+ /* everything is closed */
+ }
+
+ uiactive.addClass('ui-state-focus active');
+
+ workzoneOptions.selection.empty();
+
+ getContent(uiactive);
+
+ },
+ beforeActivate: function (event, ui) {
+ ui.newHeader.addClass('active');
+ $('#basketcontextwrap .basketcontextmenu').hide();
+ }
+ });
+
+ $('.bloc', cache).droppable({
+ accept: function (elem) {
+ if ($(elem).hasClass('grouping') && !$(elem).hasClass('SSTT')) {
+ return true;
+ }
+ return false;
+ },
+ scope: 'objects',
+ hoverClass: 'groupDrop',
+ tolerance: 'pointer',
+ drop: function () {
+ fix();
+ }
+ });
+
+ if ($('.SSTT.active', cache).length > 0) {
+ var el = $('.SSTT.active', cache)[0];
+ $(el).trigger('click');
+ }
+
+ $('.SSTT, .content', cache)
+ .droppable({
+ scope: 'objects',
+ hoverClass: 'baskDrop',
+ tolerance: 'pointer',
+ accept: function (elem) {
+ if ($(elem).hasClass('CHIM')) {
+ if ($(elem).closest('.content').prev()[0] === $(this)[0]) {
+ return false;
+ }
+ }
+ if ($(elem).hasClass('grouping') || $(elem).parent()[0] === $(this)[0]) {
+ return false;
+ }
+ return true;
+ },
+ drop: function (event, ui) {
+ dropOnBask(event, ui.draggable, $(this));
+ }
+ });
+
+ if ($('#basketcontextwrap').length === 0) {
+ $('body').append('
');
+ }
+
+ $('.context-menu-item', cache).hover(function () {
+ $(this).addClass('context-menu-item-hover');
+ }, function () {
+ $(this).removeClass('context-menu-item-hover');
+ });
+ $.each($('.SSTT', cache), function () {
+ var el = $(this);
+ $(this).find('.contextMenuTrigger').contextMenu('#' + $(this).attr('id') + ' .contextMenu', {
+ appendTo: '#basketcontextwrap',
+ openEvt: 'click',
+ theme: 'vista',
+ dropDown: true,
+ showTransition: 'slideDown',
+ hideTransition: 'hide',
+ shadow: false
+ });
+ });
+
+ }
+
+ function getContent(header, order) {
+ if (window.console) {
+ console.log('Reload content for ', header);
+ }
+
+ var url = $('a', header).attr('href');
+
+ if (typeof order !== 'undefined') {
+ url += '?order=' + order;
+ }
+
+ $.ajax({
+ type: 'GET',
+ url: url,
+ dataType: 'html',
+ beforeSend: function () {
+ $('#tooltip').hide();
+ header.next().addClass('loading');
+ },
+ success: function (data) {
+ header.removeClass('unread');
+
+ var dest = header.next();
+ if (dest.data('ui-droppable')) {
+ dest.droppable('destroy');
+ }
+ dest.empty().removeClass('loading');
+
+ dest.append(data);
+
+ $('a.WorkZoneElementRemover', dest).bind('mousedown', function (event) {
+ return false;
+ }).bind('click', function (event) {
+ return WorkZoneElementRemover($(this), false);
+ });
+
+ $("#baskets div.content select[name=valid_ord]").on('change', function () {
+ var active = $('#baskets .SSTT.ui-state-active');
+ if (active.length === 0) {
+ return;
+ }
+
+ var order = $(this).val();
+
+ getContent(active, order);
+ });
+
+ dest.droppable({
+ accept: function (elem) {
+ if ($(elem).hasClass('CHIM')) {
+ if ($(elem).closest('.content')[0] === $(this)[0]) {
+ return false;
+ }
+ }
+ if ($(elem).hasClass('grouping') || $(elem).parent()[0] === $(this)[0]) {
+ return false;
+ }
+ return true;
+ },
+ hoverClass: 'baskDrop',
+ scope: 'objects',
+ drop: function (event, ui) {
+ dropOnBask(event, ui.draggable, $(this).prev());
+ },
+ tolerance: 'pointer'
+ });
+
+ $('.noteTips, .captionRolloverTips', dest).tooltip({
+ extraClass: 'tooltip_flat'
+ });
+
+ dest.find('.CHIM').draggable({
+ helper: function () {
+ $('body').append('' +
+ '
' +
+ workzoneOptions.selection.length() + '
');
+ return $('#dragDropCursor');
+ },
+ scope: 'objects',
+ distance: 20,
+ scroll: false,
+ refreshPositions: true,
+ cursorAt: {
+ top: 10,
+ left: -20
+ },
+ start: function (event, ui) {
+ var baskets = $('#baskets');
+ baskets.append('
' +
+ '
');
+ $('.bottom-scroller', baskets).bind('mousemove', function () {
+ $('#baskets .bloc').scrollTop($('#baskets .bloc').scrollTop() + 30);
+ });
+ $('.top-scroller', baskets).bind('mousemove', function () {
+ $('#baskets .bloc').scrollTop($('#baskets .bloc').scrollTop() - 30);
+ });
+ },
+ stop: function () {
+ $('#baskets').find('.top-scroller, .bottom-scroller')
+ .unbind()
+ .remove();
+ },
+ drag: function (event, ui) {
+ if (appCommons.utilsModule.is_ctrl_key(event) || $(this).closest('.content').hasClass('grouping')) {
+ $('#dragDropCursor div').empty().append('+ ' + workzoneOptions.selection.length());
+ } else {
+ $('#dragDropCursor div').empty().append(workzoneOptions.selection.length());
+ }
+
+ }
+ });
+ window.workzoneOptions = workzoneOptions;
+ appEvents.emit('ui.answerSizer');
+ return;
+ }
+ });
+ }
+
+ function dropOnBask(event, from, destKey, singleSelection) {
+ let action = '';
+ let dest_uri = '';
+ let lstbr = [];
+ let sselcont = [];
+ let act = 'ADD';
+ from = $(from);
+
+ if (from.hasClass('CHIM')) {
+ /* Element(s) come from an open object in the workzone */
+ action = $(' #baskets .ui-state-active').hasClass('grouping') ? 'REG2' : 'CHU2';
+ } else {
+ /* Element(s) come from result */
+ action = 'IMGT2';
+ }
+
+ action += destKey.hasClass('grouping') ? 'REG' : 'CHU';
+
+ if (destKey.hasClass('content')) {
+ /* I dropped on content */
+ dest_uri = $('a', destKey.prev()).attr('href');
+ } else {
+ /* I dropped on Title */
+ dest_uri = $('a', destKey).attr('href');
+ }
+
+ if (window.console) {
+ window.console.log('Requested action is ', action, ' and act on ', dest_uri);
+ }
+
+ if (action === 'IMGT2CHU' || action === 'IMGT2REG') {
+ if ($(from).hasClass('.baskAdder')) {
+ lstbr = [$(from).attr('id').split('_').slice(2, 4).join('_')];
+ } else if (singleSelection) {
+ if (from.length === 1) {
+ lstbr = [$(from).attr('id').split('_').slice(1, 3).join('_')];
+ } else {
+ lstbr = [$(from).selector.split('_').slice(1, 3).join('_')];
+ }
+ } else {
+ lstbr = searchSelection.asArray;
+ }
+ } else {
+ sselcont = $.map(workzoneOptions.selection.get(), function (n, i) {
+ return $('.CHIM_' + n, $('#baskets .content:visible')).attr('id').split('_').slice(1, 2).pop();
+ });
+ lstbr = workzoneOptions.selection.get();
+ }
+
+ switch (action) {
+ case 'CHU2CHU' :
+ if (!appCommons.utilsModule.is_ctrl_key(event)) act = 'MOV';
+ break;
+ case 'IMGT2REG':
+ case 'CHU2REG' :
+ case 'REG2REG':
+ let sameSbas = true;
+ const sbas_reg = destKey.attr('sbas');
+
+ for (let i = 0; i < lstbr.length && sameSbas; i++) {
+ if (lstbr[i].split('_').shift() !== sbas_reg) {
+ sameSbas = false;
+ break;
+ }
+ }
+
+ if (sameSbas === false) {
+ return Alerts('', localeService.t('reg_wrong_sbas'));
+ }
+
+ break;
+ default:
+ }
+ let url = '';
+ let data = {};
+ switch (act + action) {
+ case 'MOVCHU2CHU':
+ url = dest_uri + 'stealElements/';
+ data = {
+ elements: sselcont
+ };
+ break;
+ case 'ADDCHU2REG':
+ case 'ADDREG2REG':
+ case 'ADDIMGT2REG':
+ case 'ADDCHU2CHU':
+ case 'ADDREG2CHU':
+ case 'ADDIMGT2CHU':
+ url = dest_uri + 'addElements/';
+ data = {
+ lst: lstbr.join(';')
+ };
+ break;
+ default:
+ if (window.console) {
+ console.log('Should not happen');
+ }
+ return false;
+ }
+
+ if (window.console) {
+ window.console.log('About to execute ajax POST on ', url, ' with datas ', data);
+ }
+
+ $.ajax({
+ type: 'POST',
+ url: url,
+ data: data,
+ dataType: 'json',
+ beforeSend: function () {
+
+ },
+ success: function (data) {
+ if (!data.success) {
+ humane.error(data.message);
+ } else {
+ humane.info(data.message);
+ }
+ if (act === 'MOV' || $(destKey).next().is(':visible') === true || $(destKey).hasClass('content') === true) {
+ $('.CHIM.selected:visible').fadeOut();
+ workzoneOptions.selection.empty();
+ return workzoneOptions.reloadCurrent();
+ }
+
+ return true;
+ }
+ });
+ }
+
+ function fix() {
+ $.ajax({
+ type: 'POST',
+ url: `${url}prod/WorkZone/attachStories/`,
+ data: {stories: searchSelection.asArray},
+ dataType: 'json',
+ success: function (data) {
+ humane.info(data.message);
+ workzoneOptions.refresh();
+ }
+ });
+ }
+
+ function unfix(link) {
+ $.ajax({
+ type: 'POST',
+ url: link,
+ dataType: 'json',
+ success: function (data) {
+ humane.info(data.message);
+ workzoneOptions.refresh();
+ }
+ });
+ }
+
+ function setRemoveWarning(state) {
+ warnOnRemove = state;
+ }
+
+ // remove record from basket/story preferences
+ function toggleRemoveWarning(el) {
+ var state = !el.checked;
+ appCommons.userModule.setPref('reg_delete', (state ? '1' : '0'));
+ warnOnRemove = state;
+ }
+
+ // map events to result selection:
+ appEvents.listenAll({
+ 'workzone.selection.selectAll': () => workzoneOptions.selection.selectAll(),
+ // 'workzone.selection.unselectAll': () => workzoneOptions.selection.empty(),
+ // 'workzone.selection.selectByType': (dataType) => workzoneOptions.selection.select(dataType.type),
+ 'workzone.selection.remove': (data) => workzoneOptions.selection.remove(data.records)
+ });
+
+ appEvents.listenAll({
+ 'broadcast.searchResultSelection': (selection) => {
+ searchSelection = selection;
+ },
+ 'workzone.refresh': refreshBaskets,
+ 'workzone.doAddToBasket': (options) => {
+ workzoneOptions.addElementToBasket(options);
+ },
+ 'workzone.doRemoveFromBasket': (options) => {
+ WorkZoneElementRemover(options.event, options.confirm);
+ },
+ 'workzone.doRemoveWarning': setRemoveWarning,
+ 'workzone.doToggleRemoveWarning': toggleRemoveWarning
+ });
+
+ return {
+ initialize, workzoneFacets, workzoneBaskets, workzoneThesaurus, setRemoveWarning,
+ toggleRemoveWarning, getResultSelectionStream
+ };
+};
+export default workzone;
diff --git a/Phraseanet-production-client/src/components/ui/workzone/thesaurus/index.js b/Phraseanet-production-client/src/components/ui/workzone/thesaurus/index.js
new file mode 100644
index 0000000000..db43503142
--- /dev/null
+++ b/Phraseanet-production-client/src/components/ui/workzone/thesaurus/index.js
@@ -0,0 +1,45 @@
+require('./thesaurus.scss');
+
+import $ from 'jquery';
+import thesaurus from '../../../thesaurus/index';
+
+const workzoneThesaurus = (services) => {
+ const { configService, localeService, appEvents } = services;
+ let $container = null;
+ let thesaurusService = thesaurus(services);
+ const initialize = () => {
+ $container = $('#thesaurus_tab');
+ thesaurusService.initialize({ $container });
+
+ $('#thesaurus_tab .input-medium').on('keyup', function () {
+ if ($('#thesaurus_tab .input-medium').val() !== '') {
+ $('#thesaurus_tab .th_clear').show();
+ } else {
+ $('#thesaurus_tab .th_clear').hide();
+ }
+ });
+
+ $('.th_clear').on('click', function () {
+ $('#thesaurus_tab .input-medium').val('');
+ $('#thesaurus_tab .gform').submit();
+ $('#thesaurus_tab .th_clear').hide();
+ });
+
+ $('.treeview>li.expandable>.hitarea').on('click', function () {
+ if ($(this).css('background-position') === '99% 22px') {
+ $(this).css('background-position', '99% -28px');
+ $(this).addClass('active');
+ } else {
+ $(this).css('background-position', '99% 22px');
+ $(this).removeClass('active');
+ }
+ });
+ };
+
+ appEvents.listenAll({
+ 'thesaurus.show': thesaurusService.show
+ });
+
+ return { initialize };
+};
+export default workzoneThesaurus;
diff --git a/Phraseanet-production-client/src/components/ui/workzone/thesaurus/thesaurus.scss b/Phraseanet-production-client/src/components/ui/workzone/thesaurus/thesaurus.scss
new file mode 100644
index 0000000000..0f95950636
--- /dev/null
+++ b/Phraseanet-production-client/src/components/ui/workzone/thesaurus/thesaurus.scss
@@ -0,0 +1 @@
+@import '../../../../../node_modules/jquery-treeview/jquery.treeview'; // no extension to import css file
diff --git a/Phraseanet-production-client/src/components/uploader/index.js b/Phraseanet-production-client/src/components/uploader/index.js
new file mode 100644
index 0000000000..a82b56208d
--- /dev/null
+++ b/Phraseanet-production-client/src/components/uploader/index.js
@@ -0,0 +1,538 @@
+import $ from 'jquery';
+import * as _ from 'underscore';
+import dialog from './../../phraseanet-common/components/dialog';
+import Alerts from '../utils/alert';
+require('./../../phraseanet-common/components/tooltip');
+
+const uploader = (services) => {
+ const { configService, localeService, appEvents } = services;
+ let UploaderManager;
+ const initialize = () => {
+ dragOnModalClosed();
+
+
+ $('body').on('click', '.uploader-open-action', (event) => {
+ event.preventDefault();
+ var $this = $(event.currentTarget);
+
+ require.ensure([], () => {
+ // load uploader manager dep
+ UploaderManager = require('./uploaderService').default;
+ openModal($this, []);
+ });
+ });
+ };
+
+ const dragOnModalClosed = () => {
+ $('html').on('drop', (event) => {
+ if (event.originalEvent.dataTransfer !== undefined) {
+ let fileList = event.originalEvent.dataTransfer.files;
+ // open modal
+ if (fileList.length > 0) {
+
+ require.ensure([], () => {
+ // load uploader manager dep
+ UploaderManager = require('./uploaderService').default;
+ openModal($('.uploader-open-action'), fileList);
+ });
+
+ event.preventDefault();
+ event.stopPropagation();
+ return false;
+ }
+ }
+ }).on('dragover', (event) => {
+ event.preventDefault();
+ event.stopPropagation();
+ }).on('dragleave', (event) => {
+ event.preventDefault();
+ event.stopPropagation();
+ });
+ }
+
+ const disableDragOnModalClosed = () => {
+ $('html').off('drop');
+ $('html').off('dragover');
+ $('html').off('dragleave');
+ }
+
+ const openModal = ($this, filesList) => {
+ var options = {
+ size: 'Full',
+ loading: true,
+ title: $this.attr('title'),
+ closeOnEscape: true,
+ closeCallback: () => {
+ dragOnModalClosed();
+ }
+ };
+
+ let $dialog = dialog.create(services, options);
+ $.ajax({
+ type: 'GET',
+ url: $this.attr('href'),
+ dataType: 'html',
+ success: function (data) {
+ disableDragOnModalClosed();
+ $dialog.setContent(data);
+ $(document).ready(() => onOpenModal(filesList));
+ return;
+ }
+ });
+ };
+ const onOpenModal = (filesList) => {
+
+ // @TODO replace with feature detection:
+ var iev = 0;
+ var ieold = (/MSIE (\d+\.\d+);/.test(navigator.userAgent));
+ var trident = !!navigator.userAgent.match(/Trident\/7.0/);
+ var rv = navigator.userAgent.indexOf('rv:11.0');
+
+ if (ieold) iev = new Number(RegExp.$1);
+ if (navigator.appVersion.indexOf('MSIE 10') !== -1) iev = 10;
+ if (trident && rv !== -1) iev = 11;
+
+ if (iev >= 10) {
+ $('#UPLOAD_FLASH_LINK').hide();
+ $('#upload_type option[value="flash"]').remove();
+ }
+ // Upload management
+ var uploaderInstance = new UploaderManager({
+ container: $('#uploadBox'),
+ uploadBox: $('#uploadBox .upload-box-addedfiles'),
+ settingsBox: $('#uploadBox .settings-box'),
+ downloadBox: $('#uploadBox .download-box')
+ });
+
+ var totalElement;
+ var maxFileSize = window.uploaderOptions.maxFileSize;
+
+ uploaderInstance.Preview.setOptions({
+ maxWidth: 130,
+ maxHeight: 120
+ });
+
+ $('#upload_type').on('change', function () {
+ if ($(this).val() === 'html') {
+ $("#UPLOAD_HTML5_LINK").trigger("click");
+ }else if ($(this).val() === 'flash') {
+ $("#UPLOAD_FLASH_LINK").trigger("click");
+ }
+ });
+
+ // Init jquery tabs
+ $('.upload-tabs', uploaderInstance.getContainer()).tabs({
+ beforeLoad: function (event, ui) {
+ ui.jqXHR.success(function (xhr, status, index, anchor) {
+ var lazaretBox = $('#lazaretBox');
+
+ $('.userTips', lazaretBox).tooltip();
+ });
+ ui.jqXHR.error(function (xhr, status, index, anchor) {
+ // display error message if ajax failed
+ $(anchor.hash).html(localeService.t('error'));
+ });
+
+ ui.tab.find('span').html(' ');
+ },
+ load: function (event, ui) {
+ ui.tab.find('span').empty();
+ $('.btn.page-lazaret', uploaderInstance.getContainer()).bind('click', function () {
+ $('.lazaret-target').attr('href', $('a', $(this)).attr('href'));
+ $('.upload-tabs', uploaderInstance.getContainer()).tabs('load', 1);
+ $('#lazaretBox').empty();
+
+ return false;
+ });
+ },
+ create: function () {
+ $('#tab-upload').css('overflow', 'hidden');
+ },
+ heightStyle: 'fill'
+ });
+
+ // Show the good collection status box
+ $('select[name="base_id"]', uploaderInstance.getSettingsBox()).bind('change', function () {
+ var selectedCollId = $(this).find('option:selected').val();
+
+ $('#uploadBox .settings-box .collection-status').hide();
+
+ $('#uploadBox #status-' + selectedCollId).show();
+ });
+
+ uploaderInstance.getContainer().on('file-added', function () {
+ $('.number-files').html(uploaderInstance.countData());
+ });
+
+ uploaderInstance.getContainer().on('file-removed', function () {
+ $('.number-files').html(uploaderInstance.countData());
+ });
+
+ uploaderInstance.getContainer().on('file-transmited', function () {
+ var domEl = $('.number-files-transmited');
+ domEl.html(parseInt(domEl.html(), 10) + 1);
+ });
+
+ uploaderInstance.getContainer().on('uploaded-file-removed', function () {
+ var domEl = $('.number-files-to-transmit');
+ domEl.html(parseInt(domEl.html(), 10) - 1);
+ });
+
+ // add a url
+ $('button.add-url', uploaderInstance.getContainer()).bind('click', function(e) {
+ e.preventDefault();
+ var url = $('#add-url', uploaderInstance.getContainer()).val();
+
+ $('.upload-box').show();
+
+ // perform a "head" request on the url (via php proxy) to get mime and size
+ var distantfileInfos = {
+ 'content-type': '?',
+ 'content-length': '?'
+ };
+ $.get(
+ 'upload/head/',
+ {
+ 'url': url
+ }
+ ).done(
+ function(data) {
+ distantfileInfos = data;
+ }
+ ).always(
+ function() {
+ var fileContent = JSON.stringify( {'url' : url} , null, 2); // the content of the "micro json file" that will be uploaded
+ var blob = new Blob(
+ [ fileContent ],
+ {
+ type: 'application/json'
+ }
+ );
+ $('#fileupload', uploaderInstance.getContainer()).fileupload(
+ 'add',
+ {
+ 'files': blob, // files is an array with 1 element
+ 'fileInfos': [ distantfileInfos ] // ... so we do the same with our custom data
+ }
+ );
+ }
+ );
+ });
+
+ // Remove all element from upload box
+ $('button.clear-queue', uploaderInstance.getContainer()).bind('click', function () {
+ uploaderInstance.clearUploadBox();
+ $('ul', $(this).closest('.upload-box')).empty();
+ uploaderInstance.getContainer().trigger('file-removed');
+ });
+
+ // Cancel all upload
+ $('#cancel-all').bind('click', function () {
+ //Remove all cancel
+ $('button.remove-element', uploaderInstance.getDownloadBox()).each(function (i, el) {
+ $(el).trigger('click');
+ });
+
+ progressbarAll.width('0%');
+ });
+
+ // Remove an element from the upload box
+ $(uploaderInstance.getUploadBox()).on('click', 'button.remove-element', function () {
+ var container = $(this).closest('li');
+ var uploadIndex = container.find('input[name=uploadIndex]').val();
+ uploaderInstance.removeData(uploadIndex);
+ container.remove();
+ uploaderInstance.getContainer().trigger('file-removed');
+ });
+
+ // Get all elements in the upload box & trigger the submit event
+ $('button.upload-submitter', uploaderInstance.getContainer()).bind('click', function () {
+ // Fetch all valid elements
+ var documents = uploaderInstance.getUploadBox().find('li.upload-valid');
+
+ totalElement = documents.length;
+
+ if (totalElement > 0) {
+ $('.number-files').html('');
+ $('.number-files-to-transmit').html(totalElement);
+ $('.transmit-box').show();
+
+ var $dialog = dialog.get(1);
+
+ // reset progressbar for iframe uploads
+ if (!$.support.xhrFileUpload && !$.support.xhrFormDataFileUpload) {
+ progressbarAll.width('0%');
+ }
+ // enabled cancel all button
+ $('#cancel-all').attr('disabled', false);
+
+ // prevent dialog box from being closed while files are being downloaded
+ $dialog.getDomElement().bind('dialogbeforeclose', function (event, ui) {
+ if (!uploaderInstance.Queue.isEmpty()) {
+ Alerts(localeService.t('warning'), localeService.t('fileBeingDownloaded'));
+ return false;
+ }
+ });
+
+ documents.each(function (index, el) {
+ let indexValue = $(el).find('input[name=uploadIndex]').val();
+ var data = uploaderInstance.getData(indexValue);
+ uploaderInstance.getData(indexValue).submit();
+ });
+ }
+ });
+
+ $('#fileupload', uploaderInstance.getContainer()).fileupload({
+ namespace: 'phrasea-upload',
+ // define our own mediatype to handle and convert the response
+ // to prevent errors when Iframe based uploads
+ // as they require text/plain or text/html Content-type
+ // see http://api.jquery.com/extending-ajax/#Converters
+ dataType: 'phrjson',
+ converters: {
+ 'html phrjson': function (htmlEncodedJson) {
+ return $.parseJSON(htmlEncodedJson);
+ },
+ 'iframe phrjson': function (iframe) {
+ return $.parseJSON(iframe.find('body').text());
+ }
+ },
+ // override "on error" local ajax event to prevent global ajax event from being triggered
+ // as all fileupload options are passed as argument to the $.ajax jquery function
+ error: function () {
+ return false;
+ },
+ // Set singleFileUploads, sequentialUploads to true so the files
+ // are upload one by one
+ singleFileUploads: true, // There will be ONE AND ONLY ONE file into data.files
+ sequentialUploads: true,
+ recalculateProgress: true,
+ // When a file is added
+ add: function (e, data) {
+ // Since singleFileUploads & sequentialUploads are setted to true
+ // There is ONE AND ONLY ONE file into data.files
+ $.each(data.files, function (index, file) {
+ $('.upload-box').show();
+ let params = {};
+ let html = '';
+ if (file.error) {
+ params = $.extend({}, file, {error: localeService.t('errorFileApi')});
+ html = _.template($('#upload_items_error_tpl').html())(params);
+ uploaderInstance.getUploadBox().append(html);
+ } else if (file.size > maxFileSize) {
+ params = $.extend({}, file, {error: localeService.t('errorFileApiTooBig')});
+ html = _.template($('#upload_items_error_tpl').html())(params);
+ uploaderInstance.getUploadBox().append(html);
+ } else {
+ // Add data to Queue
+ uploaderInstance.addData(data);
+
+ // Check support of file.size && file.type property
+ var formatedFile = {
+ id: 'file-' + index,
+ size: typeof file.size !== 'undefined' ? uploaderInstance.Formater.size(file.size) : '',
+ name: encodeURI(file.name),
+ type: typeof file.type !== 'undefined' ? file.type : '',
+ uploadIndex: uploaderInstance.getUploadIndex()
+ };
+
+ // if the "file" is a blob (tiny json with url to a distant file),
+ // we can find infos of distant file into data, and fix html
+ if(typeof(data.fileInfos) !== 'undefined') {
+ formatedFile.size = uploaderInstance.Formater.size(data.fileInfos[index]['content-length']);
+ formatedFile.name = data.fileInfos[index]['basename'];
+ formatedFile.type = data.fileInfos[index]['content-type'];
+ }
+
+ // Set context in upload-box
+ html = _.template($('#upload_items_tpl').html())(formatedFile);
+ uploaderInstance.getUploadBox().append(html);
+
+ var context = $('li', uploaderInstance.getUploadBox()).last();
+
+ var uploadIndex = context.find('input[name=uploadIndex]').val();
+
+ uploaderInstance.addAttributeToData(uploadIndex, 'context', context);
+
+ uploaderInstance.Preview.render(file, function (img) {
+ context.find('.thumbnail .canva-wrapper').prepend(img);
+ uploaderInstance.addAttributeToData(uploadIndex, 'image', img);
+ });
+ }
+ });
+
+ uploaderInstance.getContainer().trigger('file-added');
+ },
+
+ submit: function(e, data) {
+ return false;
+ },
+
+ // on success upload
+ done: function (e, data) {
+ // set progress bar to 100% for preventing mozilla bug which never reach 100%
+ data.context.find('.progress-bar').width('100%');
+ data.context.find('div.progress').removeClass('progress-striped active');
+ data.context.find('button.remove-element').removeClass('btn-inverse').addClass('disabled');
+
+ uploaderInstance.removeData(data.uploadIndex);
+ uploaderInstance.getContainer().trigger('file-transmited');
+
+ data.context.find('button.remove-element').remove();
+
+ if (!$.support.xhrFileUpload && !$.support.xhrFormDataFileUpload) {
+ progressbarAll.width(100 - Math.round((uploaderInstance.Queue.getLength() * (100 / totalElement))) + '%');
+ }
+
+ if (uploaderInstance.Queue.isEmpty()) {
+ progressbarAll.width('100%');
+ bitrateBox.empty();
+ $('#uploadBoxRight .progress').removeClass('progress-striped active');
+ var $dialog = dialog.get(1);
+ // unbind check before close event & disabled button for cancel all download
+ $dialog.getDomElement().unbind('dialogbeforeclose');
+ // disabled cancel-all button, if queue is empty and last upload success
+ $('#cancel-all').attr('disabled', true);
+ }
+
+ return false;
+ },
+
+ fail: function () {
+ // disabled cancel-all button, if queue is empty and last upload fail
+ if (uploaderInstance.Queue.isEmpty()) {
+ $('#cancel-all').attr('disabled', true);
+ }
+ }
+ });
+
+ // on submit file
+ $('#fileupload', uploaderInstance.getContainer()).bind('fileuploadsubmit', function (e, data) {
+ var $this = $(this);
+ var params = [];
+ data.formData = [];
+
+ // get form datas attached to the file
+ params.push(data.context.find('input, select').serializeArray());
+ params.push($('input', $('.collection-status:visible', uploaderInstance.getSettingsBox())).serializeArray());
+ params.push($('select', uploaderInstance.getSettingsBox()).serializeArray());
+
+ $.each(params, function (i, p) {
+ $.each(p, function (i, f) {
+ data.formData.push(f);
+ });
+ });
+
+ // remove current context
+ data.context.remove();
+
+ // Set new context in download-box
+ $.each(data.files, function (index, file) {
+ let params = $.extend({}, file, {id: 'file-' + index, name: encodeURI(file.name)});
+
+ // if the "file" is a blob (tiny json with url to a distant file),
+ // we can find infos of distant file into data, and fix html
+ if (typeof (data.fileInfos) !== 'undefined') {
+ params.name = data.fileInfos[index]['basename'];
+ }
+
+ let html = _.template($('#download_items_tpl').html())(params);
+
+ uploaderInstance.getDownloadBox().append(html);
+
+ data.context = $('li', uploaderInstance.getDownloadBox()).last();
+
+ // copy image
+ data.context.find('.upload-record .canva-wrapper').prepend(data.image);
+
+ // launch ajax request
+ var jqXHR = $this.fileupload('send', data)
+ .success(function (response) {
+ if (response.success) {
+ // case record
+ if (response.element === 'record') {
+ html = _.template($('#download_finish_tpl').html())({
+ heading: response.message,
+ reasons: response.reasons
+ });
+ data.context.find('.upload-record p.success').append(html).show();
+ } else {
+ // case quarantine
+ html = _.template($('#download_finish_tpl').html())({
+ heading: response.message,
+ reasons: response.reasons
+ });
+ data.context.find('.upload-record p.error').append(html).show();
+ }
+ } else {
+ // fail
+ html = _.template($('#download_finish_tpl').html())({
+ heading: response.message,
+ reasons: response.reasons
+ });
+ data.context.find('.upload-record p.error').append(html).show();
+ }
+ })
+ .error(function (jqXHR, textStatus, errorThrown) {
+ // Request is aborted
+ if (errorThrown === 'abort') {
+ return false;
+ } else {
+ data.context.find('.upload-record p.error').append(jqXHR.status + ' ' + jqXHR.statusText).show();
+ }
+ // Remove data
+ uploaderInstance.removeData(data.uploadIndex);
+ // Remove cancel button
+ $('button.remove-element', data.context).remove();
+ });
+
+ // cancel request
+ $('button.remove-element', data.context).bind('click', function (e) {
+ jqXHR.abort();
+ data.context.remove();
+
+ uploaderInstance.getContainer().trigger('uploaded-file-removed');
+ });
+ });
+
+ return false;
+ });
+
+ var bitrateBox = $('#uploadBoxRight .bitrate-box');
+
+ // Get one file upload progress & bitrate
+ $('#fileupload', uploaderInstance.getContainer()).bind('fileuploadprogress', function (e, data) {
+ var progressbar = data.context.find('.progress-bar');
+ progressbar.width(Math.round(uploaderInstance.Formater.pourcent(data.loaded, data.total)) + '%');
+ bitrateBox.empty().append(uploaderInstance.Formater.bitrate(data.bitrate));
+ });
+
+ var progressbarAll = $('#uploadBoxRight .progress-bar-total');
+
+ // Get global upload progress
+ $('#fileupload', uploaderInstance.getContainer()).bind('fileuploadprogressall', function (e, data) {
+ progressbarAll.width(Math.round(uploaderInstance.Formater.pourcent(data.loaded, data.total)) + '%');
+ });
+
+ $('#fileupload', uploaderInstance.getContainer()).bind('fileuploadfail', function (e, data) {
+ // Remove from queue
+ uploaderInstance.removeData(data.uploadIndex);
+ });
+
+ $('#fileupload', uploaderInstance.getContainer()).bind('fileuploadsend', function (e, data) {
+
+ // IFRAME progress fix
+ if (!$.support.xhrFileUpload && !$.support.xhrFormDataFileUpload) {
+ data.context.find('.progress-bar').width('25%');
+ }
+ });
+
+ // if initialized with dropped files:
+ if (filesList !== undefined) {
+ $('#fileupload', uploaderInstance.getContainer()).fileupload('add', {files: filesList});
+ }
+ };
+
+ return {initialize};
+};
+export default uploader;
diff --git a/Phraseanet-production-client/src/components/uploader/uploaderService.js b/Phraseanet-production-client/src/components/uploader/uploaderService.js
new file mode 100644
index 0000000000..0ba2741d41
--- /dev/null
+++ b/Phraseanet-production-client/src/components/uploader/uploaderService.js
@@ -0,0 +1,251 @@
+import $ from 'jquery';
+let loadImage = require('blueimp-load-image/js/load-image');
+/* The jQuery UI widget factory, can be omitted if jQuery UI is already included */
+require('imports-loader?$=jquery!blueimp-file-upload/js/vendor/jquery.ui.widget.js');
+/* The Iframe Transport is required for browsers without support for XHR file uploads */
+require('imports-loader?define=>false&exports=>false&$=jquery!blueimp-file-upload/js/jquery.iframe-transport.js');
+/* The basic File Upload plugin */
+require('imports-loader?define=>false&exports=>false&$=jquery!blueimp-file-upload/js/jquery.fileupload.js');
+
+/**
+ * UPLOADER MANAGER
+ */
+var UploaderManager = function (options) {
+ options = options || {};
+
+ if ('container' in options === false) {
+ throw 'missing container parameter';
+ } else if (!options.container.jquery) {
+ throw 'container parameter must be a jquery dom element';
+ }
+
+ if ('settingsBox' in options === false) {
+ throw 'missing settingBox parameter';
+ } else if (!options.settingsBox.jquery) {
+ throw 'container parameter must be a jquery dom element';
+ }
+
+ if ('uploadBox' in options === false) {
+ throw 'missing uploadBox parameter';
+ } else if (!options.uploadBox.jquery) {
+ throw 'container parameter must be a jquery dom element';
+ }
+
+ if ('downloadBox' in options === false) {
+ throw 'missing downloadBox parameter';
+ } else if (!options.downloadBox.jquery) {
+ throw 'container parameter must be a jquery dom element';
+ }
+
+ this.recordClass = options.recordClass || 'upload-record';
+
+ this.options = options;
+
+ this.options.uploadBox.wrapInner('');
+
+ this.options.uploadBox = this.options.uploadBox.find('ul:first');
+
+ this.options.downloadBox.wrapInner('');
+
+ this.options.downloadBox = this.options.downloadBox.find('ul:first');
+
+ if ($.isFunction($.fn.sortable)) {
+ this.options.uploadBox.sortable();
+ }
+
+ this.uploadIndex = 0;
+
+ this.Queue = new Queue();
+ this.Formater = new Formater();
+ this.Preview = new Preview();
+};
+
+UploaderManager.prototype = {
+ setOptions: function (options) {
+ return $.extend(this.options, options);
+ },
+ getContainer: function () {
+ return this.options.container;
+ },
+ getUploadBox: function () {
+ return this.options.uploadBox;
+ },
+ getSettingsBox: function () {
+ return this.options.settingsBox;
+ },
+ getDownloadBox: function () {
+ return this.options.downloadBox;
+ },
+ clearUploadBox: function () {
+ this.getUploadBox().empty();
+ this.uploadIndex = 0;
+ this.Queue.clear();
+ },
+ getDatas: function () {
+ return this.Queue.all();
+ },
+ getData: function (index) {
+ return this.Queue.get(index);
+ },
+ addData: function (data) {
+ this.uploadIndex++;
+ data.uploadIndex = this.uploadIndex;
+ this.Queue.set(this.uploadIndex, data);
+ },
+ removeData: function (index) {
+ this.Queue.remove(index);
+ },
+ addAttributeToData: function (indexOfData, attribute, value) {
+ var data = this.getData(indexOfData);
+ if ($.type(attribute) === 'string') {
+ data[attribute] = value;
+ this.Queue.set(indexOfData, data);
+ }
+ },
+ getUploadIndex: function () {
+ return this.uploadIndex;
+ },
+ hasData: function () {
+ return !this.Queue.isEmpty();
+ },
+ countData: function () {
+ return this.Queue.getLength();
+ }
+};
+/**
+ * PREVIEW
+ *
+ * Dependency : loadImage function
+ * @see https://github.com/blueimp/JavaScript-Load-Image
+ *
+ * Options
+ * maxWidth: (int) Max width of preview
+ * maxHeight: (int) Max height of preview
+ * minWidth: (int) Min width of preview
+ * minHeight: (int) Min height of preview
+ * canva: (boolean) render preview as canva if supported by the navigator
+ */
+
+var Preview = function () {
+ this.options = {
+ fileType: /^image\/(gif|jpeg|png|jpg)$/,
+ maxSize: 5242880 // 5MB
+ };
+};
+
+Preview.prototype = {
+ setOptions: function (options) {
+ this.options = $.extend(this.options, options);
+ },
+ getOptions: function () {
+ return this.options;
+ },
+ render: function (file, callback) {
+ if (
+ typeof loadImage === 'function' &&
+ this.options.fileType.test(file.type)
+ ) {
+ if (
+ $.type(this.options.maxSize) !== 'number' ||
+ file.size < this.options.maxSize
+ ) {
+ var options = {
+ maxWidth: this.options.maxWidth || 150,
+ maxHeight: this.options.maxHeight || 75,
+ minWidth: this.options.minWidth || 80,
+ minHeight: this.options.minHeight || 40,
+ canvas: this.options.canva || true
+ };
+ loadImage(file, callback, options);
+ }
+ }
+ }
+};
+
+/**
+ * FORMATER
+ */
+
+var Formater = function () {};
+
+Formater.prototype = {
+ size: function (bytes) {
+ if (typeof bytes !== 'number') {
+ throw bytes + ' is not a number';
+ }
+ if (bytes >= 1073741824) {
+ return (bytes / 1073741824).toFixed(2) + ' GB';
+ }
+ if (bytes >= 1048576) {
+ return (bytes / 1048576).toFixed(2) + ' MB';
+ }
+ return (bytes / 1024).toFixed(2) + ' KB';
+ },
+ bitrate: function (bits) {
+ if (typeof bits !== 'number') {
+ throw bits + ' is not a number';
+ }
+ // 1 byte = 8 bits
+ var bytes = bits >> 3;
+
+ if (bytes >= 1 << 30) {
+ return (bytes / (1 << 30)).toFixed(2) + ' Go/s';
+ }
+ if (bytes >= 1 << 20) {
+ return (bytes / (1 << 20)).toFixed(2) + ' Mo/s';
+ }
+ if (bytes >= 1 << 10) {
+ return (bytes / (1 << 10)).toFixed(2) + ' Ko/s';
+ }
+ return bytes + ' o/s';
+ },
+ pourcent: function (current, total) {
+ return (current / total * 100).toFixed(2);
+ }
+};
+
+/**
+ * QUEUE
+ */
+var Queue = function () {
+ this.list = {};
+};
+
+Queue.prototype = {
+ all: function () {
+ return this.list;
+ },
+ set: function (id, item) {
+ this.list[id] = item;
+ return this;
+ },
+ get: function (id) {
+ if (!this.list[id]) {
+ throw 'Unknown ID' + id;
+ }
+ return this.list[id];
+ },
+ remove: function (id) {
+ delete this.list[id];
+ },
+ getLength: function () {
+ var count = 0;
+ for (let k in this.list) {
+ if (this.list.hasOwnProperty(k)) {
+ ++count;
+ }
+ }
+ return count;
+ },
+ isEmpty: function () {
+ return this.getLength() === 0;
+ },
+ clear: function () {
+ var $this = this;
+ $.each(this.list, function (k) {
+ $this.remove(k);
+ });
+ }
+};
+
+export default UploaderManager;
diff --git a/Phraseanet-production-client/src/components/user/index.js b/Phraseanet-production-client/src/components/user/index.js
new file mode 100644
index 0000000000..fa8652cb97
--- /dev/null
+++ b/Phraseanet-production-client/src/components/user/index.js
@@ -0,0 +1,61 @@
+import $ from 'jquery';
+import ui from '../ui';
+import notify from '../notify';
+import * as appCommons from './../../phraseanet-common';
+
+const user = (services) => {
+ const { configService, localeService, appEvents } = services;
+
+ const initialize = () => {
+
+ };
+
+ const onUserDisconnect = (...data) => {
+ // @TODO refactor - display modal in here
+ ui(services).showModal('disconnected', {title: localeService.t('serverDisconnected')});
+ };
+
+ appEvents.listenAll({
+ 'user.disconnected': onUserDisconnect
+ });
+
+ const manageSession = (...params) => {
+ let [data, showMessages] = params;
+
+ if (typeof (showMessages) === 'undefined') {
+ showMessages = false;
+ }
+
+ if (showMessages) {
+ // @todo: to be moved
+ if ($.trim(data.message) !== '') {
+ if ($('#MESSAGE').length === 0) {
+ $('body').append('
');
+ }
+ $('#MESSAGE')
+ .empty()
+ .append(data.message + ' ' + localeService.t('hideMessage') + '
')
+ .attr('title', 'Global Message')
+ .dialog({
+ autoOpen: false,
+ closeOnEscape: true,
+ resizable: false,
+ draggable: false,
+ modal: true,
+ close: function () {
+ if ($('.dialog_remove:checked', $(this)).length > 0) {
+ // @TODO get from module
+ appCommons.userModule.setTemporaryPref('message', 0);
+ }
+ }
+ })
+ .dialog('open');
+ }
+ }
+ return true;
+ };
+
+ return {initialize, manageSession};
+};
+
+export default user;
diff --git a/Phraseanet-production-client/src/components/utils/alert.js b/Phraseanet-production-client/src/components/utils/alert.js
new file mode 100644
index 0000000000..383c0d3a45
--- /dev/null
+++ b/Phraseanet-production-client/src/components/utils/alert.js
@@ -0,0 +1,53 @@
+import $ from 'jquery';
+
+function create_dialog() {
+ if ($('#p4_alerts').length === 0) {
+ $('body').append('
');
+ }
+ return $('#p4_alerts');
+}
+
+function alert(title, message, callback) {
+ var $dialog = create_dialog();
+
+ var button = {};
+
+ button.Ok = function () {
+ if (typeof callback === 'function') {
+ callback();
+ } else {
+ $dialog.dialog('close');
+ }
+ };
+ if ($dialog.data('ui-dialog')) {
+ $dialog.dialog('destroy');
+ }
+
+ $dialog.attr('title', title)
+ .empty()
+ .append(message)
+ .dialog({
+ autoOpen: false,
+ closeOnEscape: true,
+ resizable: false,
+ draggable: false,
+ modal: true,
+ buttons: button,
+ overlay: {
+ backgroundColor: '#000',
+ opacity: 0.7
+ }
+ }).dialog('open');
+
+ if (typeof callback === 'function') {
+ $dialog.bind('dialogclose', function (event, ui) {
+ callback();
+ });
+ }
+
+ return;
+}
+
+const Alerts = alert;
+
+export default Alerts;
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/colorAnimation.js b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorAnimation.js
new file mode 100644
index 0000000000..d315be6abf
--- /dev/null
+++ b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorAnimation.js
@@ -0,0 +1,130 @@
+import $ from 'jquery';
+/*
+ * $ Color Animations
+ * Copyright 2007 John Resig
+ * Released under the MIT and GPL licenses.
+ */
+
+(function () {
+
+ // We override the animation for all of these color styles
+ $.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor', 'color', 'outlineColor'], function (i, attr) {
+ $.fx.step[attr] = function (fx) {
+ if (fx.state === 0) {
+ fx.start = getColor(fx.elem, attr);
+ fx.end = getRGB(fx.end);
+ }
+
+ fx.elem.style[attr] = 'rgb(' + [
+ Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 255), 0),
+ Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 255), 0),
+ Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 255), 0)
+ ].join(',') + ')';
+ };
+ });
+
+ // Color Conversion functions from highlightFade
+ // By Blair Mitchelmore
+ // http://$.offput.ca/highlightFade/
+
+ // Parse strings looking for color tuples [255,255,255]
+ function getRGB(color) {
+ var result;
+
+ // Check if we're already dealing with an array of colors
+ if (color && color.constructor === Array && color.length === 3) {
+ return color;
+ }
+
+ // Look for rgb(num,num,num)
+ if (result = (/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/).exec(color)) {
+ return [parseInt(result[1], 10), parseInt(result[2], 10), parseInt(result[3], 10)];
+ }
+
+ // Look for rgb(num%,num%,num%)
+ if (result = (/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/).exec(color)) {
+ return [parseFloat(result[1]) * 2.55, parseFloat(result[2]) * 2.55, parseFloat(result[3]) * 2.55];
+ }
+
+ // Look for #a0b1c2
+ if (result = (/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/).exec(color)) {
+ return [parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)];
+ }
+
+ // Look for #fff
+ if (result = (/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/).exec(color)) {
+ return [parseInt(result[1] + result[1], 16), parseInt(result[2] + result[2], 16), parseInt(result[3] + result[3], 16)];
+ }
+
+ // Otherwise, we're most likely dealing with a named color
+ return colors[$.trim(color).toLowerCase()];
+ }
+
+ function getColor(elem, attr) {
+ var color;
+
+ do {
+ color = $.curCSS(elem, attr);
+
+ // Keep going until we find an element that has color, or we hit the body
+ if (color !== '' && color !== 'transparent' || $.nodeName(elem, 'body')) {
+ break;
+ }
+
+ attr = 'backgroundColor';
+ } while (elem = elem.parentNode);
+
+ return getRGB(color);
+ }
+
+ // Some named colors to work with
+ // From Interface by Stefan Petre
+ // http://interface.eyecon.ro/
+
+ var colors = {
+ aqua: [0, 255, 255],
+ azure: [240, 255, 255],
+ beige: [245, 245, 220],
+ black: [0, 0, 0],
+ blue: [0, 0, 255],
+ brown: [165, 42, 42],
+ cyan: [0, 255, 255],
+ darkblue: [0, 0, 139],
+ darkcyan: [0, 139, 139],
+ darkgrey: [169, 169, 169],
+ darkgreen: [0, 100, 0],
+ darkkhaki: [189, 183, 107],
+ darkmagenta: [139, 0, 139],
+ darkolivegreen: [85, 107, 47],
+ darkorange: [255, 140, 0],
+ darkorchid: [153, 50, 204],
+ darkred: [139, 0, 0],
+ darksalmon: [233, 150, 122],
+ darkviolet: [148, 0, 211],
+ fuchsia: [255, 0, 255],
+ gold: [255, 215, 0],
+ green: [0, 128, 0],
+ indigo: [75, 0, 130],
+ khaki: [240, 230, 140],
+ lightblue: [173, 216, 230],
+ lightcyan: [224, 255, 255],
+ lightgreen: [144, 238, 144],
+ lightgrey: [211, 211, 211],
+ lightpink: [255, 182, 193],
+ lightyellow: [255, 255, 224],
+ lime: [0, 255, 0],
+ magenta: [255, 0, 255],
+ maroon: [128, 0, 0],
+ navy: [0, 0, 128],
+ olive: [128, 128, 0],
+ orange: [255, 165, 0],
+ pink: [255, 192, 203],
+ purple: [128, 0, 128],
+ violet: [128, 0, 128],
+ red: [255, 0, 0],
+ silver: [192, 192, 192],
+ white: [255, 255, 255],
+ yellow: [255, 255, 0]
+ };
+
+})();
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/colorpicker.js b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/colorpicker.js
new file mode 100644
index 0000000000..40ee869957
--- /dev/null
+++ b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/colorpicker.js
@@ -0,0 +1,517 @@
+//require('./colorpicker.scss');
+
+import $ from 'jquery';
+/**
+ *
+ * Color picker
+ * Author: Stefan Petre www.eyecon.ro
+ *
+ * Dual licensed under the MIT and GPL licenses
+ *
+ */
+(function ($) {
+ const ColorPicker = function () {
+ let ids = {};
+ let inAction;
+ let charMin = 65;
+ let visible;
+ let tpl = '';
+ let defaults = {
+ eventName: 'click',
+ onShow: function () {
+ },
+ onBeforeShow: function () {
+ },
+ onHide: function () {
+ },
+ onChange: function () {
+ },
+ onSubmit: function () {
+ },
+ color: 'ff0000',
+ livePreview: true,
+ flat: false
+ };
+ const fillRGBFields = function (hsb, cal) {
+ let rgb = _HSBToRGB(hsb);
+ $(cal).data('colorpicker').fields
+ .eq(1).val(rgb.r).end()
+ .eq(2).val(rgb.g).end()
+ .eq(3).val(rgb.b).end();
+ };
+ const fillHSBFields = function (hsb, cal) {
+ $(cal).data('colorpicker').fields
+ .eq(4).val(hsb.h).end()
+ .eq(5).val(hsb.s).end()
+ .eq(6).val(hsb.b).end();
+ };
+ const fillHexFields = function (hsb, cal) {
+ $(cal).data('colorpicker').fields
+ .eq(0).val(_HSBToHex(hsb)).end();
+ };
+ const setSelector = function (hsb, cal) {
+ $(cal).data('colorpicker').selector.css('backgroundColor', '#' + _HSBToHex({h: hsb.h, s: 100, b: 100}));
+ $(cal).data('colorpicker').selectorIndic.css({
+ left: parseInt(150 * hsb.s / 100, 10),
+ top: parseInt(150 * (100 - hsb.b) / 100, 10)
+ });
+ };
+ const setHue = function (hsb, cal) {
+ $(cal).data('colorpicker').hue.css('top', parseInt(150 - 150 * hsb.h / 360, 10));
+ };
+ const setCurrentColor = function (hsb, cal) {
+ $(cal).data('colorpicker').currentColor.css('backgroundColor', '#' + _HSBToHex(hsb));
+ };
+ const setNewColor = function (hsb, cal) {
+ $(cal).data('colorpicker').newColor.css('backgroundColor', '#' + _HSBToHex(hsb));
+ };
+ const keyDown = function (ev) {
+ var pressedKey = ev.charCode || ev.keyCode || -1;
+ if ((pressedKey > charMin && pressedKey <= 90) || pressedKey === 32) {
+ return false;
+ }
+ var cal = $(this).parent().parent();
+ if (cal.data('colorpicker').livePreview === true) {
+ change.apply(this);
+ }
+ };
+ const change = function (ev) {
+ let cal = $(this).parent().parent();
+ let col;
+ if (this.parentNode.className.indexOf('_hex') > 0) {
+ cal.data('colorpicker').color = col = _HexToHSB(fixHex(this.value));
+ } else if (this.parentNode.className.indexOf('_hsb') > 0) {
+ cal.data('colorpicker').color = col = fixHSB({
+ h: parseInt(cal.data('colorpicker').fields.eq(4).val(), 10),
+ s: parseInt(cal.data('colorpicker').fields.eq(5).val(), 10),
+ b: parseInt(cal.data('colorpicker').fields.eq(6).val(), 10)
+ });
+ } else {
+ cal.data('colorpicker').color = col = _RGBToHSB(fixRGB({
+ r: parseInt(cal.data('colorpicker').fields.eq(1).val(), 10),
+ g: parseInt(cal.data('colorpicker').fields.eq(2).val(), 10),
+ b: parseInt(cal.data('colorpicker').fields.eq(3).val(), 10)
+ }));
+ }
+ if (ev) {
+ fillRGBFields(col, cal.get(0));
+ fillHexFields(col, cal.get(0));
+ fillHSBFields(col, cal.get(0));
+ }
+ setSelector(col, cal.get(0));
+ setHue(col, cal.get(0));
+ setNewColor(col, cal.get(0));
+ cal.data('colorpicker').onChange.apply(cal, [col, _HSBToHex(col), _HSBToRGB(col)]);
+ };
+ const blur = function (ev) {
+ var cal = $(this).parent().parent();
+ cal.data('colorpicker').fields.parent().removeClass('colorpicker_focus');
+ };
+ const focus = function () {
+ charMin = this.parentNode.className.indexOf('_hex') > 0 ? 70 : 65;
+ $(this).parent().parent().data('colorpicker').fields.parent().removeClass('colorpicker_focus');
+ $(this).parent().addClass('colorpicker_focus');
+ };
+ const downIncrement = function (ev) {
+ var field = $(this).parent().find('input').focus();
+ var current = {
+ el: $(this).parent().addClass('colorpicker_slider'),
+ max: this.parentNode.className.indexOf('_hsb_h') > 0 ? 360 : (this.parentNode.className.indexOf('_hsb') > 0 ? 100 : 255),
+ y: ev.pageY,
+ field: field,
+ val: parseInt(field.val(), 10),
+ preview: $(this).parent().parent().data('colorpicker').livePreview
+ };
+ $(document).bind('mouseup', current, upIncrement);
+ $(document).bind('mousemove', current, moveIncrement);
+ };
+ const moveIncrement = function (ev) {
+ ev.data.field.val(Math.max(0, Math.min(ev.data.max, parseInt(ev.data.val + ev.pageY - ev.data.y, 10))));
+ if (ev.data.preview) {
+ change.apply(ev.data.field.get(0), [true]);
+ }
+ return false;
+ };
+ const upIncrement = function (ev) {
+ change.apply(ev.data.field.get(0), [true]);
+ ev.data.el.removeClass('colorpicker_slider').find('input').focus();
+ $(document).unbind('mouseup', upIncrement);
+ $(document).unbind('mousemove', moveIncrement);
+ return false;
+ };
+ const downHue = function (ev) {
+ var current = {
+ cal: $(this).parent(),
+ y: $(this).offset().top
+ };
+ current.preview = current.cal.data('colorpicker').livePreview;
+ $(document).bind('mouseup', current, upHue);
+ $(document).bind('mousemove', current, moveHue);
+ };
+ const moveHue = function (ev) {
+ change.apply(
+ ev.data.cal.data('colorpicker')
+ .fields
+ .eq(4)
+ .val(parseInt(360 * (150 - Math.max(0, Math.min(150, (ev.pageY - ev.data.y)))) / 150, 10))
+ .get(0),
+ [ev.data.preview]
+ );
+ return false;
+ };
+ const upHue = function (ev) {
+ fillRGBFields(ev.data.cal.data('colorpicker').color, ev.data.cal.get(0));
+ fillHexFields(ev.data.cal.data('colorpicker').color, ev.data.cal.get(0));
+ $(document).unbind('mouseup', upHue);
+ $(document).unbind('mousemove', moveHue);
+ return false;
+ };
+ const downSelector = function (ev) {
+ var current = {
+ cal: $(this).parent(),
+ pos: $(this).offset()
+ };
+ current.preview = current.cal.data('colorpicker').livePreview;
+ $(document).bind('mouseup', current, upSelector);
+ $(document).bind('mousemove', current, moveSelector);
+ };
+ const moveSelector = function (ev) {
+ change.apply(
+ ev.data.cal.data('colorpicker')
+ .fields
+ .eq(6)
+ .val(parseInt(100 * (150 - Math.max(0, Math.min(150, (ev.pageY - ev.data.pos.top)))) / 150, 10))
+ .end()
+ .eq(5)
+ .val(parseInt(100 * (Math.max(0, Math.min(150, (ev.pageX - ev.data.pos.left)))) / 150, 10))
+ .get(0),
+ [ev.data.preview]
+ );
+ return false;
+ };
+ const upSelector = function (ev) {
+ fillRGBFields(ev.data.cal.data('colorpicker').color, ev.data.cal.get(0));
+ fillHexFields(ev.data.cal.data('colorpicker').color, ev.data.cal.get(0));
+ $(document).unbind('mouseup', upSelector);
+ $(document).unbind('mousemove', moveSelector);
+ return false;
+ };
+ const enterSubmit = function (ev) {
+ $(this).addClass('colorpicker_focus');
+ };
+ const leaveSubmit = function (ev) {
+ $(this).removeClass('colorpicker_focus');
+ };
+ const clickSubmit = function (ev) {
+ var cal = $(this).parent();
+ var col = cal.data('colorpicker').color;
+ cal.data('colorpicker').origColor = col;
+ setCurrentColor(col, cal.get(0));
+ cal.data('colorpicker').onSubmit(col, _HSBToHex(col), _HSBToRGB(col), cal.data('colorpicker').el);
+ };
+ const show = function (ev) {
+ var cal = $('#' + $(this).data('colorpickerId'));
+ cal.data('colorpicker').onBeforeShow.apply(this, [cal.get(0)]);
+ var pos = $(this).offset();
+ var viewPort = getViewport();
+ var top = pos.top + this.offsetHeight;
+ var left = pos.left;
+ if (top + 176 > viewPort.t + viewPort.h) {
+ top -= this.offsetHeight + 176;
+ }
+ if (left + 356 > viewPort.l + viewPort.w) {
+ left -= 356;
+ }
+ cal.css({left: left + 'px', top: top + 'px'});
+ if (cal.data('colorpicker').onShow.apply(this, [cal.get(0)]) !== false) {
+ cal.show();
+ }
+ $(document).bind('mousedown', {cal: cal}, hide);
+ return false;
+ };
+ const hide = function (ev) {
+ if (!isChildOf(ev.data.cal.get(0), ev.target, ev.data.cal.get(0))) {
+ if (ev.data.cal.data('colorpicker').onHide.apply(this, [ev.data.cal.get(0)]) !== false) {
+ ev.data.cal.hide();
+ }
+ $(document).unbind('mousedown', hide);
+ }
+ };
+ const isChildOf = function (parentEl, el, container) {
+ if (parentEl === el) {
+ return true;
+ }
+ if (parentEl.contains) {
+ return parentEl.contains(el);
+ }
+ if (parentEl.compareDocumentPosition) {
+ return !!(parentEl.compareDocumentPosition(el) & 16);
+ }
+ var prEl = el.parentNode;
+ while (prEl && prEl !== container) {
+ if (prEl === parentEl) {
+ return true;
+ }
+ prEl = prEl.parentNode;
+ }
+ return false;
+ };
+ const getViewport = function () {
+ var m = document.compatMode === 'CSS1Compat';
+ return {
+ l: window.pageXOffset || (m ? document.documentElement.scrollLeft : document.body.scrollLeft),
+ t: window.pageYOffset || (m ? document.documentElement.scrollTop : document.body.scrollTop),
+ w: window.innerWidth || (m ? document.documentElement.clientWidth : document.body.clientWidth),
+ h: window.innerHeight || (m ? document.documentElement.clientHeight : document.body.clientHeight)
+ };
+ };
+ const fixHSB = function (hsb) {
+ return {
+ h: Math.min(360, Math.max(0, hsb.h)),
+ s: Math.min(100, Math.max(0, hsb.s)),
+ b: Math.min(100, Math.max(0, hsb.b))
+ };
+ };
+ const fixRGB = function (rgb) {
+ return {
+ r: Math.min(255, Math.max(0, rgb.r)),
+ g: Math.min(255, Math.max(0, rgb.g)),
+ b: Math.min(255, Math.max(0, rgb.b))
+ };
+ };
+ const fixHex = function (hex) {
+ var len = 6 - hex.length;
+ if (len > 0) {
+ var o = [];
+ for (let i = 0; i < len; i++) {
+ o.push('0');
+ }
+ o.push(hex);
+ hex = o.join('');
+ }
+ return hex;
+ };
+ const _HexToRGB = function (hex) {
+ hex = parseInt(((hex.indexOf('#') > -1) ? hex.substring(1) : hex), 16);
+ return {r: hex >> 16, g: (hex & 0x00FF00) >> 8, b: (hex & 0x0000FF)};
+ };
+ const _HexToHSB = function (hex) {
+ return _RGBToHSB(_HexToRGB(hex));
+ };
+ const _RGBToHSB = function (rgb) {
+ var hsb = {
+ h: 0,
+ s: 0,
+ b: 0
+ };
+ var min = Math.min(rgb.r, rgb.g, rgb.b);
+ var max = Math.max(rgb.r, rgb.g, rgb.b);
+ var delta = max - min;
+ hsb.b = max;
+ if (max !== 0) {
+
+ }
+ hsb.s = max !== 0 ? 255 * delta / max : 0;
+ if (hsb.s !== 0) {
+ if (rgb.r === max) {
+ hsb.h = (rgb.g - rgb.b) / delta;
+ } else if (rgb.g === max) {
+ hsb.h = 2 + (rgb.b - rgb.r) / delta;
+ } else {
+ hsb.h = 4 + (rgb.r - rgb.g) / delta;
+ }
+ } else {
+ hsb.h = -1;
+ }
+ hsb.h *= 60;
+ if (hsb.h < 0) {
+ hsb.h += 360;
+ }
+ hsb.s *= 100 / 255;
+ hsb.b *= 100 / 255;
+ return hsb;
+ };
+ const _HSBToRGB = function (hsb) {
+ var rgb = {};
+ var h = Math.round(hsb.h);
+ var s = Math.round(hsb.s * 255 / 100);
+ var v = Math.round(hsb.b * 255 / 100);
+ if (s === 0) {
+ rgb.r = rgb.g = rgb.b = v;
+ } else {
+ var t1 = v;
+ var t2 = (255 - s) * v / 255;
+ var t3 = (t1 - t2) * (h % 60) / 60;
+ if (h === 360) {
+ h = 0;
+ }
+ if (h < 60) {
+ rgb.r = t1;
+ rgb.b = t2;
+ rgb.g = t2 + t3;
+ } else if (h < 120) {
+ rgb.g = t1;
+ rgb.b = t2;
+ rgb.r = t1 - t3;
+ } else if (h < 180) {
+ rgb.g = t1;
+ rgb.r = t2;
+ rgb.b = t2 + t3;
+ } else if (h < 240) {
+ rgb.b = t1;
+ rgb.r = t2;
+ rgb.g = t1 - t3;
+ } else if (h < 300) {
+ rgb.b = t1;
+ rgb.g = t2;
+ rgb.r = t2 + t3;
+ } else if (h < 360) {
+ rgb.r = t1;
+ rgb.g = t2;
+ rgb.b = t1 - t3;
+ } else {
+ rgb.r = 0;
+ rgb.g = 0;
+ rgb.b = 0;
+ }
+ }
+ return {r: Math.round(rgb.r), g: Math.round(rgb.g), b: Math.round(rgb.b)};
+ };
+ const _RGBToHex = function (rgb) {
+ var hex = [
+ rgb.r.toString(16),
+ rgb.g.toString(16),
+ rgb.b.toString(16)
+ ];
+ $.each(hex, function (nr, val) {
+ if (val.length === 1) {
+ hex[nr] = '0' + val;
+ }
+ });
+ return hex.join('');
+ };
+ const _HSBToHex = function (hsb) {
+ return _RGBToHex(_HSBToRGB(hsb));
+ };
+ const restoreOriginal = function () {
+ var cal = $(this).parent();
+ var col = cal.data('colorpicker').origColor;
+ cal.data('colorpicker').color = col;
+ fillRGBFields(col, cal.get(0));
+ fillHexFields(col, cal.get(0));
+ fillHSBFields(col, cal.get(0));
+ setSelector(col, cal.get(0));
+ setHue(col, cal.get(0));
+ setNewColor(col, cal.get(0));
+ };
+ return {
+ init: function (opt) {
+ opt = $.extend({}, defaults, opt || {});
+ if (typeof opt.color === 'string') {
+ opt.color = _HexToHSB(opt.color);
+ } else if (opt.color.r !== undefined && opt.color.g !== undefined && opt.color.b !== undefined) {
+ opt.color = _RGBToHSB(opt.color);
+ } else if (opt.color.h !== undefined && opt.color.s !== undefined && opt.color.b !== undefined) {
+ opt.color = fixHSB(opt.color);
+ } else {
+ return this;
+ }
+ return this.each(function () {
+ if (!$(this).data('colorpickerId')) {
+ var options = $.extend({}, opt);
+ options.origColor = opt.color;
+ var id = 'collorpicker_' + parseInt(Math.random() * 1000, 10);
+ $(this).data('colorpickerId', id);
+ var cal = $(tpl).attr('id', id);
+ if (options.flat) {
+ cal.appendTo(this).show();
+ } else {
+ cal.appendTo(document.body);
+ }
+ options.fields = cal
+ .find('input')
+ .bind('keyup', keyDown)
+ .bind('change', change)
+ .bind('blur', blur)
+ .bind('focus', focus);
+ cal
+ .find('span').bind('mousedown', downIncrement).end()
+ .find('>div.colorpicker_current_color').bind('click', restoreOriginal);
+ options.selector = cal.find('div.colorpicker_color').bind('mousedown', downSelector);
+ options.selectorIndic = options.selector.find('div div');
+ options.el = this;
+ options.hue = cal.find('div.colorpicker_hue div');
+ cal.find('div.colorpicker_hue').bind('mousedown', downHue);
+ options.newColor = cal.find('div.colorpicker_new_color');
+ options.currentColor = cal.find('div.colorpicker_current_color');
+ cal.data('colorpicker', options);
+ cal.find('div.colorpicker_submit')
+ .bind('mouseenter', enterSubmit)
+ .bind('mouseleave', leaveSubmit)
+ .bind('click', clickSubmit);
+ fillRGBFields(options.color, cal.get(0));
+ fillHSBFields(options.color, cal.get(0));
+ fillHexFields(options.color, cal.get(0));
+ setHue(options.color, cal.get(0));
+ setSelector(options.color, cal.get(0));
+ setCurrentColor(options.color, cal.get(0));
+ setNewColor(options.color, cal.get(0));
+ if (options.flat) {
+ cal.css({
+ position: 'relative',
+ display: 'block'
+ });
+ } else {
+ $(this).bind(options.eventName, show);
+ }
+ }
+ });
+ },
+ showPicker: function () {
+ return this.each(function () {
+ if ($(this).data('colorpickerId')) {
+ show.apply(this);
+ }
+ });
+ },
+ hidePicker: function () {
+ return this.each(function () {
+ if ($(this).data('colorpickerId')) {
+ $('#' + $(this).data('colorpickerId')).hide();
+ }
+ });
+ },
+ setColor: function (col) {
+ if (typeof col === 'string') {
+ col = _HexToHSB(col);
+ } else if (col.r !== undefined && col.g !== undefined && col.b !== undefined) {
+ col = _RGBToHSB(col);
+ } else if (col.h !== undefined && col.s !== undefined && col.b !== undefined) {
+ col = fixHSB(col);
+ } else {
+ return this;
+ }
+ return this.each(function () {
+ if ($(this).data('colorpickerId')) {
+ var cal = $('#' + $(this).data('colorpickerId'));
+ cal.data('colorpicker').color = col;
+ cal.data('colorpicker').origColor = col;
+ fillRGBFields(col, cal.get(0));
+ fillHSBFields(col, cal.get(0));
+ fillHexFields(col, cal.get(0));
+ setHue(col, cal.get(0));
+ setSelector(col, cal.get(0));
+ setCurrentColor(col, cal.get(0));
+ setNewColor(col, cal.get(0));
+ }
+ });
+ }
+ };
+ }();
+ $.fn.extend({
+ ColorPicker: ColorPicker.init,
+ ColorPickerHide: ColorPicker.hidePicker,
+ ColorPickerShow: ColorPicker.showPicker,
+ ColorPickerSetColor: ColorPicker.setColor
+ });
+})($);
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/colorpicker.scss b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/colorpicker.scss
new file mode 100644
index 0000000000..f420d520ea
--- /dev/null
+++ b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/colorpicker.scss
@@ -0,0 +1,163 @@
+$colorPickerImagesPath: './images/' !default;
+
+.colorpicker {
+ width: 356px;
+ height: 176px;
+ overflow: hidden;
+ position: absolute;
+ background: url('#{$colorPickerImagesPath}colorpicker_background.png');
+ font-family: Arial, Helvetica, sans-serif;
+ display: none;
+}
+.colorpicker_color {
+ width: 150px;
+ height: 150px;
+ left: 14px;
+ top: 13px;
+ position: absolute;
+ background: #f00;
+ overflow: hidden;
+ cursor: crosshair;
+}
+.colorpicker_color div {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 150px;
+ height: 150px;
+ background: url('#{$colorPickerImagesPath}colorpicker_overlay.png');
+}
+.colorpicker_color div div {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 11px;
+ height: 11px;
+ overflow: hidden;
+ background: url('#{$colorPickerImagesPath}colorpicker_select.gif');
+ margin: -5px 0 0 -5px;
+}
+.colorpicker_hue {
+ position: absolute;
+ top: 13px;
+ left: 171px;
+ width: 35px;
+ height: 150px;
+ cursor: n-resize;
+}
+.colorpicker_hue div {
+ position: absolute;
+ width: 35px;
+ height: 9px;
+ overflow: hidden;
+ background: url('#{$colorPickerImagesPath}colorpicker_indic.gif') left top;
+ margin: -4px 0 0 0;
+ left: 0px;
+}
+.colorpicker_new_color {
+ position: absolute;
+ width: 60px;
+ height: 30px;
+ left: 213px;
+ top: 13px;
+ background: #f00;
+}
+.colorpicker_current_color {
+ position: absolute;
+ width: 60px;
+ height: 30px;
+ left: 283px;
+ top: 13px;
+ background: #f00;
+}
+.colorpicker input {
+ background-color: transparent;
+ border: 1px solid transparent;
+ position: absolute;
+ font-size: 10px;
+ font-family: Arial, Helvetica, sans-serif;
+ color: #898989;
+ top: 4px;
+ right: 11px;
+ text-align: right;
+ margin: 0;
+ padding: 0;
+ height: 11px;
+}
+.colorpicker_hex {
+ position: absolute;
+ width: 72px;
+ height: 22px;
+ background: url('#{$colorPickerImagesPath}colorpicker_hex.png') top;
+ left: 212px;
+ top: 142px;
+}
+.colorpicker_hex input {
+ right: 6px;
+}
+.colorpicker_field {
+ height: 22px;
+ width: 62px;
+ background-position: top;
+ position: absolute;
+}
+.colorpicker_field span {
+ position: absolute;
+ width: 12px;
+ height: 22px;
+ overflow: hidden;
+ top: 0;
+ right: 0;
+ cursor: n-resize;
+}
+.colorpicker_rgb_r {
+ background-image: url('#{$colorPickerImagesPath}colorpicker_rgb_r.png');
+ top: 52px;
+ left: 212px;
+}
+.colorpicker_rgb_g {
+ background-image: url('#{$colorPickerImagesPath}colorpicker_rgb_g.png');
+ top: 82px;
+ left: 212px;
+}
+.colorpicker_rgb_b {
+ background-image: url('#{$colorPickerImagesPath}colorpicker_rgb_b.png');
+ top: 112px;
+ left: 212px;
+}
+.colorpicker_hsb_h {
+ background-image: url('#{$colorPickerImagesPath}colorpicker_hsb_h.png');
+ top: 52px;
+ left: 282px;
+}
+.colorpicker_hsb_s {
+ background-image: url('#{$colorPickerImagesPath}colorpicker_hsb_s.png');
+ top: 82px;
+ left: 282px;
+}
+.colorpicker_hsb_b {
+ background-image: url('#{$colorPickerImagesPath}colorpicker_hsb_b.png');
+ top: 112px;
+ left: 282px;
+}
+.colorpicker_submit {
+ position: absolute;
+ width: 22px;
+ height: 22px;
+ background: url('#{$colorPickerImagesPath}colorpicker_submit.png') top;
+ left: 322px;
+ top: 142px;
+ overflow: hidden;
+}
+.colorpicker_focus {
+ background-position: center;
+}
+.colorpicker_hex.colorpicker_focus {
+ background-position: bottom;
+}
+.colorpicker_submit.colorpicker_focus {
+ background-position: bottom;
+}
+.colorpicker_slider {
+ background-position: bottom;
+}
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/Thumbs.db b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/Thumbs.db
new file mode 100644
index 0000000000..d396c36dd8
Binary files /dev/null and b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/Thumbs.db differ
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/blank.gif b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/blank.gif
new file mode 100644
index 0000000000..75b945d255
Binary files /dev/null and b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/blank.gif differ
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_background.png b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_background.png
new file mode 100644
index 0000000000..7e916d5d1f
Binary files /dev/null and b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_background.png differ
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_hex.png b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_hex.png
new file mode 100644
index 0000000000..4e532d7c65
Binary files /dev/null and b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_hex.png differ
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_hsb_b.png b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_hsb_b.png
new file mode 100644
index 0000000000..dfac595d01
Binary files /dev/null and b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_hsb_b.png differ
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_hsb_h.png b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_hsb_h.png
new file mode 100644
index 0000000000..3977ed9f21
Binary files /dev/null and b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_hsb_h.png differ
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_hsb_s.png b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_hsb_s.png
new file mode 100644
index 0000000000..a2a699736c
Binary files /dev/null and b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_hsb_s.png differ
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_indic.gif b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_indic.gif
new file mode 100644
index 0000000000..f9fa95e282
Binary files /dev/null and b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_indic.gif differ
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_overlay.png b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_overlay.png
new file mode 100644
index 0000000000..561cdd9c59
Binary files /dev/null and b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_overlay.png differ
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_rgb_b.png b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_rgb_b.png
new file mode 100644
index 0000000000..dfac595d01
Binary files /dev/null and b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_rgb_b.png differ
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_rgb_g.png b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_rgb_g.png
new file mode 100644
index 0000000000..72b32760a5
Binary files /dev/null and b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_rgb_g.png differ
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_rgb_r.png b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_rgb_r.png
new file mode 100644
index 0000000000..4855fe03f8
Binary files /dev/null and b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_rgb_r.png differ
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_select.gif b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_select.gif
new file mode 100644
index 0000000000..599f7f13a6
Binary files /dev/null and b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_select.gif differ
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_submit.png b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_submit.png
new file mode 100644
index 0000000000..7f4c0825f5
Binary files /dev/null and b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/colorpicker_submit.png differ
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/custom_background.png b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/custom_background.png
new file mode 100644
index 0000000000..cf55ffdd68
Binary files /dev/null and b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/custom_background.png differ
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/custom_hex.png b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/custom_hex.png
new file mode 100644
index 0000000000..888f444495
Binary files /dev/null and b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/custom_hex.png differ
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/custom_hsb_b.png b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/custom_hsb_b.png
new file mode 100644
index 0000000000..2f99dae8e6
Binary files /dev/null and b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/custom_hsb_b.png differ
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/custom_hsb_h.png b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/custom_hsb_h.png
new file mode 100644
index 0000000000..a217e9218e
Binary files /dev/null and b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/custom_hsb_h.png differ
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/custom_hsb_s.png b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/custom_hsb_s.png
new file mode 100644
index 0000000000..7826b41507
Binary files /dev/null and b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/custom_hsb_s.png differ
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/custom_indic.gif b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/custom_indic.gif
new file mode 100644
index 0000000000..222fb94cfd
Binary files /dev/null and b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/custom_indic.gif differ
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/custom_rgb_b.png b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/custom_rgb_b.png
new file mode 100644
index 0000000000..80764e5d6d
Binary files /dev/null and b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/custom_rgb_b.png differ
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/custom_rgb_g.png b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/custom_rgb_g.png
new file mode 100644
index 0000000000..fc9778be1e
Binary files /dev/null and b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/custom_rgb_g.png differ
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/custom_rgb_r.png b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/custom_rgb_r.png
new file mode 100644
index 0000000000..91b0cd4c52
Binary files /dev/null and b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/custom_rgb_r.png differ
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/custom_submit.png b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/custom_submit.png
new file mode 100644
index 0000000000..cd202cd93b
Binary files /dev/null and b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/custom_submit.png differ
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/select.png b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/select.png
new file mode 100644
index 0000000000..21213bfd51
Binary files /dev/null and b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/select.png differ
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/select2.png b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/select2.png
new file mode 100644
index 0000000000..2cd2cabeb6
Binary files /dev/null and b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/select2.png differ
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/slider.png b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/slider.png
new file mode 100644
index 0000000000..8b03da96eb
Binary files /dev/null and b/Phraseanet-production-client/src/components/utils/jquery-plugins/colorpicker/images/slider.png differ
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/highlight.js b/Phraseanet-production-client/src/components/utils/jquery-plugins/highlight.js
new file mode 100644
index 0000000000..c4857f2589
--- /dev/null
+++ b/Phraseanet-production-client/src/components/utils/jquery-plugins/highlight.js
@@ -0,0 +1,21 @@
+import $ from 'jquery';
+(function () {
+ $.fn.extend({
+ highlight: function (color) {
+ if ($(this).hasClass('animating')) {
+ return $(this);
+ }
+ color = typeof color !== 'undefined' ? color : 'red';
+ const oldColor = $(this).css('backgroundColor');
+ return $(this).addClass('animating').stop().animate({
+ backgroundColor: color
+ }, 50, 'linear', function () {
+ $(this).stop().animate({
+ backgroundColor: oldColor
+ }, 450, 'linear', function () {
+ $(this).removeClass('animating');
+ });
+ });
+ }
+ });
+})();
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/imageEnhancer/imageEnhancer.js b/Phraseanet-production-client/src/components/utils/jquery-plugins/imageEnhancer/imageEnhancer.js
new file mode 100644
index 0000000000..325601dcf8
--- /dev/null
+++ b/Phraseanet-production-client/src/components/utils/jquery-plugins/imageEnhancer/imageEnhancer.js
@@ -0,0 +1,234 @@
+require('./imageEnhancer.scss');
+
+import $ from 'jquery';
+(function ($) {
+
+ const methods = {
+ init: function (options) {
+ let settings = {
+ zoomable: false,
+ display_full_screen: false
+ };
+ return this.each(function () {
+
+ let $this = $(this);
+ let data = $(this).data('image_enhance');
+
+ if (!data) {
+ if (options) {
+ $.extend(settings, options);
+ }
+
+ let wrapper = $('.thumb_wrapper', $(this));
+ let $image = $('img', $this);
+ let image_width = parseInt($('input[name="width"]', $this).val(), 10);
+ let image_height = parseInt($('input[name="height"]', $this).val(), 10);
+ let ratio = image_width / image_height;
+
+ wrapper.css('position', 'relative');
+
+ reset_position($this);
+
+ if (settings.display_full_screen) {
+ $image.parent()
+ .append('');
+
+ let $titlebar = $('.image_enhance_titlebar', $this);
+
+ $('.image_enhance_title_bg', $titlebar).css('opacity', 0.5);
+
+ $image.parent()
+ .bind('mouseover.image_enhance', function () {
+ $titlebar.stop().show().animate({
+ height: 28
+ }, 150);
+ })
+ .bind('mouseout.image_enhance', function () {
+ $titlebar.stop().animate({
+ height: 0
+ }, 150, function () {
+ $titlebar.hide();
+ });
+ });
+
+ $('.image_enhance_titlebar .full', wrapper).bind('click.image_enhance', function () {
+ $('body').append('\n\
+ \n\
+
close
\n\
+
\n\
+
');
+
+ let $theatre = $('.image_enhance_theatre');
+ let $theatre_img = $('img', $theatre);
+ $(window).bind('resize.image_enhance dblclick.image_enhance', function (event) {
+
+ if (event.type === 'dblclick') {
+ $theatre_img.removeClass('zoomed');
+ } else {
+ if ($theatre_img.hasClass('zoomed')) {
+ return;
+ }
+ }
+ let datas = calculate_sizes($(this).width(), $(this).height(), image_width, image_height, 80);
+
+ $theatre_img.width(datas.width).height(datas.height).css('top', datas.top).css('left', datas.left);
+ });
+ $(window).trigger('resize.image_enhance');
+ $('.closer', $theatre).bind('click.image_enhance', function () {
+ $theatre.remove();
+ });
+
+ if (typeof $theatre.disableSelection !== 'function' && window.console) {
+ console.error('enhanced image require jquery UI\'s disableSelection');
+ }
+ $('img', $theatre).disableSelection();
+ });
+ }
+
+
+ if (settings.zoomable) {
+ if (typeof $image.draggable !== 'function' && window.console) {
+ console.error('zoomable require jquery UI\'s draggable');
+ }
+
+ if ($image.attr('ondragstart')) {
+ $image.removeAttr('ondragstart');
+ }
+ $image.draggable();
+ $image.css({
+ 'max-width': 'none',
+ 'max-height': 'none'
+ });
+
+ $this.bind('mousewheel', function (event, delta) {
+ $image.addClass('zoomed');
+ if (delta > 0) {
+ event.stopPropagation();
+ zoomPreview(true, ratio, $image, $(this));
+ } else {
+ event.stopPropagation();
+ zoomPreview(false, ratio, $image, $(this));
+ }
+ return false;
+ }).bind('dblclick', function (event) {
+ reset_position($this);
+ });
+ }
+
+ $(this).data('image_enhance', {
+ width: image_width,
+ height: image_height
+ });
+ }
+
+ });
+ },
+ destroy: function () {
+ return this.each(function () {
+ $(this).data('image_enhance', null);
+ $('.image_enhance_titlebar, .image_enhance_theatre', this).remove();
+ });
+ }
+ };
+
+ function zoomPreview(bool, ratio, $img, $container) {
+ if ($img.length === 0) {
+ return;
+ }
+
+ let t1 = parseInt($img.css('top'), 10);
+ let l1 = parseInt($img.css('left'), 10);
+ let w1 = $img.width();
+ let h1 = $img.height();
+
+ let w2;
+
+ if (bool) {
+ if ((w1 * 1.08) < 32767) {
+ w2 = w1 * 1.08;
+ } else {
+ w2 = w1;
+ }
+ } else {
+ if ((w1 / 1.08) > 20) {
+ w2 = w1 / 1.08;
+ } else {
+ w2 = w1;
+ }
+ }
+
+ let h2 = Math.round(w2 / ratio);
+ w2 = Math.round(w2);
+
+ let wPreview = $container.width() / 2;
+ let hPreview = $container.height() / 2;
+
+ let nt = Math.round((h2 / h1) * (t1 - hPreview) + hPreview);
+ let nl = Math.round(((w2 / w1) * (l1 - wPreview)) + wPreview);
+
+ $img.css({
+ left: nl,
+ top: nt
+ }).width(w2).height(h2);
+ }
+
+ function calculate_sizes(window_width, window_height, image_width, image_height, border) {
+ if (typeof border !== 'number') {
+ border = 0;
+ }
+
+ let width;
+ let height;
+ let ratio_display = window_width / window_height;
+ let ratio_image = image_width / image_height;
+
+ if (ratio_image > ratio_display) {
+ width = window_width - border;
+ height = Math.round(width / ratio_image);
+ } else {
+ height = window_height - border;
+ width = Math.round(height * ratio_image);
+ }
+
+ let top = Math.round((window_height - height) / 2);
+ let left = Math.round((window_width - width) / 2);
+
+ return {
+ top: top,
+ left: left,
+ width: width,
+ height: height
+ };
+ }
+
+ function reset_position($this) {
+ let display_width = $this.width();
+ let display_height = $this.height();
+ let image_width = parseInt($('input[name="width"]', $this).val(), 10);
+ let image_height = parseInt($('input[name="height"]', $this).val(), 10);
+
+ let datas = calculate_sizes(display_width, display_height, image_width, image_height);
+ let $image = $('img', $this);
+
+ let top = Math.round((display_height - datas.height) / 2) + 'px';
+ let left = Math.round((display_width - datas.width) / 2) + 'px';
+
+ $image.width(datas.width).height(datas.height).css({top: top, left: left});
+ return;
+ }
+
+ $.fn.image_enhance = function (method) {
+
+ if (methods[method]) {
+ return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
+ } else if (typeof method === 'object' || !method) {
+ return methods.init.apply(this, arguments);
+ } else {
+ $.error('Method ' + method + ' does not exist on jQuery.image_enhance');
+ }
+
+
+ };
+})($);
diff --git a/Phraseanet-production-client/src/components/utils/jquery-plugins/imageEnhancer/imageEnhancer.scss b/Phraseanet-production-client/src/components/utils/jquery-plugins/imageEnhancer/imageEnhancer.scss
new file mode 100644
index 0000000000..89c08c3cbf
--- /dev/null
+++ b/Phraseanet-production-client/src/components/utils/jquery-plugins/imageEnhancer/imageEnhancer.scss
@@ -0,0 +1,53 @@
+
+.image_enhance_titlebar {
+ width: 100%;
+ position: absolute;
+ top: 0;
+ height: 0;
+}
+
+.image_enhance_title_options,
+.image_enhance_title_bg {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ top: 0;
+ left: 0;
+ z-index: 800;
+ background-color: black;
+}
+
+.image_enhance_title_options {
+ background-color: transparent;
+ z-index: 900;
+}
+
+.image_enhance_theatre {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: black;
+ z-index: 8000
+}
+
+.image_enhance_theatre_closer_wrapper {
+ position: absolute;
+ top: 10px;
+ right: 10px;
+ z-index: 8200;
+}
+
+.image_enhance_theatre img {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 8100;
+}
+
+.image_enhance_title_options span {
+ margin: 2px 5px;
+ float: right;
+ cursor: pointer;
+}
\ No newline at end of file
diff --git a/Phraseanet-production-client/src/components/utils/selectable.js b/Phraseanet-production-client/src/components/utils/selectable.js
new file mode 100644
index 0000000000..4abc5058b8
--- /dev/null
+++ b/Phraseanet-production-client/src/components/utils/selectable.js
@@ -0,0 +1,217 @@
+import $ from 'jquery';
+import * as Rx from 'rx';
+import * as appCommons from './../../phraseanet-common';
+const Selectable = function (services, $container, options) {
+ const { configService, localeService, appEvents } = services;
+ let defaults = {
+ allow_multiple: false,
+ selector: '',
+ callbackSelection: null,
+ selectStart: null,
+ selectStop: null,
+ limit: null,
+ localeService: localeService
+ };
+ options = typeof options === 'object' ? options : {};
+
+ let $this = this;
+
+ if ($container.data('selectionnable')) {
+ /* this container is already selectionnable */
+ if (window.console) {
+ console.error('Trying to apply new selection to existing one');
+ }
+
+ return $container.data('selectionnable');
+ }
+
+ this.stream = new Rx.Subject();
+ this.$container = $container;
+ this.options = $.extend(defaults, options);
+ this.datas = [];
+
+ this.$container.data('selectionnable', this);
+ this.$container.addClass('selectionnable');
+ this.$container
+ .on('click', this.options.selector, function (event) {
+ event.preventDefault();
+ if (typeof $this.options.selectStart === 'function') {
+ $this.options.selectStart($.extend($.Event('selectStart'), event), $this);
+ }
+
+ let $that = $(this);
+
+ let k = get_value($that, $this);
+
+ if (appCommons.utilsModule.is_shift_key(event) && $('.last_selected', this.$container).filter($this.options.selector).length !== 0) {
+ let lst = $($this.options.selector, this.$container);
+
+ let index1 = $.inArray($('.last_selected', this.$container).filter($this.options.selector)[0], lst);
+ let index2 = $.inArray($that[0], lst);
+
+ if (index2 < index1) {
+ let tmp = index1;
+ index1 = index2 - 1 < 0 ? index2 : index2 - 1;
+ index2 = tmp;
+ }
+
+ let stopped = false;
+
+ if (index2 !== -1 && index1 !== -1) {
+ let exp = $this.options.selector + ':gt(' + index1 + '):lt(' + (index2 - index1) + ')';
+
+ $.each($(exp, this.$container), function (i, n) {
+ if (!$(n).hasClass('selected') && stopped === false) {
+ if (!$this.hasReachLimit()) {
+ let contain = get_value($(n), $this);
+ $this.push(contain);
+ $(n).addClass('selected');
+ } else {
+ alert(localeService.t('max_record_selected'));
+ stopped = true;
+ }
+ }
+ });
+ }
+
+ if ($this.has(k) === false && stopped === false) {
+ if (!$this.hasReachLimit()) {
+ $this.push(k);
+ $that.addClass('selected');
+ } else {
+ alert(localeService.t('max_record_selected'));
+ }
+ }
+ } else {
+ if (!appCommons.utilsModule.is_ctrl_key(event)) {
+ $this.empty().push(k);
+ $('.selected', this.$container).filter($this.options.selector).removeClass('selected');
+ $that.addClass('selected');
+ } else {
+ if ($this.has(k) === true) {
+ $this.remove(k);
+ $that.removeClass('selected');
+ } else {
+ if (!$this.hasReachLimit()) {
+ $this.push(k);
+ $that.addClass('selected');
+ } else {
+ alert(localeService.t('max_record_selected'));
+ }
+ }
+ }
+ }
+
+ $('.last_selected', this.$container).removeClass('last_selected');
+ $that.addClass('last_selected');
+
+ $this.stream.onNext({
+ asArray: $this.datas,
+ serialized: $this.serialize()
+ });
+ if (typeof $this.options.selectStop === 'function') {
+ $this.options.selectStop($.extend($.Event('selectStop'), event), $this);
+ }
+
+ });
+
+ return this;
+};
+
+function get_value(element, Selectable) {
+ if (typeof Selectable.options.callbackSelection === 'function') {
+ return Selectable.options.callbackSelection($(element));
+ } else {
+ return $('input[name="id"]', $(element)).val();
+ }
+}
+
+Selectable.prototype = {
+ push: function (element) {
+ if (this.options.allow_multiple === true || !this.has(element)) {
+ this.datas.push(element);
+ }
+
+ return this;
+ },
+ hasReachLimit: function () {
+ if (this.options.limit !== null && this.options.limit <= this.datas.length) {
+ return true;
+ }
+ return false;
+ },
+ remove: function (element) {
+ this.datas = $.grep(this.datas, function (n) {
+ return (n !== element);
+ });
+
+ return this;
+ },
+ has: function (element) {
+
+ return $.inArray(element, this.datas) >= 0;
+ },
+ get: function () {
+ return this.datas;
+ },
+ empty: function () {
+ const $this = this;
+ this.datas = [];
+
+ $(this.options.selector, this.$container).filter('.selected:visible').removeClass('selected');
+
+ if (typeof $this.options.selectStop === 'function') {
+ $this.options.selectStop($.Event('selectStop'), $this);
+ }
+
+ return this;
+ },
+ length: function () {
+
+ return this.datas.length;
+ },
+ size: function () {
+
+ return this.datas.length;
+ },
+ serialize: function (separator) {
+
+ separator = separator || ';';
+
+ return this.datas.join(separator);
+ },
+ selectAll: function () {
+ this.select('*');
+
+ return this;
+ },
+ select: function (selector) {
+ const $this = this;
+ let stopped = false;
+
+ $(this.options.selector, this.$container).filter(selector).not('.selected').filter(':visible').each(function () {
+ if (!$this.hasReachLimit()) {
+ $this.push(get_value(this, $this));
+ $(this).addClass('selected');
+ } else {
+ if (stopped === false) {
+ alert($this.options.localeService.t('max_record_selected'));
+ }
+ stopped = true;
+ }
+ });
+
+ $this.stream.onNext({
+ asArray: $this.datas,
+ serialized: $this.serialize()
+ });
+
+ if (typeof $this.options.selectStop === 'function') {
+ $this.options.selectStop($.Event('selectStop'), $this);
+ }
+
+ return this;
+ }
+};
+
+export default Selectable;
diff --git a/Phraseanet-production-client/src/components/utils/utils.js b/Phraseanet-production-client/src/components/utils/utils.js
new file mode 100644
index 0000000000..dc54dc4634
--- /dev/null
+++ b/Phraseanet-production-client/src/components/utils/utils.js
@@ -0,0 +1,41 @@
+import * as AppCommons from './../../phraseanet-common';
+
+const entityMap = {
+ '&': '&',
+ '<': '<',
+ '>': '>',
+ '"': '"',
+ '\'': ''',
+ '/': '/'
+};
+const escapeHtml = function (string) {
+ return String(string).replace(/[&<>"'\/]/g, (s) => {
+ return entityMap[s];
+ });
+};
+// @TODO - check legacy code
+const cleanTags = function (string) {
+ let chars2replace = [{
+ f: '&',
+ t: '&'
+ }, {
+ f: '<',
+ t: '<'
+ }, {
+ f: '>',
+ t: '>'
+ }];
+ for (let c in chars2replace) {
+ string = string.replace(RegExp(chars2replace[c].f, 'g'), chars2replace[c].t);
+ }
+ return string;
+};
+
+const generateRandStr = (sLength = 5) => {
+ var s = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ return Array(sLength).join().split(',').map(function () {
+ return s.charAt(Math.floor(Math.random() * s.length));
+ }).join('');
+};
+
+export {escapeHtml, cleanTags, generateRandStr};
diff --git a/Phraseanet-production-client/src/components/videoEditor/canvaImage.js b/Phraseanet-production-client/src/components/videoEditor/canvaImage.js
new file mode 100644
index 0000000000..aabfd5fac8
--- /dev/null
+++ b/Phraseanet-production-client/src/components/videoEditor/canvaImage.js
@@ -0,0 +1,96 @@
+/**
+ * Canva Object
+ * @param domCanva
+ * @constructor
+ */
+const Canva = function (domCanva) {
+ this.domCanva = domCanva;
+};
+
+Canva.prototype = {
+ resize: function (elementDomNode, forceWidth) {
+
+ let w = elementDomNode.getWidth();
+ let h = null;
+ let maxH = elementDomNode.getHeight();
+ let ratio = 1;
+
+ if (elementDomNode.getAspectRatio() !== '') {
+ ratio = parseFloat(elementDomNode.getAspectRatio());
+
+ h = Math.round(w * (1 / ratio));
+
+ if (h < maxH) {
+ h = maxH;
+ w = Math.round(h * ratio);
+ }
+ } else {
+ h = maxH;
+ }
+
+ if (forceWidth !== undefined) {
+ w = parseInt(forceWidth, 10);
+
+ if (elementDomNode.getAspectRatio() !== '') {
+ h = Math.round(w * (1 / ratio));
+ } else {
+ h = maxH;
+ }
+ }
+
+ this.domCanva.setAttribute('width', w);
+ this.domCanva.setAttribute('height', h);
+
+ return this;
+ },
+ getContext2d: function () {
+
+ if (this.domCanva.getContext === undefined) {
+ /* eslint-disable no-undef */
+ return G_vmlCanvasManager
+ .initElement(this.domCanva)
+ .getContext('2d');
+ }
+
+ return this.domCanva.getContext('2d');
+ },
+ extractImage: function () {
+ return this.domCanva.toDataURL('image/png');
+ },
+ reset: function () {
+ const context = this.getContext2d();
+ const w = this.getWidth();
+ const h = this.getHeight();
+
+ context.save();
+ context.setTransform(1, 0, 0, 1, 0, 0);
+ context.clearRect(0, 0, w, h);
+ context.restore();
+
+ return this;
+ },
+ copy: function (elementDomNode) {
+ const context = this.getContext2d();
+
+ context.drawImage(
+ elementDomNode.getDomElement()
+ , 0
+ , 0
+ , this.getWidth()
+ , this.getHeight()
+ );
+
+ return this;
+ },
+ getDomElement: function () {
+ return this.domCanva;
+ },
+ getHeight: function () {
+ return this.domCanva.offsetHeight;
+ },
+ getWidth: function () {
+ return this.domCanva.offsetWidth;
+ }
+};
+
+export default Canva;
diff --git a/Phraseanet-production-client/src/components/videoEditor/index.js b/Phraseanet-production-client/src/components/videoEditor/index.js
new file mode 100644
index 0000000000..625fbb1a75
--- /dev/null
+++ b/Phraseanet-production-client/src/components/videoEditor/index.js
@@ -0,0 +1,329 @@
+/**
+ * Canva Object
+ * @param domCanva
+ * @constructor
+ */
+const Canva = function (domCanva) {
+ this.domCanva = domCanva;
+};
+
+Canva.prototype = {
+ resize: function (elementDomNode, forceWidth) {
+
+ let w = elementDomNode.getWidth();
+ let h = null;
+ let maxH = elementDomNode.getHeight();
+ let ratio = 1;
+
+ if (elementDomNode.getAspectRatio() !== '') {
+ ratio = parseFloat(elementDomNode.getAspectRatio());
+
+ h = Math.round(w * (1 / ratio));
+
+ if (h > maxH) {
+ h = maxH;
+ w = Math.round(h * ratio);
+ }
+ } else {
+ h = maxH;
+ }
+
+ if (forceWidth !== undefined) {
+ w = parseInt(forceWidth, 10);
+
+ if (elementDomNode.getAspectRatio() !== '') {
+ h = Math.round(w * (1 / ratio));
+ } else {
+ h = maxH;
+ }
+ }
+
+ this.domCanva.setAttribute('width', w);
+ this.domCanva.setAttribute('height', h);
+
+ return this;
+ },
+ getContext2d: function () {
+
+ if (this.domCanva.getContext === undefined) {
+ /* eslint-disable no-undef */
+ return G_vmlCanvasManager
+ .initElement(this.domCanva)
+ .getContext('2d');
+ }
+
+ return this.domCanva.getContext('2d');
+ },
+ extractImage: function () {
+ return this.domCanva.toDataURL('image/png');
+ },
+ reset: function () {
+ const context = this.getContext2d();
+ const w = this.getWidth();
+ const h = this.getHeight();
+
+ context.save();
+ context.setTransform(1, 0, 0, 1, 0, 0);
+ context.clearRect(0, 0, w, h);
+ context.restore();
+
+ return this;
+ },
+ copy: function (elementDomNode) {
+ const context = this.getContext2d();
+
+ context.drawImage(
+ elementDomNode.getDomElement()
+ , 0
+ , 0
+ , this.getWidth()
+ , this.getHeight()
+ );
+
+ return this;
+ },
+ getDomElement: function () {
+ return this.domCanva;
+ },
+ getHeight: function () {
+ return this.domCanva.offsetHeight;
+ },
+ getWidth: function () {
+ return this.domCanva.offsetWidth;
+ }
+};
+
+
+/**
+ * Image Object
+ * @param domElement
+ * @constructor
+ */
+const Image = function (domElement) {
+ this.domElement = domElement;
+};
+
+Image.prototype = {
+ getDomElement: function () {
+ return this.domElement;
+ },
+ getHeight: function () {
+ return this.domElement.offsetHeight;
+ },
+ getWidth: function () {
+ return this.domElement.offsetWidth;
+ }
+};
+
+/**
+ * Video Object inherits from Image object
+ * @param domElement
+ * @constructor
+ */
+const Video = function (domElement) {
+ Image.call(this, domElement);
+ this.aspectRatio = domElement.getAttribute('data-ratio');
+};
+
+Video.prototype = new Image();
+Video.prototype.constructor = Video;
+Video.prototype.getCurrentTime = function () {
+ return Math.floor(this.domElement.currentTime);
+};
+Video.prototype.getAspectRatio = function () {
+ return this.aspectRatio;
+};
+
+/**
+ * Cache Object
+ * @constructor
+ */
+const Store = function () {
+ this.datas = {};
+};
+
+Store.prototype = {
+ set: function (id, item) {
+ this.datas[id] = item;
+ return this;
+ },
+ get: function (id) {
+ if (!this.datas[id]) {
+ throw 'Unknown ID';
+ }
+ return this.datas[id];
+ },
+ remove: function (id) {
+ // never reuse same id
+ this.datas[id] = null;
+ },
+ getLength: function () {
+ let count = 0;
+ for (let k in this.datas) {
+ if (this.datas.hasOwnProperty(k)) {
+ ++count;
+ }
+ }
+ return count;
+ }
+};
+
+/**
+ * Screenshot Object
+ * @param id
+ * @param canva
+ * @param video
+ * @param altCanvas
+ * @constructor
+ */
+const ScreenShot = function (id, canva, video, altCanvas) {
+
+ const date = new Date();
+ canva.resize(video);
+ canva.copy(video);
+
+ // handle alternative canvas:
+ altCanvas = altCanvas === undefined ? [] : altCanvas;
+ this.altScreenShots = [];
+ if (altCanvas.length > 0) {
+ for (let i = 0; i < altCanvas.length; i++) {
+ let canvaEl = altCanvas[i].el;
+ canvaEl.resize(video, altCanvas[i].width);
+ canvaEl.copy(video);
+
+ this.altScreenShots.push({
+ dataURI: canvaEl.extractImage(),
+ name: altCanvas[i].name
+ });
+ }
+ }
+
+ this.id = id;
+ this.timestamp = date.getTime();
+ this.dataURI = canva.extractImage();
+ this.videoTime = video.getCurrentTime();
+
+};
+
+ScreenShot.prototype = {
+ getId: function () {
+ return this.id;
+ },
+ getDataURI: function () {
+ return this.dataURI;
+ },
+ getTimeStamp: function () {
+ return this.timestamp;
+ },
+ getVideoTime: function () {
+ return this.videoTime;
+ },
+ getAltScreenShots: function () {
+ return this.altScreenShots;
+ }
+};
+
+/**
+ * THUMB EDITOR
+ * @param videoId
+ * @param canvaId
+ * @param outputOptions
+ * @returns {{isSupported: isSupported, screenshot: screenshot, store: Store, copy: copy, getCanvaImage: getCanvaImage, resetCanva: resetCanva, getNbScreenshot: getNbScreenshot}}
+ * @constructor
+ */
+const VideoEditor = function (videoId, canvaId, outputOptions) {
+ let editorVideo;
+ const domElement = document.getElementById(videoId);
+
+ if (domElement !== null) {
+ editorVideo = new Video(domElement);
+ }
+ const store = new Store();
+
+ function getCanva() {
+ return document.getElementById(canvaId);
+ }
+
+ outputOptions = outputOptions || {};
+
+ function setAltCanvas() {
+ let domElements = [];
+ let altCanvas = outputOptions.altCanvas;
+ if (altCanvas.length > 0) {
+ for (let i = 0; i < altCanvas.length; i++) {
+ domElements.push({
+ el: new Canva(altCanvas[i]),
+ width: altCanvas[i].getAttribute('data-width'),
+ name: altCanvas[i].getAttribute('data-name')
+ });
+ }
+ }
+ return domElements;
+ }
+
+ return {
+ isSupported: function () {
+ const elem = document.createElement('canvas');
+
+ return !!document.getElementById(videoId) && document.getElementById(canvaId)
+ && !!elem.getContext && !!elem.getContext('2d');
+ },
+ screenshot: function () {
+ const screenshot = new ScreenShot(
+ store.getLength() + 1,
+ new Canva(getCanva()),
+ editorVideo,
+ setAltCanvas()
+ );
+
+ store.set(screenshot.getId(), screenshot);
+
+ return screenshot;
+ },
+ store: store,
+ copy: function (mainSource, altSources) {
+
+ const elementDomNode = document.createElement('img');
+ elementDomNode.src = mainSource;
+
+ const element = new Image(elementDomNode);
+ const editorCanva = new Canva(getCanva());
+ const altEditorCanva = setAltCanvas();
+ editorCanva
+ .reset()
+ .resize(editorVideo)
+ .copy(element);
+
+
+ // handle alternative canvas:
+ if (altEditorCanva.length > 0) {
+ for (let i = 0; i < altEditorCanva.length; i++) {
+
+ let tmpEl = document.createElement('img');
+ tmpEl.src = altSources[i].dataURI;
+
+ const canvaEl = altEditorCanva[i].el;
+
+ canvaEl
+ .reset()
+ .resize(editorVideo, altEditorCanva[i].width)
+ .copy(new Image(tmpEl)); // @TODO: should copy the right stored image
+ }
+ }
+ },
+ getCanvaImage: function () {
+ const canva = new Canva(getCanva());
+
+ return canva.extractImage();
+ },
+ resetCanva: function () {
+ const editorCanva = new Canva(getCanva());
+ editorCanva.reset();
+ },
+ getNbScreenshot: function () {
+ return store.getLength();
+ }
+ };
+};
+
+export default VideoEditor;
diff --git a/Phraseanet-production-client/src/components/videoEditor/rangeCapture.js b/Phraseanet-production-client/src/components/videoEditor/rangeCapture.js
new file mode 100644
index 0000000000..475ca15141
--- /dev/null
+++ b/Phraseanet-production-client/src/components/videoEditor/rangeCapture.js
@@ -0,0 +1,93 @@
+import _ from 'underscore';
+import $ from 'jquery';
+import rangeCapturePlugin from './rangeCapturePlugin/index';
+let hotkeys = require('videojs-hotkeys');
+import videojs from 'video.js';
+// require('video.js').default;
+
+const rangeCapture = (services, datas, activeTab = false) => {
+ const {configService, localeService, appEvents} = services;
+ let $container = null;
+ let initData = {};
+ let options = {};
+ let defaultOptions = {
+ playbackRates: [],
+ fluid: true,
+ controlBar: {
+ muteToggle: false
+ },
+ baseUrl: configService.get('baseUrl')
+ };
+ let videoPlayer;
+ const initialize = (params, userOptions) => {
+ //{$container} = params;
+ $container = params.$container;
+ initData = params.data;
+ options = _.extend(defaultOptions, userOptions, {$container: $container});
+ dispose();
+ render(initData);
+ }
+
+ const render = (initData) => {
+ let record = initData.records[0];
+ if (record.type !== 'video') {
+ return;
+ }
+ options.frameRates = {};
+ options.ratios = {};
+ const coverUrl = '';
+ let generateSourcesTpl = (record) => {
+ let recordSources = [];
+ _.each(record.sources, (s, i) => {
+ recordSources.push(``)
+ options.frameRates[s.src] = s.framerate;
+ options.ratios[s.src] = s.ratio;
+ });
+
+ return recordSources.join(' ');
+ };
+
+ let sources = generateSourcesTpl(record);
+ $container.append(
+ `${sources} `);
+
+ // window.videojs = videojs;
+ videojs.addLanguage(localeService.getLocale(), localeService.getTranslations());
+ videoPlayer = videojs('embed-video', options, () => {
+ });
+ //group video elements together
+ videoPlayer.rangeCapturePlugin(options);
+ $(videoPlayer.el_).children().not('.range-item-container').wrapAll('
');
+ videoPlayer.ready(() => {
+ let hotkeyOptions = _.extend({
+ alwaysCaptureHotkeys: true,
+ enableNumbers: false,
+ enableVolumeScroll: false,
+ volumeStep: 0.1,
+ seekStep: 1,
+ customKeys: videoPlayer.getRangeCaptureHotkeys()
+ }, videoPlayer.getRangeCaptureOverridedHotkeys());
+
+ videoPlayer.hotkeys(hotkeyOptions);
+ });
+
+ };
+
+ const dispose = () => {
+ try {
+ if (videojs.getPlayers()['embed-video']) {
+ delete videojs.getPlayers()['embed-video'];
+ }
+ } catch (e) {
+ }
+ };
+
+ const getPlayer = () => {
+ return videoPlayer;
+ };
+
+ return {initialize, getPlayer}
+}
+
+export default rangeCapture;
diff --git a/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/hotkeys.js b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/hotkeys.js
new file mode 100644
index 0000000000..f87d606827
--- /dev/null
+++ b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/hotkeys.js
@@ -0,0 +1,243 @@
+import * as Rx from 'rx';
+
+const overrideHotkeys = (settings) => {
+ // override existing keys
+ return {
+ volumeUpKey: function (event, player) {
+ // disable existing one
+ return false;
+ },
+ volumeDownKey: function (event, player) {
+ // disable existing one
+ return false;
+ },
+ rewindKey: function (event, player) {
+ // disable existing one
+ return false;
+ },
+ forwardKey: function (event, player) {
+ // disable existing one
+ return false;
+ },
+ }
+};
+
+const tapSequenceHotKey = (keyStream, eventKey) => {
+
+ return keyStream
+ .filter(function (e) {
+ if (e.which === eventKey) {
+ return true;
+ }
+ return false;
+ })
+ .buffer(function () {
+ return keyStream.debounce(250);
+ })
+ .map(function (list) {
+ return list.length;
+ })
+ .filter(function (x) {
+ return x >= 1;
+ });
+
+}
+
+const hotkeys = (player, settings) => {
+
+ let keyStream = Rx.Observable.fromEvent(settings.$container.get(0), 'keyup');
+ let rates = settings.playbackRates;
+
+ // L key speed 1x 2x 3x ...
+ tapSequenceHotKey(keyStream, 76)
+ .subscribe(function (numclicks) {
+ let rate = rates[numclicks - 1];
+ if (rate !== undefined) {
+ player.playbackRate(rate);
+ }
+ });
+
+ let hotkeys = {
+ rewindKey: {
+ key: function (e) {
+ // Backward Arrow Key
+ return (!e.ctrlKey && e.which === 37);
+ },
+ handler: (player, options) => {
+ player.rangeControlBar.setPreviousFrame(parseInt(settings.seekBackwardStep, 10) / 1000)
+ }
+ },
+ forwardKey: {
+ key: function (e) {
+ // forward Arrow Key
+ return (!e.ctrlKey && e.which === 39);
+ },
+ handler: (player, options) => {
+ player.rangeControlBar.setNextFrame(parseInt(settings.seekForwardStep, 10) / 1000)
+ }
+ },
+ rewindFrameKey: {
+ key: function (e) {
+ // Backward Arrow Key
+ return (e.ctrlKey && e.which === 37);
+ },
+ handler: (player, options) => {
+ player.rangeControlBar.setPreviousFrame()
+ }
+ },
+ forwardFrameKey: {
+ key: function (e) {
+ // forward Arrow Key
+ return (e.ctrlKey && e.which === 39);
+ },
+ handler: (player, options) => {
+ player.rangeControlBar.setNextFrame()
+ }
+ },
+ playOnlyKey: {
+ key: function (e) {
+ // L Key
+ return (!e.ctrlKey && e.which === 76);
+ },
+ handler: (player, options) => {
+ if (player.paused()) {
+ player.play();
+ }
+ }
+ },
+ pauseOnlyKey: {
+ key: function (e) {
+ // K Key
+ return (e.which === 75);
+ },
+ handler: (player, options) => {
+ if (!player.paused()) {
+ player.pause();
+ }
+ }
+ },
+ frameBackward: {
+ key: function (e) {
+ // < Key
+ return (e.which === 188);
+ },
+ handler: function (player, options) {
+ player.rangeControlBar.setPreviousFrame()
+ }
+ },
+ frameForward: {
+ key: function (e) {
+ // MAJ + < = > Key
+ return (e.which === 190);
+ },
+ handler: function (player, options) {
+ player.rangeControlBar.setNextFrame()
+ }
+ },
+ moveDownRange: {
+ key: function (e) {
+ // K Key
+ return (e.which === 40);
+ },
+ handler: (player, options) => {
+ player.rangeCollection.setActiveRange('down');
+ }
+ },
+ moveUpRange: {
+ key: function (e) {
+ // K Key
+ return (e.which === 38);
+ },
+ handler: (player, options) => {
+ player.rangeCollection.setActiveRange('up');
+ }
+ },
+ entryCuePoint: {
+ key: function (e) {
+ // I Key
+ return (!e.shiftKey && e.which === 73);
+ },
+ handler: function (player, options) {
+ player.rangeStream.onNext({
+ action: 'update',
+ range: player.rangeControlBar.setStartPositon()
+ });
+ }
+ },
+ endCuePoint: {
+ key: function (e) {
+ // O Key
+ return (!e.shiftKey && e.which === 79);
+ },
+ handler: function (player, options) {
+ player.rangeStream.onNext({
+ action: 'update',
+ range: player.rangeControlBar.setEndPosition()
+ });
+ }
+ },
+ PlayAtEntryCuePoint: {
+ key: function (e) {
+ // I Key
+ return (e.shiftKey && e.which === 73);
+ },
+ handler: function (player, options) {
+ if (!player.paused()) {
+ player.pause();
+ }
+ player.currentTime(player.rangeControlBar.getStartPosition())
+ }
+ },
+ PlayAtEndCuePoint: {
+ key: function (e) {
+ // O Key
+ return (e.shiftKey && e.which === 79);
+ },
+ handler: function (player, options) {
+ if (!player.paused()) {
+ player.pause();
+ }
+ player.currentTime(player.rangeControlBar.getEndPosition())
+ }
+ },
+ toggleLoop: {
+ key: function (e) {
+ // ctrl+ L Key
+ return (e.ctrlKey && e.which === 76);
+ },
+ handler: function (player, options) {
+ player.rangeControlBar.toggleLoop();
+ }
+ },
+ addRange: {
+ key: function (e) {
+ // ctrl + N or shift + "+"
+ return (e.ctrlKey && e.which === 78 || e.shiftKey && e.which === 107);
+ },
+ handler: (player, options) => {
+ player.rangeControlBar.setNextFrame(parseInt(settings.seekForwardStep, 10) / 1000)
+ let newRange = player.rangeCollection.addRange({});
+ player.rangeStream.onNext({
+ action: 'create',
+ range: newRange
+ })
+
+ }
+ },
+ deleteRange: {
+ key: function (e) {
+ // MAJ+SUPPR Key
+ return (e.shiftKey && e.which === 46);
+ },
+ handler: function (player, options) {
+ player.rangeStream.onNext({
+ action: 'remove'
+ });
+ }
+ }
+ }
+
+ return hotkeys;
+}
+
+export {overrideHotkeys, hotkeys};
diff --git a/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/hotkeysModal.js b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/hotkeysModal.js
new file mode 100644
index 0000000000..08e5a7b68e
--- /dev/null
+++ b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/hotkeysModal.js
@@ -0,0 +1,48 @@
+import videojs from 'video.js';
+/**
+ * VideoJs Hotkeys Modal
+ */
+
+const ModalDialog = videojs.getComponent('ModalDialog');
+
+class HotkeyModal extends ModalDialog {
+
+
+ constructor(player, settings) {
+ super(player, settings);
+ }
+
+ modalTemplate = () => {
+ return ``;
+ }
+
+ initialize() {
+ let domTpl = document.createElement('div');
+ domTpl.innerHTML = this.modalTemplate();
+ this.fillWith(domTpl)
+
+ }
+}
+
+videojs.registerComponent('HotkeyModal', HotkeyModal);
+
+export default HotkeyModal;
diff --git a/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/hotkeysModalButton.js b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/hotkeysModalButton.js
new file mode 100644
index 0000000000..0a9682eefb
--- /dev/null
+++ b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/hotkeysModalButton.js
@@ -0,0 +1,53 @@
+import $ from 'jquery';
+import videojs from 'video.js';
+const Button = videojs.getComponent('Button');
+const Component = videojs.getComponent('Component');
+import HotkeyModal from './hotkeysModal';
+
+class HotkeysModalButton extends Button {
+
+ constructor(player, settings) {
+ super(player, settings);
+ this.settings = settings;
+ }
+
+ /**
+ * Allow sub components to stack CSS class names
+ *
+ * @return {String} The constructed class name
+ * @method buildCSSClass
+ */
+ buildCSSClass() {
+ return 'vjs-hotkeys-modal-button vjs-button';
+ }
+
+ createEl(tag = 'button', props = {}, attributes = {}) {
+ let el = super.createEl(tag, props, attributes);
+ el.innerHTML = ' ';
+ return el;
+ }
+
+ /**
+ * Handles click for keyboard shortcuts modal
+ *
+ * @method handleClick
+ */
+ handleClick() {
+ this.hotkeysModal = this.player_.addChild('HotkeyModal', this.settings);
+ this.hotkeysModal.initialize();
+ this.hotkeysModal.open();
+ this.hotkeysModal.on('beforemodalclose', () => {
+ $(this.el()).show();
+ });
+ $(this.el()).hide();
+ }
+
+}
+
+// HotkeysModalButton.prototype.controlText_ = `
+//
+//
+// `;
+
+Component.registerComponent('HotkeysModalButton', HotkeysModalButton);
+export default HotkeysModalButton;
diff --git a/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/index.js b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/index.js
new file mode 100644
index 0000000000..7abbf35ee6
--- /dev/null
+++ b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/index.js
@@ -0,0 +1,365 @@
+/* eslint-disable quotes */
+require('./style/main.scss');
+import $ from 'jquery';
+import * as Rx from 'rx';
+import videojs from 'video.js';
+import HotkeyModal from './hotkeysModal';
+import HotkeysModalButton from './hotkeysModalButton';
+import RangeBarCollection from './rangeBarCollection';
+import RangeCollection from './rangeCollection';
+import RangeControlBar from './rangeControlBar';
+import {WebVTT} from 'videojs-vtt.js';
+import {overrideHotkeys, hotkeys} from './hotkeys';
+import RangeItemContainer from './rangeItemContainer';
+import * as appCommons from './../../../phraseanet-common';
+
+// import rangeControls from './oldControlBar';
+
+const icons = `
+
+
+
+loop-range
+
+
+
+
+
+
+prev-forward-frame
+
+
+
+
+
+next-forward-frame
+
+
+
+
+
+prev-frame
+
+
+
+
+next-frame
+
+
+
+
+cue-start
+
+
+
+cue-end
+
+
+
+trash
+
+
+
+
+
+`;
+
+const defaults = {
+ seekBackwardStep: 1000,
+ seekForwardStep: 1000,
+ align: 'top-left',
+ class: '',
+ content: 'This overlay will show up while the video is playing',
+ debug: false,
+ overlays: [{
+ start: 'playing',
+ end: 'paused'
+ }]
+};
+
+const Component = videojs.getComponent('Component');
+
+const plugin = function (options) {
+ const settings = videojs.mergeOptions(defaults, options);
+ this.looping = false;
+ this.loopData = [];
+ this.activeRange = {};
+ this.activeRangeStream = new Rx.Subject(); //new Rx.Observable.ofObjectChanges(this.activeRange);
+ this.rangeStream = new Rx.Subject();
+ this.rangeBarCollection = this.controlBar.getChild('progressControl').getChild('seekBar').addChild('RangeBarCollection', settings);
+ this.rangeControlBar = this.addChild('RangeControlBar', settings);
+ this.rangeItemContainer = this.addChild('RangeItemContainer', settings);
+ this.rangeCollection = this.rangeItemContainer.getChild('RangeCollection');
+
+ this.hotkeysModalButton = this.addChild('HotkeysModalButton', settings);
+
+ $(this.el()).prepend(icons);
+
+ this.setEditorWidth = () => {
+ let editorWidth = this.currentWidth();
+
+ if (editorWidth < 672) {
+ $(this.el()).addClass('vjs-mini-screen');
+ } else {
+ $(this.el()).removeClass('vjs-mini-screen');
+ }
+ }
+
+ this.setEditorHeight = () => {
+ // gather components sizes
+ let editorHeight = this.currentHeight() + $(this.rangeControlBar.el()).height() + $(this.rangeCollection.el()).height();
+
+ if (editorHeight > 0) {
+ options.$container.height(editorHeight + 'px');
+ }
+ }
+ // range actions:
+ this.rangeStream.subscribe((params) => {
+ params.handle = params.handle || false;
+ console.log('RANGE EVENT ===========', params.action, '========>>>')
+ switch (params.action) {
+ case 'initialize':
+ this.rangeCollection.update(params.range);
+ break;
+ case 'select':
+ case 'change':
+ params.range = this.shouldTakeSnapShot(params.range, false);
+ this.activeRange = this.rangeCollection.update(params.range);
+
+ this.activeRangeStream.onNext({
+ activeRange: this.activeRange
+ });
+
+ this.rangeBarCollection.refreshRangeSliderPosition(this.activeRange);
+ this.rangeControlBar.refreshRangePosition(this.activeRange, params.handle);
+ setTimeout(() => {
+ this.rangeControlBar.setRangePositonToBeginning(params.range);
+ }, 300);
+ break;
+ // flow through update:
+ case 'create':
+ case 'update':
+ params.range = this.shouldTakeSnapShot(params.range, false);
+ this.activeRange = this.rangeCollection.update(params.range);
+
+ this.activeRangeStream.onNext({
+ activeRange: this.activeRange
+ });
+
+ this.rangeBarCollection.refreshRangeSliderPosition(this.activeRange);
+ this.rangeControlBar.refreshRangePosition(this.activeRange, params.handle);
+ break;
+ case 'remove':
+ // if a range is specified remove it from collection:
+ if (params.range !== undefined) {
+ this.rangeCollection.remove(params.range);
+ if (params.range.id === this.activeRange.id) {
+ // remove from controls components too if active:
+ this.rangeBarCollection.removeActiveRange();
+ this.rangeControlBar.removeActiveRange();
+ }
+ } else {
+ this.rangeBarCollection.removeActiveRange();
+ this.rangeControlBar.removeActiveRange();
+ this.rangeCollection.remove(this.activeRange);
+ }
+
+ break;
+ case 'drag-update':
+ // if changes come from range bar
+ this.rangeControlBar.refreshRangePosition(params.range, params.handle);
+ this.rangeCollection.updatingByDragging(params.range);
+
+ // setting currentTime may take some additionnal time,
+ // so let's wait:
+ setTimeout(() => {
+ if (params.handle === 'start') {
+ params.range = this.shouldTakeSnapShot(params.range, false);
+ this.rangeCollection.update(params.range);
+ }
+ }, 900);
+ break;
+ case 'export-ranges':
+ break;
+ case 'export-vtt-ranges':
+ this.rangeCollection.exportRangesData(params.data);
+ break;
+ case 'resize':
+ this.setEditorWidth();
+ break;
+ case 'saveRangeCollectionPref':
+ this.saveRangeCollectionPref(params.data);
+ break;
+ case 'capture':
+ // if a range is specified remove it from collection:
+ if (params.range !== undefined) {
+ params.range = this.shouldTakeSnapShot(params.range, true);
+ this.rangeCollection.update(params.range);
+ }
+ break;
+ default:
+ }
+ console.log('<<< =================== RANGE EVENT COMPLETE')
+
+ });
+
+ this.shouldTakeSnapShot = (range, atCurrentPosition) => {
+ if(atCurrentPosition) {
+ this.takeSnapshot(range);
+ range.manualSnapShot = true;
+ return range;
+ }
+ else if (Math.round(range.startPosition) == Math.round(this.currentTime()) && !range.manualSnapShot) {
+ this.takeSnapshot(range);
+ return range;
+ } else {
+ return range;
+ }
+ }
+
+ this.takeSnapshot = (range) => {
+ let video = this.el().querySelector('video');
+ let canvas = document.createElement('canvas');
+ let ratio = settings.ratios[this.cache_.src];
+ canvas.width = 50 * ratio;
+ canvas.height = 50;
+ let context = canvas.getContext('2d');
+
+ context.fillRect(0, 0, canvas.width, canvas.height);
+ context.drawImage(video, 0, 0, canvas.width, canvas.height);
+
+ let dataURI = canvas.toDataURL('image/jpeg');
+
+ range.image = {
+ src: dataURI,
+ ratio: settings.ratios[this.cache_.src],
+ width: canvas.width,
+ height: canvas.height
+ }
+
+ return range;
+ }
+
+ this.setVTT = () => {
+ if (settings.vttFieldValue !== false) {
+ // reset existing collection
+ this.rangeCollection.reset([])
+
+ // prefill chapters with vtt data
+ let parser = new WebVTT.Parser(window,
+ window.vttjs,
+ WebVTT.StringDecoder());
+
+ let errors = [];
+
+ parser.oncue = (cue) => {
+
+ // try to parse text:
+ let parsedCue = false;
+ try {
+ parsedCue = JSON.parse(cue.text || '{}');
+
+ } catch (e) {
+ console.error('failed to parse cue text', e)
+ }
+ if (parsedCue === false) {
+ parsedCue = {
+ title: cue.text
+ }
+ }
+
+ let newRange = this.rangeCollection.addRange({
+ startPosition: cue.startTime,
+ endPosition: cue.endTime,
+ title: parsedCue.title,
+ image: {
+ src: parsedCue.image || ''
+ },
+ manualSnapShot: parsedCue.manualSnapShot
+
+ });
+
+ this.rangeStream.onNext({
+ action: 'initialize',
+ range: newRange
+ })
+ };
+
+ parser.onparsingerror = function (error) {
+ errors.push(error);
+ };
+
+ parser.parse(settings.vttFieldValue);
+ if (errors.length > 0) {
+ if (console.groupCollapsed) {
+ console.groupCollapsed(`Text Track parsing errors`);
+ }
+ errors.forEach((error) => console.error(error));
+ if (console.groupEnd) {
+ console.groupEnd();
+ }
+ }
+
+ parser.flush();
+ }
+ }
+
+ this.ready(() => {
+
+ /*resize video*/
+ var videoChapterH = $('#rangeExtractor').height();
+ $('#rangeExtractor .video-player-container').css('max-height', videoChapterH);
+ $('#rangeExtractor .range-collection-container').css('height', videoChapterH - 100);
+ $('#rangeExtractor .video-range-editor-container').css('max-height', videoChapterH).css('overflow','hidden');
+
+
+ this.setVTT();
+ // if we have to load existing chapters, let's trigger loadedmetadata:
+ if (settings.vttFieldValue !== false) {
+ var playPromise = null;
+ if (this.paused()) {
+ playPromise = this.play().then(() => {
+ this.pause();
+ }).catch(error => {
+ });
+ }
+ if (!this.paused()) {
+ if (playPromise !== undefined) {
+ playPromise.then(() => {
+ this.pause();
+ })
+ .catch(error => {
+ });
+ }
+ }
+ }
+ });
+
+ this.one('loadedmetadata', () => {
+ //this.setEditorHeight();
+ this.setEditorWidth();
+ if (settings.vttFieldValue !== false) {
+ //this.currentTime(0);
+ }
+ });
+
+ // ensure control bar is always visible by simulating user activity:
+ this.on('timeupdate', () => {
+ this.userActive(true);
+ });
+
+ // override existing hotkeys:
+ this.getRangeCaptureOverridedHotkeys = () => overrideHotkeys(settings);
+
+ // set new hotkeys
+ this.getRangeCaptureHotkeys = () => hotkeys(this, settings);
+
+ // init a default range once every components are ready:
+ this.rangeCollection.initDefaultRange();
+
+ this.saveRangeCollectionPref = (isChecked) => {
+ appCommons.userModule.setPref('overlapChapters', (isChecked ? '1' : '0'));
+ }
+}
+videojs.plugin('rangeCapturePlugin', plugin);
+export default plugin;
diff --git a/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/rangeBar.js b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/rangeBar.js
new file mode 100644
index 0000000000..c4732e032e
--- /dev/null
+++ b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/rangeBar.js
@@ -0,0 +1,119 @@
+import _ from 'underscore';
+import videojs from 'video.js';
+import noUiSlider from 'nouislider';
+/**
+ * VideoJs Range bar
+ */
+const Component = videojs.getComponent('Component');
+
+class RangeBar extends Component {
+ rangeBar;
+ activeRange;
+
+ constructor(player, settings) {
+ super(player, settings);
+ this.activeHandlePositions = [];
+ this.activeRange = {
+ id: 1,
+ startPosition: -1,
+ endPosition: -1
+ };
+ this.onUpdatedRange = _.debounce(this.onUpdatedRange, 300);
+ }
+
+ /**
+ * Create the component's DOM element
+ *
+ * @return {Element}
+ * @method createEl
+ */
+ createEl() {
+ this.rangeBar = super.createEl('div', {
+ id: 'connect',
+ className: 'vjs-range-bar',
+ innerHTML: '
'
+ });
+
+ noUiSlider.create(this.rangeBar, {
+ start: [0, 0], // ((range.startPosition/videoDuration) * 100), ((range.endPosition/videoDuration) * 100)
+ behaviour: 'drag',
+ connect: true,
+ range: {
+ min: 0,
+ max: 100
+ }
+ });
+
+ let sliderBar = document.createElement('div');
+ let sliderBase = this.rangeBar.querySelector('.noUi-base');
+
+ // Give the bar a class for styling and add it to the slider.
+ sliderBar.className += 'connect';
+ sliderBase.appendChild(sliderBar);
+
+ this.rangeBar.noUiSlider.on('update', (values, handle, a, b, handlePositions) => {
+ let offset = handlePositions[handle];
+
+ // Right offset is 100% - left offset
+ if (handle === 1) {
+ offset = 100 - offset;
+ }
+
+ // Pick left for the first handle, right for the second.
+ sliderBar.style[handle ? 'right' : 'left'] = offset + '%';
+
+ this.onUpdatedRange(handlePositions, handle);
+ });
+
+ // triggered when drag end - ensure last changed handle is synced with play head
+ this.rangeBar.noUiSlider.on('change', (values, handle, a, b, handlePositions) => {
+ this.onUpdatedRange(handlePositions, handle);
+ });
+
+ return this.rangeBar;
+ }
+
+ onUpdatedRange(handlePositions, activeHandle) {
+
+ let videoDuration = this.player_.duration();
+
+ // convert back percent into time:
+ if (this.activeRange !== undefined) {
+ // checkif changes happened:
+ let oldRange = _.extend({}, this.activeRange);
+ let newStartPosition = (handlePositions[0] / 100) * videoDuration;
+ let newEndPosition = (handlePositions[1] / 100) * videoDuration;
+ this.activeRange.startPosition = newStartPosition;
+ this.activeRange.endPosition = newEndPosition;
+ this.activeHandlePositions = handlePositions;
+ this.player_.rangeStream.onNext({
+ action: 'drag-update',
+ handle: activeHandle === 1 ? 'end' : 'start',
+ range: this.activeRange
+ });
+ }
+ }
+
+ updateRange = (range) => {
+ this.activeRange = range;
+ let videoDuration = this.player_.duration();
+ if (videoDuration > 0) {
+ // set left side with percent update
+ let left = ((range.startPosition / videoDuration) * 100);
+ let right = ((range.endPosition / videoDuration) * 100);
+
+ // set as null if not and handle
+ if (this.activeHandlePositions.length > 0) {
+ // don't update unchanged handle:
+ left = left === this.activeHandlePositions[0] ? null : left;
+ right = right === this.activeHandlePositions[1] ? null : right;
+ }
+
+ this.rangeBar.noUiSlider.set([left, right]);
+ }
+ }
+}
+
+videojs.registerComponent('RangeBar', RangeBar);
+
+export default RangeBar;
diff --git a/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/rangeBarCollection.js b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/rangeBarCollection.js
new file mode 100644
index 0000000000..45805ec985
--- /dev/null
+++ b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/rangeBarCollection.js
@@ -0,0 +1,52 @@
+import videojs from 'video.js';
+import RangeBar from './rangeBar';
+/**
+ * VideoJs Range Bar Collection
+ */
+const Component = videojs.getComponent('Component');
+
+class RangeBarCollection extends Component {
+ activeRangeItem;
+
+ constructor(player, settings) {
+ super(player, settings);
+ this.settings = settings;
+ }
+
+ /**
+ * Create the component's DOM element
+ *
+ * @return {Element}
+ * @method createEl
+ */
+ createEl() {
+ return super.createEl('div', {
+ className: 'vjs-range-container',
+ innerHTML: ''
+ });
+ }
+
+ refreshRangeSliderPosition = (range) => {
+ if (range.startPosition === -1 && range.endPosition === -1) {
+ this.removeActiveRange(range)
+ return;
+ }
+
+ if (this.activeRangeItem === undefined) {
+ this.activeRangeItem = new RangeBar(this.player_, this.settings);//this.addChild('RangeBar', [this.player_, this.settings]);
+ }
+ this.activeRangeItem.updateRange(range);
+
+ this.addChild(this.activeRangeItem);
+ }
+
+ removeActiveRange = (range) => {
+ if (this.activeRangeItem !== undefined) {
+ this.removeChild(this.activeRangeItem);
+ }
+ }
+}
+
+videojs.registerComponent('RangeBarCollection', RangeBarCollection);
+
+export default RangeBarCollection;
diff --git a/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/rangeCollection.js b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/rangeCollection.js
new file mode 100644
index 0000000000..7213a25bf0
--- /dev/null
+++ b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/rangeCollection.js
@@ -0,0 +1,504 @@
+import $ from 'jquery';
+import _ from 'underscore';
+import videojs from 'video.js';
+import RangeItem from './rangeItem';
+import {formatTime, formatToFixedDecimals} from './utils';
+import Alerts from '../../utils/alert';
+import dialog from './../../../phraseanet-common/components/dialog';
+
+const humane = require('humane-js');
+
+/**
+ * VideoJs Range Collection
+ */
+const Component = videojs.getComponent('Component');
+
+class RangeCollection extends Component {
+ uid = 0;
+ defaultRange = {
+ startPosition: -1,
+ endPosition: -1,
+ title: '',
+ handlePositions: [],
+ selected: false,
+ image: {
+ src: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFkAAAAyCAYAAAA3OHc2AAAAuElEQVR4Xu3UwQkAIAwEwdh/0Qr2kH2NBWRhODwzc8dbFTiQV33/ccj7xpADY8iQC4Gg4U+GHAgECUuGHAgECUuGHAgECUuGHAgECUuGHAgECUuGHAgECUuGHAgECUuGHAgECUuGHAgECUuGHAgECUuGHAgECUuGHAgECUuGHAgECUuGHAgECUuGHAgECUuGHAgECUuGHAgECUuGHAgECUuGHAgECUuGHAgECUuGHAgECUuGHAgEiQftoTIBhrHr1wAAAABJRU5ErkJggg==',
+ width: 89,
+ height: 50
+ },
+ manualSnapShot: false
+ };
+ rangeCollection = [];
+ rangeItemComponentCollection = [];
+ currentRange = false;
+ isHoverChapterSelected = false;
+
+ constructor(player, settings) {
+ super(player, settings);
+ this.settings = settings;
+ this.$el = this.renderElContent();
+
+ this.player_.activeRangeStream.subscribe((params) => {
+ this.currentRange = params.activeRange;
+ this.refreshRangeCollection()
+ });
+
+ this.isHoverChapterSelected = settings.preferences.overlapChapters == 1 ? true : false;
+ }
+
+ initDefaultRange() {
+ // init collection with a new range if nothing specified:
+ let newRange = this.addRange(this.defaultRange);
+ this.player_.rangeStream.onNext({
+ action: 'create',
+ range: newRange
+ });
+ }
+
+ addRangeEvent() {
+ let newRange = this.addNewRange(this.defaultRange);
+ this.player_.rangeStream.onNext({
+ action: 'create',
+ range: newRange
+ });
+ }
+
+ exportRangeEvent() {
+ this.player_.rangeStream.onNext({
+ action: 'export-ranges',
+ ranges: this.exportRanges()
+ });
+ }
+
+ exportVTTRangeEvent() {
+ this.player_.rangeStream.onNext({
+ action: 'export-vtt-ranges',
+ data: this.exportVttRanges()
+ });
+ }
+
+ setHoverChapter(isChecked) {
+ this.isHoverChapterSelected = isChecked;
+ this.player_.rangeStream.onNext({
+ action: 'saveRangeCollectionPref',
+ data: isChecked
+ });
+ }
+
+ /**
+ * Create the component's DOM element
+ *
+ * @return {Element}
+ * @method createEl
+ */
+ createEl() {
+ return super.createEl('div', {
+ className: 'range-collection-container',
+ innerHTML: ''
+ });
+ }
+
+ renderElContent() {
+ return $(this.el());
+ }
+
+ update(range) {
+ let updatedRange;
+
+ if (!this.isExist(range)) {
+ updatedRange = this.addNewRange(range);
+ } else {
+ updatedRange = this.updateRange(range);
+ }
+ return updatedRange;
+ }
+
+ updatingByDragging(range) {
+ if(this.isHoverChapterSelected) {
+ this.syncRange(range);
+ }else {
+ this.updateRange(range);
+ }
+ }
+
+ isExist(range) {
+ if (range.id === undefined) {
+ return false;
+ }
+ for (let i = 0; i < this.rangeCollection.length; i++) {
+ if (this.rangeCollection[i].id === range.id) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ remove(range) {
+ let cleanedColl = _.filter(this.rangeCollection, (rangeData, index) => {
+ if (range.id === rangeData.id) {
+ return false;
+ }
+ return true;
+ });
+ this.rangeCollection = cleanedColl;
+ // if removed range is active one, activate another one
+ if (range.id === this.currentRange.id) {
+ if (this.rangeCollection.length > 0) {
+
+ //let lastRange = this.rangeCollection.length-1;
+ this.player_.rangeStream.onNext({
+ action: 'select',
+ range: this.rangeCollection[this.rangeCollection.length - 1]
+ })
+ }
+
+ }
+ this.refreshRangeCollection();
+ }
+
+ addRange(range) {
+ let lastId = this.uid = this.uid + 1;
+ let newRange = _.extend({}, this.defaultRange, range, {id: lastId});
+ newRange = this.setHandlePositions(newRange);
+ this.rangeCollection.push(newRange);
+ this.refreshRangeCollection();
+ return newRange;
+ }
+
+ addNewRange(range) {
+ let lastId = this.uid = this.uid + 1;
+ let newRange = _.extend({}, this.defaultRange, range, {id: lastId});
+ newRange.startPosition = this.getStartingPosition();
+ newRange.endPosition = this.getEndPosition(newRange.startPosition);
+ newRange = this.setHandlePositions(newRange);
+ this.rangeCollection.push(newRange);
+ this.refreshRangeCollection();
+ return newRange;
+ }
+
+ getStartingPosition() {
+ //tracker is at ending of previous range
+ let gap = _.first(this.settings.record.sources).framerate * 0.001;
+ let lastKnownPosition = this.player_.currentTime();
+
+ if((lastKnownPosition + gap) < this.player_.duration()) {
+ lastKnownPosition += gap;
+ return lastKnownPosition;
+ }
+ return lastKnownPosition;
+ // let gap = 0.01;
+ // let lastRange = this.rangeCollection.length > 0 ?
+ // this.rangeCollection[this.rangeCollection.length -1] : null;
+ //
+ // if(lastRange != null ||
+ // formatToFixedDecimals(this.player_.currentTime()) < formatToFixedDecimals(lastRange.endPosition)) {
+ // lastKnownPosition = lastRange.endPosition + gap <= this.player_.duration()
+ // ? lastRange.endPosition + gap
+ // : this.player_.duration();
+ // }else {
+ // lastKnownPosition = this.player_.currentTime() + gap <= this.player_.duration()
+ // ? this.player_.currentTime() + gap
+ // : this.player_.duration();
+ // }
+ // return lastKnownPosition;
+ }
+
+ getEndPosition(startPosition) {
+ let rangeDuration = this.player_.duration()/10;
+ let endPosition = startPosition + rangeDuration;
+ if(endPosition >= this.player_.duration()) {
+ endPosition == this.player_.duration();
+ }
+ return endPosition;
+ // let gap = 0.01;
+ // let rangeDuration = this.player_.duration()/10;
+ // let endPosition = null;
+ // if(formatToFixedDecimals(startPosition) >= formatToFixedDecimals(this.player_.currentTime() + gap)) {
+ // endPosition = startPosition + rangeDuration <= this.player_.duration()
+ // ? startPosition + rangeDuration
+ // : this.player_.duration();
+ // }else {
+ // endPosition = this.player_.currentTime() + gap;
+ // }
+ // return endPosition;
+ }
+
+ updateRange(range) {
+ if (range.id !== undefined) {
+ this.rangeCollection = _.map(this.rangeCollection, (rangeData, index) => {
+ if (range.id === rangeData.id) {
+ range = this.setHandlePositions(range);
+ return range;
+ }
+ return rangeData;
+ });
+ }
+ this.refreshRangeCollection();
+ return range;
+ }
+
+ syncRange(range) {
+ let gap = _.first(this.settings.record.sources).framerate * 0.001;
+ if (range.id !== undefined) {
+ let index = _.findIndex(this.rangeCollection, (rangeData) => {
+ return rangeData.id == range.id;
+ });
+
+ if(index !== null) {
+ if(index < this.rangeCollection.length-1) {
+ //update next range
+ let rangeToUpdate = this.rangeCollection[index+1];
+ rangeToUpdate.startPosition = range.endPosition + gap <= rangeToUpdate.endPosition
+ ? range.endPosition + gap : rangeToUpdate.endPosition;
+ let newRange = this.setHandlePositions(rangeToUpdate);
+ this.rangeCollection[index+1] = newRange;
+ }
+ if (index > 0) {
+ //update previous range
+ let rangeToUpdate = this.rangeCollection[index-1];
+ rangeToUpdate.endPosition = range.startPosition - gap >= rangeToUpdate.startPosition
+ ? range.startPosition - gap : rangeToUpdate.startPosition;
+ let newRange = this.setHandlePositions(rangeToUpdate);
+ this.rangeCollection[index-1] = newRange;
+ }
+
+ let newRange = this.setHandlePositions(range);
+ this.rangeCollection[index] = newRange;
+ }
+ }
+ this.refreshRangeCollection();
+ return range;
+
}
+
+
+ setHandlePositions(range) {
+ let videoDuration = this.player_.duration();
+ if (videoDuration > 0) {
+ let left = ((range.startPosition / videoDuration) * 100);
+ let right = ((range.endPosition / videoDuration) * 100);
+
+ range.handlePositions = {left, right};
+ }
+ return range;
+ }
+
+ getRangeById(id) {
+ let foundRange = {};
+ for (let i = 0; i < this.rangeCollection.length; i++) {
+ if (this.rangeCollection[i].id === id) {
+ foundRange = this.rangeCollection[i];
+ }
+ }
+ return foundRange;
+ }
+
+ exportRanges = () => {
+ let exportedRanges = [];
+ for (let i = 0; i < this.rangeCollection.length; i++) {
+ exportedRanges.push({
+ startPosition: this.rangeCollection[i].startPosition,
+ endPosition: this.rangeCollection[i].endPosition
+ })
+ }
+ return exportedRanges;
+ }
+ exportVttRanges = () => {
+ let exportedRanges = [`WEBVTT
+`];
+ let titleValue= document.getElementById("default-video-chapter-label").value;
+ for (let i = 0; i < this.rangeCollection.length; i++) {
+ let exportableData = {
+ title: this.rangeCollection[i].title != "" ? this.rangeCollection[i].title : titleValue
+ };
+
+ if (this.rangeCollection[i].image.src !== '') {
+ exportableData.image = this.rangeCollection[i].image.src;
+ exportableData.manualSnapShot = this.rangeCollection[i].manualSnapShot || false;
+ }
+
+ exportedRanges.push(`${i + 1}
+${formatTime(this.rangeCollection[i].startPosition, 'hh:mm:ss.mmm')} --> ${formatTime(this.rangeCollection[i].endPosition, 'hh:mm:ss.mmm')}
+${JSON.stringify(exportableData)}
+`)
+ }
+ return exportedRanges.join('\n');
+ }
+
+ get = (model) => {
+ if (model === undefined) {
+ return this.rangeCollection;
+ }
+ return this.getRangeById(model.id);
+ }
+
+ splice = (...args) => {
+ return Array.prototype.splice.apply(this.rangeCollection, args);
+ }
+
+ getIndex = (model) => {
+ let index = {};
+ for (let i = 0; i < this.rangeCollection.length; i++) {
+ if (this.rangeCollection[i].id === model.id) {
+ index = i;
+ }
+ }
+ return index;
+ }
+
+ getSelection = () => {
+ let selectedRanges = [];
+ for (let i = 0; i < this.rangeCollection.length; i++) {
+ if (this.rangeCollection[i].selected === true) {
+ selectedRanges.push(this.rangeCollection[i]);
+ }
+ }
+ return selectedRanges;
+ }
+
+ resetSelection = () => {
+ for (let i = 0; i < this.rangeCollection.length; i++) {
+ this.rangeCollection[i].selected = false;
+ }
+ }
+
+ addToSelection = (model) => {
+ for (let i = 0; i < this.rangeCollection.length; i++) {
+ if (this.rangeCollection[i].id === model.id) {
+ this.rangeCollection[i].selected = true;
+ }
+ }
+ }
+
+ removeFromSelection = (model) => {
+ for (let i = 0; i < this.rangeCollection.length; i++) {
+ if (this.rangeCollection[i].id === model.id) {
+ this.rangeCollection[i].selected = false;
+ }
+ }
+ }
+
+ getFirstSelected = () => {
+ let firstModel = false;
+ for (let i = 0; i < this.rangeCollection.length; i++) {
+ if (this.rangeCollection[i].selected === true && firstModel === false) {
+ firstModel = this.rangeCollection[i];
+ }
+ }
+ return firstModel;
+ }
+
+ getLastSelected = () => {
+ let lastModel = false;
+ for (let i = 0; i < this.rangeCollection.length; i++) {
+ if (this.rangeCollection[i].selected === true) {
+ lastModel = this.rangeCollection[i];
+ }
+ }
+ return lastModel;
+ }
+
+ reset = (collection) => {
+ this.rangeCollection = collection;
+ // refresh internal indexes:
+ for (let i = 0; i < this.rangeCollection.length; i++) {
+ this.rangeCollection[i].index = i;
+ }
+ this.refreshRangeCollection();
+ }
+
+ setActiveRange = (direction) => {
+ if (this.currentRange === false) {
+ return;
+ }
+ let toIndex = this.currentRange.index - 1;
+
+ if (direction === 'down') {
+ toIndex = this.currentRange.index + 1;
+ }
+
+ if (this.rangeCollection[toIndex] !== undefined) {
+
+ this.player_.rangeStream.onNext({
+ action: 'change',
+ range: this.rangeCollection[toIndex]
+ });
+ }
+ }
+
+ moveRange = (direction) => {
+ if (this.currentRange === false) {
+ return;
+ }
+ let collection = this.get();
+ let toIndex = this.currentRange.index - 1;
+
+ if (direction === 'down') {
+ toIndex = this.currentRange.index + 1;
+ }
+ this.addToSelection(this.currentRange);
+ let selectedModels = this.getSelection();
+
+ for (let i = selectedModels.length; i--;) {
+ let fromIndex = this.getIndex(this.get(selectedModels[i]));
+
+ collection.splice(toIndex, 0, this.splice(fromIndex, 1)[0]);
+ }
+
+ this.reset(collection);
+ }
+
+ refreshRangeCollection = () => {
+ // remove any existing items
+ for (let i = 0; i < this.rangeItemComponentCollection.length; i++) {
+ this.rangeItemComponentCollection[i].dispose();
+ this.removeChild(this.rangeItemComponentCollection[i]);
+ }
+ this.rangeItemComponentCollection = [];
+
+ let activeId = 0;
+ if (this.currentRange !== false) {
+ activeId = this.currentRange.id;
+ }
+
+ for (let i = 0; i < this.rangeCollection.length; i++) {
+ let model = _.extend({}, this.rangeCollection[i], {index: i});
+ let item = new RangeItem(this.player_, {
+ model: model,
+ collection: this,
+ isActive: this.rangeCollection[i].id === activeId ? true : false
+ }, this.settings);
+
+ this.rangeItemComponentCollection.push(item);
+ this.addChild(item);
+
+
+ }
+ }
+
+ exportRangesData = (rangeData) => {
+ var title = this.settings.translations.alertTitle;
+ var message = this.settings.translations.updateTitle;
+ var services = this.settings.services;
+ $.ajax({
+ type: 'POST',
+ url: `${this.settings.baseUrl}prod/tools/metadata/save/`,
+ data: {
+ databox_id: this.settings.databoxId,
+ record_id: this.settings.recordId,
+ meta_struct_id: this.settings.meta_struct_id,
+ value: rangeData
+ },
+ success: function (data) {
+ if (!data.success) {
+ humane.error(data.message);
+ } else {
+ humane.info(message);
+ }
+ }
+ });
+};
+}
+
+videojs.registerComponent('RangeCollection', RangeCollection);
+
+export default RangeCollection;
diff --git a/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/rangeControlBar.js b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/rangeControlBar.js
new file mode 100644
index 0000000000..dccce544ef
--- /dev/null
+++ b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/rangeControlBar.js
@@ -0,0 +1,482 @@
+import $ from 'jquery';
+import _ from 'underscore';
+import videojs from 'video.js';
+import {formatMilliseconds, formatTime} from './utils';
+/**
+ * VideoJs Range Control Bar
+ */
+const Component = videojs.getComponent('Component');
+
+
+const icons = `
+
+
+
+loop-range
+
+
+
+
+
+
+prev-forward-frame
+
+
+
+
+
+next-forward-frame
+
+
+
+
+
+prev-frame
+
+
+
+
+next-frame
+
+
+
+
+cue-start
+
+
+
+cue-end
+
+
+
+trash
+
+
+
+
+
+`;
+const defaults = {
+ frameRate: 24
+};
+class RangeControlBar extends Component {
+ rangeControlBar;
+ frameRate;
+ currentRange;
+
+ constructor(player, options) {
+ super(player, options);
+ const settings = videojs.mergeOptions(defaults, options);
+
+ //this.settings = settings;
+ this.looping = false;
+ this.loopData = []; // @dprecated
+ this.frameStep = 1;
+
+ this.frameRate = settings.frameRates[this.player_.cache_.src];
+ this.frameDuration = (1 / this.frameRate);
+
+ this.currentRange = false;
+ this.player_.activeRangeStream.subscribe((params) => {
+ this.currentRange = params.activeRange;
+ this.onRefreshDisplayTime();
+ })
+ }
+
+ rangeMenuTemplate() {
+ return `
+
+
+ icon-cue-end
+ remove
+ loop
+ prev forward frame
+ prev frame
+
+ :
+ :
+ s
+ f
+
+
+ :
+ :
+ s
+ f
+ next frame
+ next forward frame
+
+E. 00:00:00s 00f
+
`;
+ }
+
+ /**
+ * Create the component's DOM element
+ *
+ * @return {Element}
+ * @method createEl
+ */
+ createEl() {
+ this.rangeControlBar = super.createEl('div', {
+ className: 'range-control-bar',
+ innerHTML: ''
+ });
+ $(this.rangeControlBar)
+ .on('click', '#start-range', (event) => {
+ event.preventDefault();
+ this.player_.rangeStream.onNext({
+ action: 'update',
+ handle: 'start',
+ range: this.setStartPositon()
+ });
+ })
+ .on('click', '#end-range', (event) => {
+ event.preventDefault();
+ this.player_.rangeStream.onNext({
+ action: 'update',
+ handle: 'end',
+ range: this.setEndPosition()
+ });
+ })
+ .on('click', '#delete-range', (event) => {
+ event.preventDefault();
+ this.player_.rangeStream.onNext({
+ action: 'remove'
+ });
+ })
+ .on('click', '#backward-frame', (event) => {
+ event.preventDefault();
+ this.setPreviousFrame();
+ })
+ .on('click', '#forward-frame', (event) => {
+ event.preventDefault();
+ this.setNextFrame();
+ })
+ .on('click', '#prev-forward-frame', (event) => {
+ event.preventDefault();
+ if (!this.player_.paused()) {
+ this.player_.pause();
+ }
+ this.player_.currentTime(this.getStartPosition())
+ })
+ .on('click', '#next-forward-frame', (event) => {
+ event.preventDefault();
+ if (!this.player_.paused()) {
+ this.player_.pause();
+ }
+ this.player_.currentTime(this.getEndPosition())
+ })
+ .on('click', '#loop-range', (event) => {
+ event.preventDefault();
+ this.toggleLoop();
+ })
+ .on('click', '#display-current', (event) => {
+ let $el = $(event.currentTarget);
+ let mode = $el.data('mode');
+
+ console.log('mode:', $el.data('mode'))
+ switch (mode) {
+ case 'remaining':
+ $el.data('mode', 'elapsed');
+ $el.attr('videotip', this.player_.localize('Elapsed time'))
+ break;
+ case 'elapsed':
+ if (this.currentRange === false) {
+ $el.data('mode', 'remaining');
+ $el.attr('videotip', this.player_.localize('Remaining time'))
+ } else {
+ $el.data('mode', 'duration');
+ $el.attr('videotip', this.player_.localize('Range duration'))
+ }
+ break;
+ case 'duration':
+ $el.data('mode', 'remaining');
+ $el.attr('videotip', this.player_.localize('Remaining time'))
+ break;
+ default:
+ if (this.currentRange === false) {
+ $el.data('mode', 'remaining');
+ $el.attr('videotip', this.player_.localize('Remaining time'))
+ } else {
+ $el.data('mode', 'duration');
+ $el.attr('videotip', this.player_.localize('Range duration'))
+ }
+ }
+ this.onRefreshDisplayTime();
+ /*// toggle mode
+ if ($el.data('mode') === 'remaining') {
+ $el.data('mode', 'current');
+ $el.attr('videotip', this.player_.localize('Elapsed time'))
+ } else {
+ $el.data('mode', 'remaining');
+ $el.attr('videotip', this.player_.localize('Remaining time'))
+ }*/
+ })
+ .on('keyup', '.range-input', (event) => {
+ if (event.keyCode === 13) {
+ $(event.currentTarget).blur();
+ }
+ })
+ .on('focus', '.range-input', (event) => {
+ event.currentTarget.setSelectionRange(0, event.currentTarget.value.length)
+ })
+ .on('blur', '.range-input', (event) => {
+ event.preventDefault();
+ let $el = $(event.currentTarget);
+
+ if (this.validateScopeInput($el.data('scope'))) {
+ // this.validateScopeInput();
+ let newCurrentTime = this.getScopeInputTime($el.data('scope'));
+ this.player_.currentTime(newCurrentTime);
+ $el.addClass('is-valid');
+ setTimeout(() => $el.removeClass('is-valid'), 500);
+ } else {
+ $el.addClass('has-error');
+ setTimeout(() => $el.removeClass('has-error'), 1200);
+ }
+ // fallback on old values if have errors:
+ this.player_.rangeStream.onNext({
+ action: 'update',
+ handle: ($el.data('scope') === 'start-range' ? 'start' : 'end'),
+ range: ($el.data('scope') === 'start-range' ? this.setStartPositon() : this.setEndPosition())
+ });
+
+ });
+
+ $(this.rangeControlBar).append(this.rangeMenuTemplate());
+
+ this.player_.on('timeupdate', () => {
+ this.onRefreshDisplayTime();
+ // if a loop exists
+ if (this.looping === true && this.loopData.length > 0) {
+
+ let start = this.currentRange.startPosition; //this.loopData[0];
+ let end = this.currentRange.endPosition; //this.loopData[1];
+
+ var current_time = this.player_.currentTime();
+
+ if (current_time < start || end > 0 && current_time >= end) {
+ this.player_.currentTime(start);
+ setTimeout(() => {
+ // Resume play if the element is paused.
+ if (this.player_.paused()) {
+ this.player_.play();
+ }
+ }, 150);
+ }
+
+ }
+ });
+ return this.rangeControlBar;
+ }
+
+ refreshRangePosition(range, handle) {
+ handle = handle || false;
+ this.updateRangeDisplay('start-range', range.startPosition);
+ this.updateRangeDisplay('end-range', range.endPosition);
+
+ if (handle === 'start') {
+ this.player_.currentTime(range.startPosition)
+ } else if (handle === 'end') {
+ this.player_.currentTime(range.endPosition)
+ }
+ }
+
+ setRangePositonToBeginning(range) {
+ this.player_.currentTime(range.startPosition);
+ }
+
+ updateRangeDisplay(scope, currentTime) {
+
+ let format = formatMilliseconds(currentTime, this.frameRate);
+
+ $(`#${scope}-input-hours`).val(('0' + format.hours).slice(-2));
+ $(`#${scope}-input-minutes`).val(('0' + format.minutes).slice(-2));
+ $(`#${scope}-input-seconds`).val(('0' + format.seconds).slice(-2));
+ $(`#${scope}-input-frames`).val(('0' + format.frames).slice(-2));
+ }
+
+ getScopeInputs(scope) {
+ return {
+ hours: $(`#${scope}-input-hours`).val(),
+ minutes: $(`#${scope}-input-minutes`).val(),
+ seconds: $(`#${scope}-input-seconds`).val(),
+ frames: $(`#${scope}-input-frames`).val()
+ }
+ }
+
+ validateScopeInput(scope) {
+ let scopeInputs = this.getScopeInputs(scope);
+ var regex = /^\d+$/; // allow only numbers [0-9]
+ if (regex.test(scopeInputs.hours) && regex.test(scopeInputs.minutes) && regex.test(scopeInputs.seconds) && regex.test(scopeInputs.frames)) {
+ if (scopeInputs.minutes < 0 || scopeInputs.minutes > 59) {
+ return false;
+ }
+ if (scopeInputs.seconds < 0 || scopeInputs.seconds > 59) {
+ return false;
+ }
+ if (scopeInputs.frames < 0 || scopeInputs.frames > this.frameRate) {
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ getScopeInputTime(scope) {
+ let scopeInputs = this.getScopeInputs(scope);
+ let hours = parseInt(scopeInputs.hours, 10);
+ let minutes = parseInt(scopeInputs.minutes, 10);
+ let seconds = parseInt(scopeInputs.seconds, 10);
+ let frames = parseInt(scopeInputs.frames, 10);
+ let milliseconds = frames === 0 ? 0 : (((1000 / this.frameRate) * frames) / 1000).toFixed(2);
+
+ return (hours * 3600) + (minutes * 60) + (seconds) + parseFloat(milliseconds);
+ }
+
+ toggleLoop() {
+ let $el = $('#loop-range');
+ if (!this.player_.paused()) {
+ this.player_.pause();
+ }
+ this.looping = !this.looping;
+
+ if (this.looping) {
+ $el.addClass('active');
+ this.loopBetween();
+ } else {
+ $el.removeClass('active');
+ }
+ }
+
+ loopBetween(range) {
+ range = range || this.player_.activeRange;
+ this.loop(range.startPosition, range.endPosition);
+ }
+
+ loop(start, end) {
+ this.looping = true;
+ this.player_.currentTime(start);
+
+ // @deprecated
+ this.loopData = [start, end];
+
+ setTimeout(() => {
+ // Resume play if the element is paused.
+ if (this.player_.paused()) {
+ this.player_.play();
+ }
+ }, 150);
+ }
+
+ setStartPositon() {
+ if (this.currentRange === false) {
+ throw new Error('setStartPositon > no range provided')
+ }
+ let newRange = _.extend({}, this.currentRange);
+ // set start
+ newRange.startPosition = this.player_.currentTime();
+ newRange.startPositionFormated = formatMilliseconds(this.player_.currentTime(), this.frameRate);
+ let firstTime = newRange.startPosition === -1 && newRange.endPosition === -1;
+ let startBehindEnd = newRange.startPosition > newRange.endPosition;
+
+ if (firstTime || startBehindEnd) {
+ newRange.endPosition = this.player_.duration()
+ }
+ return newRange;
+ }
+
+ getStartPosition() {
+ if (this.currentRange === false) {
+ throw new Error('getStartPosition > no range provided')
+ }
+ return this.currentRange.startPosition;
+ }
+
+ setEndPosition() {
+ if (this.currentRange === false) {
+ throw new Error('setEndPositon > no range provided')
+ }
+ let newRange = _.extend({}, this.currentRange);
+ newRange.endPosition = this.player_.currentTime();
+ newRange.endPositionFormated = formatMilliseconds(this.player_.currentTime(), this.frameRate);
+ let firstTime = newRange.startPosition === -1 && newRange.endPosition === -1;
+ let startBehindEnd = newRange.startPosition > newRange.endPosition;
+ if (firstTime || startBehindEnd) {
+ newRange.startPosition = 0;
+ }
+ return newRange;
+ }
+
+
+ getEndPosition() {
+ if (this.currentRange === false) {
+ throw new Error('getEndPosition > no range provided')
+ }
+ return this.currentRange.endPosition;
+ }
+
+ removeActiveRange() {
+ this.updateRangeDisplay('start-range', 0);
+ this.updateRangeDisplay('end-range', 0);
+ }
+
+ /**
+ *
+ * @param step (frames)
+ */
+ setNextFrame(step) {
+ let position = this.player_.currentTime();
+ if (!this.player_.paused()) {
+ this.player_.pause();
+ }
+
+ if (step !== undefined) {
+ this.player_.currentTime(position + step);
+ } else {
+ this.player_.currentTime(position + (this.frameDuration * this.frameStep));
+ }
+ }
+
+ /**
+ *
+ * @param step (frames)
+ */
+ setPreviousFrame(step) {
+ let position = this.player_.currentTime();
+ if (!this.player_.paused()) {
+ this.player_.pause();
+ }
+
+ if (step !== undefined) {
+ this.player_.currentTime(position - step);
+ } else {
+ this.player_.currentTime(position - (this.frameDuration * this.frameStep));
+ }
+ }
+
+ onRefreshDisplayTime() {
+ if (this.$displayCurrent === undefined) {
+ this.$displayCurrent = $('#display-current');
+ }
+ if (this.$displayCurrent.length > 0) {
+ switch (this.$displayCurrent.data('mode')) {
+ case 'remaining':
+ this.$displayCurrent.html('R. ' + formatTime(this.player_.remainingTime(), '', this.frameRate))
+ break;
+ case 'elapsed':
+ this.$displayCurrent.html('E. ' + formatTime(this.player_.currentTime(), '', this.frameRate))
+ break;
+ case 'duration':
+ this.$displayCurrent.html('D. ' + formatTime(this.currentRange.endPosition - this.currentRange.startPosition, '', this.frameRate))
+ break;
+ default:
+ }
+ }
+ }
+
+}
+
+videojs.registerComponent('RangeControlBar', RangeControlBar);
+
+export default RangeControlBar;
diff --git a/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/rangeItem.js b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/rangeItem.js
new file mode 100644
index 0000000000..40455f5105
--- /dev/null
+++ b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/rangeItem.js
@@ -0,0 +1,150 @@
+import _ from 'underscore';
+import $ from 'jquery';
+import videojs from 'video.js';
+import {formatTime} from './utils';
+import SortableComponent from './sortableComponent';
+/**
+ * VideoJs Range bar
+ */
+const Component = videojs.getComponent('Component');
+let chapterLabel = document.getElementById("default-video-chapter-label").value;
+let rangeItemTemplate = (model, frameRate) => {
+ let image = '';
+ if (model.image.src !== '') {
+ image = `
+
+
+
+
+
`;
+ }
+
+ return `
+
+${model.index + 1}
+
+${image}
+
+
+
+
+
+
+ ${formatTime(model.startPosition, 'hms', frameRate)}
+ ${formatTime(model.endPosition, 'hms', frameRate)}
+
+
+
+
+
${formatTime(model.endPosition - model.startPosition, 'hms', frameRate)}
+
+
+
+`;
+ // remove
+};
+class RangeItem extends Component {
+ rangeOptions;
+ settings;
+ item;
+
+ constructor(player, rangeOptions, settings) {
+ super(player, rangeOptions);
+ this.frameRate = settings.frameRates[this.player_.cache_.src];
+ this.settings = settings;
+ this.$el = this.renderElContent();
+
+ this.$el.on('click', '#capture-thumbnail-icon', (event) => {
+ event.preventDefault();
+ this.player_.rangeStream.onNext({
+ action: 'capture',
+ range: rangeOptions.model
+ });
+ // don't trigger other events
+ event.stopPropagation();
+ });
+
+ this.$el.on('click', (event) => {
+ // event.preventDefault();
+ let $el = $(event.currentTarget);
+ if (rangeOptions.isActive === false) {
+ // broadcast active state:
+ this.player_.rangeStream.onNext({
+ action: 'change',
+ range: rangeOptions.model
+ });
+ }
+ })
+ this.$el.on('click', '.remove-range', (event) => {
+ event.preventDefault();
+ this.player_.rangeStream.onNext({
+ action: 'remove',
+ range: rangeOptions.model
+ });
+ // don't trigger other events
+ event.stopPropagation();
+ })
+ this.$el.on('click focus', '.range-title', (event) => {
+ event.stopPropagation(); // stop unfocus
+ });
+ this.$el.on('keydown', '.range-title', (event) => {
+ event.stopPropagation();
+ });
+ this.$el.on('keyup', '.range-title', (event) => {
+ if (event.keyCode === 13) {
+ $(event.currentTarget).blur();
+ }
+ })
+ this.$el.on('blur', '.range-title', (event) => {
+ event.preventDefault();
+ let $el = $(event.currentTarget);
+ this.player_.rangeStream.onNext({
+ action: 'update',
+ range: _.extend(rangeOptions.model, {
+ title: $el.val()
+ })
+ });
+ // don't trigger other events
+ event.stopPropagation();
+ })
+
+ this.sortable = new SortableComponent(rangeOptions, this.$el);
+
+ }
+
+ /**
+ * Create the component's DOM element
+ *
+ * @return {Element}
+ * @method createEl
+ */
+ createEl() {
+ this.rangeOptions = super.createEl('div', {
+ className: 'range-collection-item',
+ innerHTML: ''
+ }, {
+ draggable: true
+ });
+
+ return this.rangeOptions;
+ }
+
+ renderElContent() {
+ $(this.el_).append(rangeItemTemplate(this.options_.model, this.frameRate));
+ if (this.options_.isActive) {
+ $(this.el_).addClass('active')
+ }
+ return $(this.el_);
+ }
+
+ dispose() {
+ this.$el.off();
+ this.sortable.dispose();
+ }
+}
+
+videojs.registerComponent('RangeItem', RangeItem);
+
+export default RangeItem;
diff --git a/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/rangeItemContainer.js b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/rangeItemContainer.js
new file mode 100644
index 0000000000..cf179eaf3d
--- /dev/null
+++ b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/rangeItemContainer.js
@@ -0,0 +1,90 @@
+import _ from 'underscore';
+import $ from 'jquery';
+import videojs from 'video.js';
+import RangeCollection from './rangeCollection';
+
+const Component = videojs.getComponent('Component');
+
+class RangeItemContainer extends Component {
+ container;
+ settings;
+ rangeCollection;
+
+ constructor(player, settings) {
+ super(player);
+ this.settings = settings;
+ this.$el = this.renderHeaderContent();
+ this.rangeCollection = this.addChild('RangeCollection', settings);
+ this.$el = this.renderButtonsContent();
+
+ this.$el.on('click', '.add-range', (event) => {
+ event.preventDefault();
+ this.rangeCollection.addRangeEvent();
+ });
+
+ this.$el.on('click', '.export-ranges', (event) => {
+ event.preventDefault();
+ this.rangeCollection.exportRangeEvent();
+ });
+
+ if(this.settings.ChapterVttFieldName == false
+ || this.settings.meta_struct_id == undefined) {
+ this.$el.find('.export-vtt-ranges').prop('disabled', true);
+ }else {
+ this.$el.on('click', '.export-vtt-ranges', (event) => {
+ event.preventDefault();
+ this.rangeCollection.exportVTTRangeEvent();
+ });
+ }
+
+ this.$el.on('click', 'input[name=hover-chapters]', (event) => {
+ let $el = $(event.currentTarget);
+ this.rangeCollection.setHoverChapter($el.is(':checked'));
+ });
+ }
+
+ /**
+ * Create the component's DOM element
+ *
+ * @return {Element}
+ * @method createEl
+ */
+ createEl() {
+ this.container = super.createEl('div', {
+ className: 'range-item-container',
+ innerHTML: ''
+ });
+
+ return this.container;
+ }
+
+ renderHeaderContent() {
+ var checkedValue = this.settings.preferences.overlapChapters == 1 ? 'checked' : '';
+ $(this.el()).append(`
+ `);
+ return $(this.el_);
+ }
+
+ renderButtonsContent() {
+ $(this.el()).append(`
+
+ ${this.player_.localize('Add new range')}
+ ${this.player_.localize('Save as VTT')}
+
+
`);
+ return $(this.el_);
+ }
+
+ dispose() {
+ this.$el.off();
+ }
+}
+
+videojs.registerComponent('RangeItemContainer', RangeItemContainer);
+
+export default RangeItemContainer;
diff --git a/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/sortableComponent.js b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/sortableComponent.js
new file mode 100644
index 0000000000..7464b394ed
--- /dev/null
+++ b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/sortableComponent.js
@@ -0,0 +1,233 @@
+import * as _ from 'underscore';
+import $ from 'jquery';
+
+class SortableComponent {
+ tagName;
+ template;
+ customEvents;
+ parent;
+ options;
+ dragTooltipContainer;
+ isSortingEnabled;
+ defaultOptions = {
+ selectionClass: 'drag-selected',
+ overClass: 'drag-over',
+ }
+
+ constructor(options, $el) {
+ if (!options) {
+ options = {};
+ }
+ options.attributes = {
+ draggable: true
+ };
+ this.options = _.extend(this.defaultOptions, options);
+ this.$el = $el;
+ this.model = options.model;
+ if (!this.options.events) {
+ this.options.events = {};
+ }
+ this.$el
+ .on('mousedown', (event) => this.onMouseDown(event))
+ .on('mouseup', (event) => this.onMouseUp(event))
+ .on('drag', (event) => this.onDrag(event))
+ .on('dragstart', (event) => this.onDragStart(event))
+ .on('dragenter', (event) => this.onDragEnter(event))
+ .on('dragleave', (event) => this.onDragLeave(event))
+ .on('dragover', (event) => this.onDragOver(event))
+ .on('drop', (event) => this.drop(event));
+
+ this.dragTooltipContainer = false;
+
+ // create tooltip container if not existing:
+ if ($('.drag-mousemove-container').length === 0) {
+ $('body').append('
');
+ }
+ this.dragTooltipContainer = $('.drag-mousemove-container');
+ this.enableSorting();
+ }
+
+ dispose() {
+ this.$el.off();
+ }
+
+ disableSorting() {
+ this.isSortingEnabled = false;
+ }
+
+ enableSorting() {
+ this.isSortingEnabled = true;
+ }
+
+ /*initialize(options) {
+ this.listenTo(this.model, 'change:_selected', this.onModelChanged);
+ }
+ onModelChanged() {
+ if( this.model.get('_selected') === true) {
+ this.$el.addClass(this.options.selectionClass);
+ } else {
+ this.$el.removeClass(this.options.selectionClass);
+ }
+ }*/
+
+ onMouseDown(e) {
+ }
+
+ onMouseUp(e) {
+ if (!this.isSortingEnabled) return;
+
+ let isSelected = this.$el.hasClass(this.options.selectionClass);
+ // if selection has more than one item, then user drag
+
+ if (!this.isMultipleModifier(e)) {
+ let selectedModels = this.options.collection.getSelection();
+
+ // if selection is 1 or 0, then do something - else user is dragging
+ if (selectedModels.length < 2) {
+ // remove previous selection if multpile modifier not active
+ this.clearSelection();
+ if (isSelected) {
+ // remove selection:
+ this.removeSelection(this.model);
+ } else {
+ // is not already selected:
+ this.addSelection(this.model);
+ }
+ } else {
+ // if there is a multiselection and modifier is not active
+ this.clearSelection();
+ // then select clicked one:
+ this.addSelection(this.model);
+ }
+ } else {
+ if (e.shiftKey) {
+ let collection = this.options.collection;
+ let currentIndex = collection.getIndex(this.model);
+ let firstModel = collection.getFirstSelected();
+ let firstIndex = collection.getIndex(firstModel);
+ let lastModel = collection.getLastSelected();
+ let lastIndex = collection.getIndex(lastModel);
+ // get first selection offset
+ // get last selected offset
+ // get current
+ this.clearSelection();
+ let models = collection.get()
+ if (firstIndex < currentIndex) {
+ for (let i = firstIndex; i < currentIndex; i++) {
+ this.addSelection(models[i]);
+ }
+ } else {
+ for (let i = lastIndex; i > currentIndex; i--) {
+ this.addSelection(models[i]);
+ }
+ }
+ }
+ // with multiple modifier
+ if (isSelected) {
+ // remove from selection
+ this.removeSelection(this.model);
+ } else {
+ // add to selection
+ this.addSelection(this.model);
+ }
+ }
+ this.selectionChange();
+
+ }
+
+ onDrag() {
+ if (!this.isSortingEnabled) return;
+ }
+
+ onDragStart(e) {
+ if (!this.isSortingEnabled) return;
+
+ let isSelected = this.$el.hasClass(this.selectionClass);
+
+ // jquery ui sortable: http://jsfiddle.net/hQnWG/614/
+ //if the element's parent is not the owner, then block this event
+ if (
+ this.isMultipleModifier(e)
+ &&
+ e.target.getAttribute('aria-grabbed') === 'false'
+ ) {
+ this.clearSelection();
+ //add this additional selection
+ this.addSelection(this.model); //e.target
+ } else {
+ // if start drag a non selected model, add the model to selection:
+ if (!isSelected) {
+ this.clearSelection();
+ this.$el.addClass(this.options.selectionClass);
+ this.addSelection(this.model);
+ }
+ }
+
+ this.options.draggedModel = this.model;
+ this.$el.attr('aria-grabbed', 'true');
+ this.selectionChange();
+ }
+
+ onDragEnter(e) {
+ if (!this.isSortingEnabled) return;
+ e.preventDefault();
+ this.$el.addClass(this.options.overClass);
+ }
+
+ onDragLeave(e) {
+ if (!this.isSortingEnabled) return;
+ e.preventDefault();
+ this.$el.removeClass(this.options.overClass);
+ }
+
+ onDragOver(e) {
+ if (!this.isSortingEnabled) return;
+ e.preventDefault();
+
+ return false;
+ }
+
+ drop(e) {
+ if (!this.isSortingEnabled) return;
+ e.preventDefault();
+ this.onDragLeave(e);
+ let selectedModels = [];
+ let collection = this.options.collection.get();
+ let toIndex = this.$el.index();
+
+ selectedModels = this.options.collection.getSelection();
+
+ for (let i = selectedModels.length; i--;) {
+ let fromIndex = this.options.collection.getIndex(this.options.collection.get(selectedModels[i]));
+
+ collection.splice(toIndex, 0, this.options.collection.splice(fromIndex, 1)[0]);
+ }
+
+ this.options.collection.reset(collection);
+ }
+
+ /**
+ * trigger multiple selection with keyboard modifier
+ */
+ isMultipleModifier(e) {
+ return (e.ctrlKey || e.metaKey || e.shiftKey);
+ }
+
+ clearSelection() {
+ this.options.collection.resetSelection();
+ }
+
+ addSelection(model) {
+ this.options.collection.addToSelection(model);
+ }
+
+ removeSelection(model) {
+ this.options.collection.removeFromSelection(model);
+ }
+
+ selectionChange() {
+ //this.triggerMethod('selection:changed', this.options.collection.getSelection());
+ }
+}
+
+export default SortableComponent;
diff --git a/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/style/buttons.scss b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/style/buttons.scss
new file mode 100644
index 0000000000..563a3b5616
--- /dev/null
+++ b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/style/buttons.scss
@@ -0,0 +1,73 @@
+.button {
+ /* Structure */
+ display: inline-block;
+ zoom: 1;
+ white-space: nowrap;
+ vertical-align: middle;
+ text-align: center;
+ cursor: pointer;
+ user-select: none;
+ box-sizing: border-box;
+ font-size: 13px;
+ padding: 3px 10px;
+ line-height: 17px;
+}
+
+/* Firefox: Get rid of the inner focus border */
+.button::-moz-focus-inner {
+ padding: 0;
+ border: 0;
+}
+
+
+.button {
+ color: #FFF; /* rgba not supported (IE 8) */
+ color: rgba(255, 255, 255, 0.80); /* rgba supported */
+ border: 1px solid #000; /*IE 6/7/8*/
+ border: none rgba(0, 0, 0, 0); /*IE9 + everything else*/
+ background-color: #000;
+ text-decoration: none;
+ border-radius: 0px;
+}
+.button-hover,
+.button:hover,
+.button:focus {
+ background-color: #0c4554;
+ // filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#1a000000',GradientType=0);
+ // background-image: -webkit-gradient(linear, 0 0, 0 100%, from(transparent), color-stop(40%, rgba(0,0,0, 0.05)), to(rgba(0,0,0, 0.10)));
+ // background-image: -webkit-linear-gradient(transparent, rgba(0,0,0, 0.05) 40%, rgba(0,0,0, 0.10));
+ // background-image: -moz-linear-gradient(top, rgba(0,0,0, 0.05) 0%, rgba(0,0,0, 0.10));
+ // background-image: -o-linear-gradient(transparent, rgba(0,0,0, 0.05) 40%, rgba(0,0,0, 0.10));
+ // background-image: linear-gradient(transparent, rgba(0,0,0, 0.05) 40%, rgba(0,0,0, 0.10));
+}
+.button:focus {
+ outline: 0;
+}
+.button-active,
+.button:active {
+ box-shadow: 0 0 0 1px rgba(0,0,0, 0.15) inset, 0 0 30px rgba(0,0,0, .3) inset;
+ border-color: #000\9;
+ background-color: #0c4554;
+}
+
+.button[disabled],
+.button-disabled,
+.button-disabled:hover,
+.button-disabled:focus,
+.button-disabled:active {
+ border: none;
+ background-image: none;
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+ filter: alpha(opacity=40);
+ -khtml-opacity: 0.40;
+ -moz-opacity: 0.40;
+ opacity: 0.40;
+ cursor: not-allowed;
+ box-shadow: none;
+}
+
+.button-primary,
+.button-selected {
+ background-color: #076882;
+ color: #fff;
+}
\ No newline at end of file
diff --git a/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/style/main.scss b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/style/main.scss
new file mode 100644
index 0000000000..3892c0a3b4
--- /dev/null
+++ b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/style/main.scss
@@ -0,0 +1,54 @@
+$asset-theme-path: './assets/images/';
+$icon-font-path: '../../../../../node_modules/videojs-font/fonts' ;
+// this file is loaded via include path - relative to the root of project...
+@import "../../../../../node_modules/video.js/src/css/variables";
+@import "../../../../../node_modules/video.js/src/css/private-variables";
+@import "../../../../../node_modules/video.js/src/css/utilities";
+
+@import "../../../../../node_modules/videojs-font/scss/icons";
+
+@import "../../../../../node_modules/video.js/src/css/components/layout";
+@import "../../../../../node_modules/video.js/src/css/components/big-play";
+//@import "../../../../../node_modules/video.js/src/css/components/button";
+@import "../../../../../node_modules/video.js/src/css/components/close-button";
+
+@import "../../../../../node_modules/video.js/src/css/components/menu/menu";
+@import "../../../../../node_modules/video.js/src/css/components/menu/menu-popup";
+@import "../../../../../node_modules/video.js/src/css/components/menu/menu-inline";
+
+@import "../../../../../node_modules/video.js/src/css/components/control-bar";
+@import "../../../../../node_modules/video.js/src/css/components/control";
+@import "../../../../../node_modules/video.js/src/css/components/control-spacer";
+
+@import "../../../../../node_modules/video.js/src/css/components/progress";
+@import "../../../../../node_modules/video.js/src/css/components/slider";
+
+@import "../../../../../node_modules/video.js/src/css/components/volume";
+
+@import "../../../../../node_modules/video.js/src/css/components/poster";
+@import "../../../../../node_modules/video.js/src/css/components/live";
+@import "../../../../../node_modules/video.js/src/css/components/time";
+@import "../../../../../node_modules/video.js/src/css/components/play-pause";
+@import "../../../../../node_modules/video.js/src/css/components/text-track";
+@import "../../../../../node_modules/video.js/src/css/components/fullscreen";
+@import "../../../../../node_modules/video.js/src/css/components/playback-rate";
+@import "../../../../../node_modules/video.js/src/css/components/error";
+@import "../../../../../node_modules/video.js/src/css/components/loading";
+@import "../../../../../node_modules/video.js/src/css/components/captions";
+@import "../../../../../node_modules/video.js/src/css/components/chapters";
+@import "../../../../../node_modules/video.js/src/css/components/subtitles";
+@import "../../../../../node_modules/video.js/src/css/components/adaptive";
+@import "../../../../../node_modules/video.js/src/css/components/captions-settings";
+@import "../../../../../node_modules/video.js/src/css/components/modal-dialog";
+@import "buttons";
+@import 'rangeCapture';
+@import 'skin';
+@import 'skin-big-play';
+@import 'tooltip';
+@import 'slider';
+
+.video-js-box, video.video-js {
+ width: 100%;
+ height: 100%;
+}
+
diff --git a/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/style/rangeCapture.scss b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/style/rangeCapture.scss
new file mode 100644
index 0000000000..6a6a04fded
--- /dev/null
+++ b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/style/rangeCapture.scss
@@ -0,0 +1,584 @@
+
+
+.video-js .vjs-control-bar,
+.vjs-control-bar {
+ bottom: 4em;
+}
+.PNB10 {
+ &.video-range-editor-container {
+ padding-top: 0;
+ padding-left: 0;
+ }
+}
+.video-range-editor-container {
+ height: 100%;
+ #embed-video {
+ overflow: hidden;
+ height: 100%;
+ }
+ overflow: auto;
+ #display-current {
+ cursor: pointer;
+ position: relative;
+ display: inline-block;
+ }
+ .icon {
+ display: inline-block;
+ width: 16px;
+ height: 16px;
+ font-size: 16px;
+ fill: currentColor;
+ }
+ .icon-label {
+ display: none;
+ }
+ .display-time {
+ padding: 0 10px;
+ text-align: center;
+ }
+ .control-button {
+ background: none;
+ border: none;
+ color: inherit;
+ display: inline-block;
+
+ overflow: visible; // IE8
+ font-size: inherit; // IE in general. WTF.
+ line-height: inherit;
+ text-transform: none;
+ text-decoration: none;
+ transition: none;
+
+ appearance: none;
+
+
+ width: 35px;
+ height: 30px;
+ margin: auto;
+ padding: 0;
+ flex: none;
+ outline: none;
+ position: relative;
+ text-align: center;
+ margin: 0;
+ padding: 0;
+ height: 100%;
+ &.active {
+ box-shadow: 0 0 0 1px rgba(0,0,0, 0.15) inset, 0 0 30px rgba(0,0,0, 0.7) inset;
+ border-color: #000\9;
+ background-color: #076882;
+ }
+
+ }
+
+ input.range-input {
+ background: none;
+ background-color: transparent;
+ border: none;
+ box-shadow: none;
+ font-size: 12px;
+ width: 20px;
+ margin: 0;
+ margin-top: -2px;
+ padding: 0px 1px;
+ color: #FFF;
+ display: inline-block;
+ &:focus {
+ box-shadow: 0 0 5px rgba(81, 203, 238, 1);
+ //border: 1px solid rgba(81, 203, 238, 1);
+ &.has-error {
+ box-shadow: 0 0 5px rgba(255, 0, 0, 1);
+ }
+ &.is-valid {
+ box-shadow: 0 0 5px rgba(0, 255, 0, 1);
+ }
+ }
+ &.has-error {
+ box-shadow: 0 0 5px rgba(255, 0, 0, 1);
+ }
+ &.is-valid {
+ box-shadow: 0 0 5px rgba(0, 255, 0, 1);
+ }
+ &.range-title {
+ width: 100%;
+ font-family: Roboto, sans-serif;
+ font-size: 15px;
+ font-weight: 500;
+ color: #ffffff;
+ }
+ // need to be separated, otherwise ignored (http://stackoverflow.com/questions/2610497/change-an-inputs-html5-placeholder-color-with-css)
+ &::-webkit-input-placeholder { /* WebKit, Blink, Edge */
+ font-style: italic;
+ color: #fff;
+ }
+ &:-moz-placeholder { /* Mozilla Firefox 4 to 18 */
+ font-style: italic;
+ color: #fff;
+ opacity: 1;
+ }
+ &::-moz-placeholder { /* Mozilla Firefox 19+ */
+ font-style: italic;
+ color: #fff;
+ opacity: 1;
+ }
+ &:-ms-input-placeholder { /* Internet Explorer 10-11 */
+ font-style: italic;
+ color: #fff;
+ }
+ }
+ .progress-container {
+ position: relative;
+ background-color: #000;
+ width: 100%;
+ height: 13px;
+ box-sizing: border-box;
+ border-radius: 2px;
+ border: 1px solid #054a5d;
+ .progress-bar {
+ position: absolute;
+ background-color: #72CEFD;
+
+ }
+ .progress-value {
+ font-size: 10px;
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ text-align: center;
+ }
+ }
+ .video-player-container {
+ left: 30%;
+ width: 70%;
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ right: 0;
+ margin: 4px;
+ }
+}
+
+#prod-tool-box .btn-container{
+ margin: 10px 0px;
+ text-align: center;
+ position: relative;
+ &.video-subtitle-left-button {
+ margin: 0;
+ }
+ .btn {
+ border-radius: 15px;
+ padding-left: 10px;
+ padding-right: 10px;
+ background: #525252;
+ border: 1px solid #fff;
+ color: #fff;
+ font-family: Roboto, sans-serif;
+ font-size: 12px;
+ font-weight: 500;
+ font-style: normal;
+ margin: 0 10px;
+ box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2), 0 4px 16px 0 rgba(0, 0, 0, 0.19);
+ &.btn-blue {
+
+ }
+ &.add-range, &.add-btn {
+ border: 1px solid #aa46bb;
+ }
+ &:hover {
+ border: 1px solid #aa46bb;
+ background: #aa46bb;
+ }
+ }
+}
+.range-control-bar {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ .range-capture-container {
+ background-color: rgba(0,0,0,0.8);
+ height: 30px;
+ display: flex;
+ box-sizing: border-box;
+ width: 100%;
+ justify-content: space-between;
+ font-size: 12px;
+ font-family: Roboto, sans-serif;
+ > span {
+ margin: auto;
+ flex-grow: 2;
+ }
+ }
+ .control-button {
+ width: 26px;
+ height: 30px;
+ margin: auto;
+ }
+ .display-time {
+ padding: 0 3px;
+ font-size: 11px;
+ }
+}
+
+.range-item-container {
+ position: absolute;
+ width: 30%;
+ top: 0;
+ background-color: rgba(82, 82, 82, 1);
+ height: 100%;
+ padding-left: 4px;
+ padding-right: 4px;
+ .range-collection-container {
+ margin-top: 48px;
+ overflow: auto;
+ position: relative;
+ .range-item-index-div {
+ padding: 0;
+ width: 22px;
+ text-align: center;
+ background: #aa46bb;
+ span {
+ line-height: 60px;
+ font-family: Roboto, sans-serif;
+ font-size: 13px;
+ font-weight: 500;
+ color: #ffffff;
+ }
+ }
+ }
+ .header-chapters {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ height: 48px;
+ margin-left: 4px;
+ margin-right: 4px;
+ border-bottom: 1px solid #484848;
+ padding: 4px;
+ h4 {
+ color: #ffffff;
+ font-family: Roboto, sans-serif;
+ font-size: 14px;
+ }
+ .checkbox-chapters {
+ display: block;
+ text-align: right;
+ color: #ffffff;
+ font-family: Roboto, sans-serif;
+ font-size: 12px;
+ input {
+ margin: 0 4px 0 0;
+ }
+ span {
+ line-height: 16px;
+ }
+ }
+ }
+ .range-collection-item {
+ border-bottom: 1px solid #484848;
+ box-sizing: content-box;
+ height: 60px;
+ display: flex;
+ justify-content: space-between;
+ font-size: 12px;
+ font-family: Roboto, sans-serif;
+ position: relative;
+ cursor: pointer;
+ margin-left: 4px;
+ margin-right: 4px;
+ // padding-left: 20px;
+ * {
+ user-drag: none;
+ user-select: none;
+ -moz-user-select: none;
+ -webkit-user-drag: none;
+ -webkit-user-select: none;
+ -ms-user-select: none;
+ }
+ .range-item-screenshot {
+ padding: 0 10px 0 0;
+ position: relative;
+ img {
+ min-width: 90px;
+ }
+ #capture-thumbnail-icon {
+ background-image: url("/assets/common/images/icons/capture-chapter.png");
+ background-position: center;
+ background-repeat: no-repeat;
+ background-size: contain;
+ width: 36px;
+ height: 36px;
+ position: absolute;
+ right: 4px;
+ display: none;
+ }
+ }
+ .range-item-index {
+ text-align: center;
+ }
+ .range-item-title {
+ padding-left: 10px;
+ padding-right: 10px;
+ flex-grow: 3;
+ box-sizing: border-box;
+ }
+ .range-item-time-data {
+ flex-grow: 3;
+ padding: 0;
+ .display-time {
+ font-size: 11px;
+ padding: 0 3px;
+ }
+ .display-time-container {
+ text-align: center;
+ }
+ }
+ .spacer {
+ flex-grow: 2;
+ }
+ > span {
+ margin: auto;
+ }
+ &.active {
+ // border: 2px solid rgba(255,255,255,0.1);
+ //box-shadow: 0 0 0 1px rgba(0,0,0, 0.15) inset, 0 0 30px rgba(0,0,0, 0.7) inset;
+ border-color: #000\9;
+ background-color: rgba(137, 76, 148, 0.6);
+ .progress-bar {
+ background-color: #aa46bb;
+ }
+ span {
+ color: #FFF;
+ }
+ .range-item-screenshot {
+ #capture-thumbnail-icon {
+ display: block;
+ }
+ }
+ }
+ .icon-container {
+ width: 40px;
+ height: 30px;
+ margin: 0;
+ padding: 0;
+ vertical-align: middle;
+
+ white-space: nowrap;
+ text-align: center;
+ display: inline-block;
+ line-height: 36px;
+ &.small-icon {
+ width: 16px;
+ height: 16px;
+ vertical-align: sub;
+ line-height: 16px;
+ }
+ }
+ &.drag-selected {
+ // background-color: #3FAB8F;
+ opacity: .2;
+ }
+ //&:after {
+ // content: '';
+ // position: absolute;
+ // box-sizing: border-box;
+ // left: 5px;
+ // top: 10%;
+ // height: 80%;
+ // width: 6px;
+ // border: 2px dotted rgba(0, 0, 0, 0.1);
+ // background: transparent;
+ // cursor: move;
+ //}
+ //&:hover {
+ // &:after {
+ // border: 2px dotted rgba(0, 0, 0, 0.3);
+ // }
+ //}
+ &.drag-over {
+ background-color: transparent;
+ border: 3px dotted rgba(0, 0, 0, 0.3);
+ &:after {
+ display: none;
+ }
+ > * {
+ visibility: hidden;
+
+ }
+ }
+ &.over:after {
+ display: none;
+ }
+ .range-item-close {
+ flex-grow: 1;
+ .remove-range {
+ cursor: pointer;
+ width: 20px;
+ height: 100%;
+ background-image: url("/assets/common/images/icons/picto-delete.png");
+ background-position: center;
+ background-repeat: no-repeat;
+ background-size: contain;
+ margin: 0 auto;
+ }
+ .remove-range:hover {
+ background-image: url("/assets/common/images/icons/picto-delete-hover.png");
+ }
+ }
+ }
+}
+.vjs-fullscreen {
+ .range-control-bar {
+ position: absolute;
+ bottom: 0;
+ }
+ .video-player-container {
+ left: 0%;
+ width: 100%;
+ }
+ .range-item-container {
+ position: absolute;
+ top: 40px;
+ width: 400px;
+ right: 20px;
+ margin: 0;
+ padding: 10px 10px 0px 10px;
+ background-color: rgba(82, 82, 82, 0.9);
+ height: auto;
+ margin-left: 0;
+ margin-right: 0;
+ .range-collection-container {
+ overflow-y: auto;
+ max-height: 600px;
+ position: relative;
+ }
+ .btn-container {
+ position: relative;
+ }
+ }
+ .vjs-control-bar {
+ bottom: 4em;
+ }
+}
+.vjs-mini-screen {
+ .range-item-container {
+ .range-collection-container {
+ margin-top: 48px;
+ .range-collection-item {
+ margin-left: 0px;
+ margin-right: 0px;
+ .range-item-screenshot {
+ padding-right: 3px;
+ }
+ .range-item-time-data, .range-item-index, .range-item-title {
+ padding: 4px 4px;
+ }
+ }
+ }
+ }
+ input.range-input {
+ width: 17px;
+ padding: 0;
+ font-size: 11px;
+ }
+
+}
+.video-range-editor-container {
+ .video-js .vjs-modal-dialog {
+ background: rgba(0,0,0,.8);
+ }
+}
+
+.vjs-modal-dialog-content {
+ overflow: auto;
+ bottom: 6em;
+ height: auto;
+ .vjs-hotkeys-modal {
+ .shortcut-label {
+ display: inline-block;
+ padding: 3px 10px;
+ color: #4d4d4d;
+ background-color: #FFF;
+ border-radius: 2px;
+ min-width: 30px;
+ text-align: center;
+ }
+ .dl-horizontal dt{
+ width: 200px;
+ color: #FFF;
+ }
+ &.video-tools-help {
+ h1 {
+ text-align: center;
+ }
+ .dl-horizontal dt {
+ width: 50%;
+ padding-right: 25px;
+ text-align: right;
+ }
+ }
+ }
+}
+.vjs-button {
+ background: none;
+ border: none;
+ color: inherit;
+ display: inline-block;
+
+ overflow: visible; // IE8
+ font-size: inherit; // IE in general. WTF.
+ line-height: inherit;
+ text-transform: none;
+ text-decoration: none;
+ transition: none;
+
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+}
+
+.video-js button.vjs-hotkeys-modal-button {
+ cursor: pointer;
+ height: 3em;
+ position: absolute;
+ right: 5px;
+ top: 0.5em;
+ z-index: 2;
+ // background-color: rgba(0,0,0, .4);
+ border-radius: 3px;
+ .vjs-control-text {
+ display: inline-block;
+ width: 20px;
+ height: 20px;
+ //font-size: 16px;
+ color: #FFF;
+ clip: inherit;
+ position: relative;
+ .fa-info {
+ color: #000;
+ }
+ }
+}
+
+
+.vjs-range-container {
+ position: relative;
+ // background-color: #FF0000;
+ // height: 100px;
+ top: -15px;
+ left: 0;
+ width: 100%;
+
+}
+
+.drag-mousemove-container {
+ position: absolute;
+ z-index: 9999;
+ ul {
+ margin: -6px 0 0 10px;
+ padding: 5px 10px;
+ background-color: rgba(0,0,0,0.5);
+ border-radius: 3px;
+ }
+}
diff --git a/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/style/skin-big-play.scss b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/style/skin-big-play.scss
new file mode 100644
index 0000000000..d5f8521932
--- /dev/null
+++ b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/style/skin-big-play.scss
@@ -0,0 +1,54 @@
+$big-play-button--height: 75px;
+.video-js .vjs-big-play-button {
+ font-size: 75px;
+ line-height: $big-play-button--height;
+ height: $big-play-button--height;
+ width: $big-play-button--width; // Firefox bug: For some reason without width the icon wouldn't show up. Switched to using width and removed padding.
+ display: block;
+ position: absolute;
+ top: 10px;
+ left: 10px;
+ padding: 0;
+ cursor: pointer;
+ opacity: 1;
+ border: none; //0.06666em solid $primary-foreground-color;
+ text-shadow: 0px 0px 7px rgba(0,0,0,0.55);
+ color: #FFF;
+ // Need a slightly gray bg so it can be seen on black backgrounds
+ // @include background-color-with-alpha($primary-background-color, $primary-background-transparency);
+ // @include border-radius(0.3em);
+ @include transition(all 0.4s);
+
+ @extend .vjs-icon-play;
+
+ // Since the big play button doesn't inherit from vjs-control, we need to specify a bit more than
+ // other buttons for the icon.
+ &:before {
+ @extend %icon-default;
+ }
+}
+
+// Allow people that hate their poster image to center the big play button.
+.vjs-big-play-centered .vjs-big-play-button {
+ top: 50%;
+ left: 50%;
+ margin-top: -($big-play-button--height / 2);
+ margin-left: -($big-play-button--width / 2);
+}
+
+.video-js:hover .vjs-big-play-button,
+.video-js .vjs-big-play-button:focus {
+ outline: 0;
+ //border-color: $primary-foreground-color;
+ background-color: transparent;
+ //@include background-color-with-alpha($secondary-background-color, $secondary-background-transparency);
+ // @include transition(all 0s);
+}
+
+// Hide if controls are disabled, the video is playing, or native controls are used.
+.vjs-controls-disabled .vjs-big-play-button,
+.vjs-has-started .vjs-big-play-button,
+.vjs-using-native-controls .vjs-big-play-button,
+.vjs-error .vjs-big-play-button {
+ display: none;
+}
diff --git a/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/style/skin.scss b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/style/skin.scss
new file mode 100644
index 0000000000..d70d0165c1
--- /dev/null
+++ b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/style/skin.scss
@@ -0,0 +1,218 @@
+// Video JS Sublime Skin
+// The following are SCSS variables to automate some of the values.
+// But don't feel limited by them. Change/replace whatever you want.
+
+// The color of icons, text, and the big play button border.
+// Try changing to #0f0
+$primary-foreground-color: #fff; // #fff default
+
+// The default color of control backgrounds is mostly black but with a little
+// bit of blue so it can still be seen on all-black video frames, which are common.
+// Try changing to #900
+$primary-background-color: #000; // #2B333F default
+
+// Try changing to true
+$center-big-play-button: true; // true default
+
+.video-js {
+ /* The base font size controls the size of everything, not just text.
+ All dimensions use em-based sizes so that the scale along with the font size.
+ Try increasing it to 15px and see what happens. */
+ font-size: 10px;
+
+ /* The main font color changes the ICON COLORS as well as the text */
+ color: $primary-foreground-color;
+}
+
+/* The "Big Play Button" is the play button that shows before the video plays.
+ To center it set the align values to center and middle. The typical location
+ of the button is the center, but there is trend towards moving it to a corner
+ where it gets out of the way of valuable content in the poster image.*/
+.vjs-sublime-skin .vjs-big-play-button {
+ /* The font size is what makes the big play button...big.
+ All width/height values use ems, which are a multiple of the font size.
+ If the .video-js font-size is 10px, then 3em equals 30px.*/
+ font-size: 8em;
+
+ /* We're using SCSS vars here because the values are used in multiple places.
+ Now that font size is set, the following em values will be a multiple of the
+ new font size. If the font-size is 3em (30px), then setting any of
+ the following values to 3em would equal 30px. 3 * font-size. */
+ $big-play-width: 3em;
+ /* 1.5em = 45px default */
+ $big-play-height: 1.5em;
+
+ line-height: $big-play-height;
+ height: $big-play-height;
+ width: $big-play-width;
+
+ /* 0.06666em = 2px default */
+ border: 0;
+ /* 0.3em = 9px default */
+ border-radius: 0.3em;
+
+ @if $center-big-play-button {
+ /* Align center */
+ left: 50%;
+ top: 50%;
+ margin-left: -($big-play-width / 2);
+ margin-top: -($big-play-height / 2);
+ } @else {
+ /* Align top left. 0.5em = 15px default */
+ left: 0.5em;
+ top: 0.5em;
+ }
+}
+
+/* The default color of control backgrounds is mostly black but with a little
+ bit of blue so it can still be seen on all-black video frames, which are common. */
+.video-js .vjs-control-bar,
+.video-js .vjs-big-play-button,
+.video-js .vjs-menu-button .vjs-menu-content {
+ /* IE8 - has no alpha support */
+ background-color: $primary-background-color;
+ /* Opacity: 1.0 = 100%, 0.0 = 0% */
+ background-color: rgba($primary-background-color, 0.7);
+ left: 2em;
+ right: 2em;
+
+ width: auto;
+ // bottom: 4em;
+ border-radius: 3px;
+}
+
+// Make a slightly lighter version of the main background
+// for the slider background.
+$slider-bg-color: lighten($primary-background-color, 33%);
+
+/* Slider - used for Volume bar and Progress bar */
+.video-js .vjs-slider {
+ background-color: $slider-bg-color;
+ background-color: rgba($slider-bg-color, 0.5);
+ background-color: rgba(255,255,255,.3);
+ border-radius: 2px;
+ height: 4px;
+}
+
+/* The slider bar color is used for the progress bar and the volume bar
+ (the first two can be removed after a fix that's coming) */
+.video-js .vjs-volume-level,
+.video-js .vjs-play-progress,
+.video-js .vjs-slider-bar {
+ background: $primary-foreground-color;
+}
+
+/* The main progress bar also has a bar that shows how much has been loaded. */
+.video-js .vjs-load-progress {
+ /* For IE8 we'll lighten the color */
+ background: ligthen($slider-bg-color, 25%);
+ /* Otherwise we'll rely on stacked opacities */
+ background: rgba($slider-bg-color, 0.5);
+}
+
+/* The load progress bar also has internal divs that represent
+ smaller disconnected loaded time ranges */
+.video-js .vjs-load-progress div {
+ /* For IE8 we'll lighten the color */
+ background: ligthen($slider-bg-color, 50%);
+ /* Otherwise we'll rely on stacked opacities */
+ background: rgba($slider-bg-color, 0.75);
+}
+
+//Skin Style Starts
+.vjs-sublime-skin .vjs-poster {
+ outline: none; //Remove Blue Outline on Click
+ outline: 0;
+}
+.vjs-sublime-skin:hover .vjs-big-play-button {
+ background-color: transparent;
+}
+.vjs-sublime-skin .vjs-fullscreen-control:before, .vjs-sublime-skin.vjs-fullscreen .vjs-fullscreen-control:before {
+ content: ''; //Remove Fullscreen Exit Icon
+}
+.vjs-sublime-skin.vjs-fullscreen .vjs-fullscreen-control {
+ background: #fff;
+}
+.vjs-sublime-skin .vjs-fullscreen-control {
+ border: 3px solid #fff;
+ box-sizing: border-box;
+ cursor: pointer;
+ margin-top: -7px;
+ top: 50%;
+ height: 14px;
+ width: 22px;
+ margin-right: 10px;
+}
+.vjs-sublime-skin.vjs-fullscreen .vjs-fullscreen-control:after {
+ background: #000;
+ content: "";
+ display: block;
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ height: 5px;
+ width: 5px;
+}
+.vjs-sublime-skin .vjs-progress-holder {
+ margin: 0;
+}
+.vjs-sublime-skin .vjs-progress-control .vjs-progress-holder:after {
+ border-radius: 2px;
+ display: block;
+ height: 4px;
+}
+.vjs-sublime-skin .vjs-progress-control .vjs-load-progres, .vjs-sublime-skin .vjs-progress-control .vjs-play-progress {
+ border-radius: 2px;
+ height: 4px;
+}
+.vjs-sublime-skin .vjs-playback-rate {
+ display: none; //Remove Playback Rate
+}
+.vjs-sublime-skin .vjs-progress-control {
+ margin-right: 40px;
+}
+.vjs-sublime-skin .vjs-time-control {
+ right: 40px;
+}
+.vjs-sublime-skin .vjs-mute-control:before, .vjs-sublime-skin .vjs-volume-menu-button:before, .vjs-sublime-skin .vjs-mute-control.vjs-vol-0:before, .vjs-sublime-skin .vjs-volume-menu-button.vjs-vol-0:before, .vjs-sublime-skin .vjs-mute-control.vjs-vol-1:before, .vjs-sublime-skin .vjs-volume-menu-button.vjs-vol-1:before, .vjs-sublime-skin .vjs-mute-control.vjs-vol-2:before, .vjs-sublime-skin .vjs-volume-menu-button.vjs-vol-2:before {
+ content: ''; //Remove Volume Icons
+}
+.vjs-sublime-skin .vjs-menu-button-inline .vjs-menu, .vjs-sublime-skin .vjs-menu-button-inline:focus .vjs-menu, .vjs-sublime-skin .vjs-menu-button-inline.vjs-slider-active .vjs-menu {
+ display: block;
+ opacity: 1;
+}
+.vjs-sublime-skin .vjs-volume-menu-button {
+ width: 3em;
+ position: absolute;
+ right: 0;
+ margin-right: 40px;
+}
+.vjs-sublime-skin .vjs-menu-button .vjs-menu-content, .vjs-sublime-skin .vjs-menu-button-inline:hover, .vjs-sublime-skin .vjs-menu-button-inline:focus, .vjs-sublime-skin .vjs-menu-button-inline.vjs-slider-active {
+ width: 3em;
+}
+.vjs-sublime-skin .vjs-menu-button-inline .vjs-menu {
+ left: 0; //Override to Align Volume To the Right Side
+}
+.vjs-sublime-skin .vjs-mouse-display:before, .vjs-sublime-skin .vjs-play-progress:before, .vjs-sublime-skin .vjs-volume-level:before {
+ content: ''; //Remove Circle from Progress Bar
+}
+.vjs-sublime-skin .vjs-volume-bar {
+ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAcCAQAAACw95UnAAAAMElEQVRIx2NgoBL4n4YKGUYNHkEG4zJg1OCRYDCpBowaPJwMppbLRg0eNXjUYBLEAXWNUA6QNm1lAAAAAElFTkSuQmCC);
+ background-size: 22px 14px;
+ background-repeat: no-repeat;
+ height: 100%;
+ width: 100%;
+ max-width: 22px;
+ max-height: 14px;
+ margin: 7px 4px;
+ border-radius: 0;
+}
+.vjs-sublime-skin .vjs-volume-level {
+ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAcAQAAAAAyhWABAAAAAnRSTlMAAHaTzTgAAAAZSURBVHgBYwAB/g9EUv+JokCqiaT+U4MCAPKPS7WUUOc1AAAAAElFTkSuQmCC);
+ background-size: 22px 14px;
+ background-repeat: no-repeat;
+ max-width: 22px;
+ max-height: 14px;
+ height: 100%;
+}
+
diff --git a/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/style/slider.scss b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/style/slider.scss
new file mode 100644
index 0000000000..2e365d04de
--- /dev/null
+++ b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/style/slider.scss
@@ -0,0 +1,50 @@
+@import "../../../../../node_modules/nouislider/distribute/nouislider.css";
+// sliders
+// create transparent sliders:
+.noUi-background {
+ background-color: transparent;
+}
+.noUi-target {
+ border: none;
+ box-shadow: none;
+ // box-shadow
+}
+.noUi-horizontal {
+ height: 9px;
+ .noUi-handle {
+ width: 8px;
+ height: 18px;
+ left: -4px;
+ top: -6px;
+ &::before {
+ top: 2px;
+ left: 2px;
+ }
+ &::after {
+ top: 2px;
+ left: 4px;
+ }
+ }
+}
+
+/* For this slider, disable the 'origin' size. */
+#connect .noUi-origin {
+ right: auto;
+ width: 0;
+}
+
+/* Position the bar and color it. */
+#connect .connect {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ background: #80c9f5;
+ // box-shadow: inset 0 0 3px rgba(51,51,51,0.45);
+}
+
+/* When the slider is moved by tap,
+ transition the connect bar like the handle. */
+#connect.noUi-state-tap .connect {
+ -webkit-transition: left 300ms, right 300ms;
+ transition: left 300ms, right 300ms;
+}
diff --git a/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/style/tooltip.scss b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/style/tooltip.scss
new file mode 100644
index 0000000000..15e80be45f
--- /dev/null
+++ b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/style/tooltip.scss
@@ -0,0 +1,69 @@
+.video-range-editor-container {
+ *[videotip]:before
+ {
+ content: "";
+ position: absolute;
+ border-bottom: 6px solid #000;
+ border-left: 6px solid transparent;
+ border-right: 6px solid transparent;
+ visibility: hidden;
+ opacity: 0; // for animation
+ left: -12px;
+ z-index: 9000;
+ }
+ *[videotip]:after
+ {
+ position: absolute;
+ content: attr(videotip);
+ left: -26px;
+ white-space: normal;
+ background: #000;
+ color: #FFFFFF;
+ padding: 4px 6px;
+ border-radius: 4px;
+ visibility: hidden;
+ opacity: 0; // for animation
+
+ z-index: 9001;
+ line-height: 15px;
+ font-size: 12px;
+ }
+
+ *[videotip]:hover:before, *[videotip]:hover:after
+ {
+ visibility: visible;
+ opacity: 1;
+ transition: opacity 0.2s ease-in;
+ }
+
+ button[videotip]{
+ // arrow
+ &:before {
+ top: 26px;
+ left: 15px;
+ }
+ // content
+ &:after {
+ top: 32px;
+ left: -20px;
+ width: 80px;
+ }
+ }
+
+ span[videotip]{
+ // arrow
+ &:before {
+ top: 18px;
+ left: 45%;
+ }
+ // content
+ &:after {
+ top: 24px;
+ left: 0px;
+ width: 100%;
+ }
+ }
+
+
+
+}
diff --git a/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/timecodeOverlay.js b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/timecodeOverlay.js
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/utils.js b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/utils.js
new file mode 100644
index 0000000000..1a42029c44
--- /dev/null
+++ b/Phraseanet-production-client/src/components/videoEditor/rangeCapturePlugin/utils.js
@@ -0,0 +1,64 @@
+const formatMilliseconds = (currentTime, frameRate) => {
+ let hours = 0;
+ let minutes = 0;
+ let seconds = 0;
+ let currentFrames = 0;
+ if (currentTime > 0) {
+ hours = Math.floor(currentTime / 3600);
+ let s = currentTime - hours * 3600;
+ minutes = Math.floor(s / 60);
+ seconds = Math.floor(s - minutes * 60);
+ let currentRest = currentTime - (Math.floor(currentTime));
+ currentFrames = Math.round(frameRate * currentRest);
+ }
+ return {
+ hours: hours,
+ minutes: minutes,
+ seconds: seconds,
+ frames: currentFrames
+ }
+}
+
+const formatTime = (currentTime, format, frameRate) => {
+ frameRate = frameRate || 24;
+ let hours = 0;
+ let minutes = 0;
+ let seconds = 0;
+ let milliseconds = 0;
+ let frames = 0;
+ if (currentTime > 0) {
+ hours = Math.floor(currentTime / 3600);
+ let s = currentTime - hours * 3600;
+ minutes = Math.floor(s / 60);
+ seconds = Math.floor(s - minutes * 60);
+ // keep only milliseconds rest ()
+ milliseconds = (currentTime - (Math.floor(currentTime))).toFixed(3);
+ frames = Math.round(frameRate * milliseconds);
+ // if( currentFrames >= )
+ }
+ switch (format) {
+ // standard vtt format
+ case 'hh:mm:ss.mmm':
+ return ('0' + hours).slice(-2) + ':' + ('0' + minutes).slice(-2) + ':' + ('0' + seconds).slice(-2) + '.' + ('00' + milliseconds).slice(-3) + '';
+ case 'hms':
+ let formatedOutput = [];
+ if (hours > 0) {
+ formatedOutput.push(('0' + hours).slice(-2) + 'h');
+ }
+
+ formatedOutput.push(('0' + minutes).slice(-2) + 'm');
+ formatedOutput.push(('0' + seconds).slice(-2) + 's');
+
+ return formatedOutput.join(' ');
+ case '':
+ default:
+ return ('0' + hours).slice(-2) + ':' + ('0' + minutes).slice(-2) + ':' + ('0' + seconds).slice(-2) + 's ' + ('0' + frames).slice(-2) + 'f';
+
+ }
+}
+
+const formatToFixedDecimals = (currentTime, decimalsPoints = 2) => {
+ return parseFloat(currentTime.toFixed(decimalsPoints));
+}
+
+export {formatMilliseconds, formatTime, formatToFixedDecimals}
diff --git a/Phraseanet-production-client/src/components/videoEditor/screenCapture.js b/Phraseanet-production-client/src/components/videoEditor/screenCapture.js
new file mode 100644
index 0000000000..308afdc257
--- /dev/null
+++ b/Phraseanet-production-client/src/components/videoEditor/screenCapture.js
@@ -0,0 +1,235 @@
+import Canva from './canvaImage';
+
+/**
+ * Image Object
+ * @param domElement
+ * @constructor
+ */
+const Image = function (domElement) {
+ this.domElement = domElement;
+};
+
+Image.prototype = {
+ getDomElement: function () {
+ return this.domElement;
+ },
+ getHeight: function () {
+ return this.domElement.offsetHeight;
+ },
+ getWidth: function () {
+ return this.domElement.offsetWidth;
+ }
+};
+
+/**
+ * Video Object inherits from Image object
+ * @param domElement
+ * @constructor
+ */
+const Video = function (domElement) {
+ Image.call(this, domElement);
+ this.aspectRatio = domElement.getAttribute('data-ratio');
+};
+
+Video.prototype = new Image();
+Video.prototype.constructor = Video;
+Video.prototype.getCurrentTime = function () {
+ return Math.floor(this.domElement.currentTime);
+};
+Video.prototype.getAspectRatio = function () {
+ return this.aspectRatio;
+};
+
+/**
+ * Cache Object
+ * @constructor
+ */
+const Store = function () {
+ this.datas = {};
+};
+
+Store.prototype = {
+ set: function (id, item) {
+ this.datas[id] = item;
+ return this;
+ },
+ get: function (id) {
+ if (!this.datas[id]) {
+ throw 'Unknown ID';
+ }
+ return this.datas[id];
+ },
+ remove: function (id) {
+ // never reuse same id
+ this.datas[id] = null;
+ },
+ getLength: function () {
+ let count = 0;
+ for (let k in this.datas) {
+ if (this.datas.hasOwnProperty(k)) {
+ ++count;
+ }
+ }
+ return count;
+ }
+};
+
+/**
+ * Screenshot Object
+ * @param id
+ * @param canva
+ * @param video
+ * @param altCanvas
+ * @constructor
+ */
+const ScreenShot = function (id, canva, video, altCanvas) {
+
+ const date = new Date();
+ canva.resize(video);
+ canva.copy(video);
+
+ // handle alternative canvas:
+ altCanvas = altCanvas === undefined ? [] : altCanvas;
+ this.altScreenShots = [];
+ if (altCanvas.length > 0) {
+ for (let i = 0; i < altCanvas.length; i++) {
+ let canvaEl = altCanvas[i].el;
+ canvaEl.resize(video);
+ canvaEl.copy(video);
+
+ this.altScreenShots.push({
+ dataURI: canvaEl.extractImage(),
+ name: altCanvas[i].name
+ });
+ }
+ }
+
+ this.id = id;
+ this.timestamp = date.getTime();
+ this.dataURI = canva.extractImage();
+ this.videoTime = video.getCurrentTime();
+
+};
+
+ScreenShot.prototype = {
+ getId: function () {
+ return this.id;
+ },
+ getDataURI: function () {
+ return this.dataURI;
+ },
+ getTimeStamp: function () {
+ return this.timestamp;
+ },
+ getVideoTime: function () {
+ return this.videoTime;
+ },
+ getAltScreenShots: function () {
+ return this.altScreenShots;
+ }
+};
+
+/**
+ * THUMB EDITOR
+ * @param videoId
+ * @param canvaId
+ * @param outputOptions
+ * @returns {{isSupported: isSupported, screenshot: screenshot, store: Store, copy: copy, getCanvaImage: getCanvaImage, resetCanva: resetCanva, getNbScreenshot: getNbScreenshot}}
+ * @constructor
+ */
+const ScreenCapture = function (videoId, canvaId, outputOptions) {
+ let editorVideo;
+ const domElement = document.getElementById(videoId);
+
+ if (domElement !== null) {
+ editorVideo = new Video(domElement);
+ }
+ const store = new Store();
+
+ function getCanva() {
+ return document.getElementById(canvaId);
+ }
+
+ outputOptions = outputOptions || {};
+
+ function setAltCanvas() {
+ let domElements = [];
+ let altCanvas = outputOptions.altCanvas;
+ if (altCanvas.length > 0) {
+ for (let i = 0; i < altCanvas.length; i++) {
+ domElements.push({
+ el: new Canva(altCanvas[i]),
+ width: altCanvas[i].getAttribute('data-width'),
+ name: altCanvas[i].getAttribute('data-name')
+ });
+ }
+ }
+ return domElements;
+ }
+
+ return {
+ isSupported: function () {
+ const elem = document.createElement('canvas');
+
+ return !!document.getElementById(videoId) && document.getElementById(canvaId)
+ && !!elem.getContext && !!elem.getContext('2d');
+ },
+ screenshot: function () {
+ const screenshot = new ScreenShot(
+ store.getLength() + 1,
+ new Canva(getCanva()),
+ editorVideo,
+ setAltCanvas()
+ );
+
+ store.set(screenshot.getId(), screenshot);
+
+ return screenshot;
+ },
+ store: store,
+ copy: function (mainSource, altSources) {
+
+ const elementDomNode = document.createElement('img');
+ elementDomNode.src = mainSource;
+
+ const element = new Image(elementDomNode);
+ const editorCanva = new Canva(getCanva());
+ const altEditorCanva = setAltCanvas();
+ editorCanva
+ .reset()
+ .resize(editorVideo)
+ .copy(element);
+
+
+ // handle alternative canvas:
+ if (altEditorCanva.length > 0) {
+ for (let i = 0; i < altEditorCanva.length; i++) {
+
+ let tmpEl = document.createElement('img');
+ tmpEl.src = altSources[i].dataURI;
+
+ const canvaEl = altEditorCanva[i].el;
+
+ canvaEl
+ .reset()
+ .resize(editorVideo, altEditorCanva[i].width)
+ .copy(new Image(tmpEl)); // @TODO: should copy the right stored image
+ }
+ }
+ },
+ getCanvaImage: function () {
+ const canva = new Canva(getCanva());
+
+ return canva.extractImage();
+ },
+ resetCanva: function () {
+ const editorCanva = new Canva(getCanva());
+ editorCanva.reset();
+ },
+ getNbScreenshot: function () {
+ return store.getLength();
+ }
+ };
+};
+
+export default ScreenCapture;
diff --git a/Phraseanet-production-client/src/empty.js b/Phraseanet-production-client/src/empty.js
new file mode 100644
index 0000000000..5c500dbf4a
--- /dev/null
+++ b/Phraseanet-production-client/src/empty.js
@@ -0,0 +1,5 @@
+/**
+ * karma no-op - for test only
+ * @type {{}}
+ */
+module.exports = {};
\ No newline at end of file
diff --git a/Phraseanet-production-client/src/lightbox-mobile/bootstrap.js b/Phraseanet-production-client/src/lightbox-mobile/bootstrap.js
new file mode 100644
index 0000000000..1c948a415c
--- /dev/null
+++ b/Phraseanet-production-client/src/lightbox-mobile/bootstrap.js
@@ -0,0 +1,289 @@
+import $ from 'jquery';
+import ConfigService from './../components/core/configService';
+import LocaleService from '../components/locale';
+import defaultConfig from './config';
+import Emitter from '../components/core/emitter';
+// import lightbox from './../components/lightbox/index';
+// import mainMenu from './../components/mainMenu';
+import merge from 'lodash.merge';
+require('./../phraseanet-common/components/tooltip');
+require('./../phraseanet-common/components/vendors/contextMenu');
+
+class Bootstrap {
+ app;
+ configService;
+ localeService;
+ appServices;
+ appLightbox;
+ validatorLoaded;
+ isReleasable;
+
+ constructor(userConfig) {
+ const configuration = merge({}, defaultConfig, userConfig);
+
+ this.appEvents = new Emitter();
+ this.configService = new ConfigService(configuration);
+ this.validatorLoaded = false;
+ this.localeService = new LocaleService({
+ configService: this.configService
+ });
+
+ this.localeService.fetchTranslations()
+ .then(() => {
+ this.onConfigReady();
+ });
+
+ return this;
+ }
+
+ onConfigReady() {
+ this.appServices = {
+ configService: this.configService,
+ localeService: this.localeService,
+ appEvents: this.appEvents
+ };
+
+ window.bodySize = {
+ x: 0,
+ y: 0
+ };
+
+ /**
+ * add components
+ */
+
+ $(document).ready(() => {
+ // let $body = $('body');
+ // window.bodySize.y = $body.height();
+ // window.bodySize.x = $body.width();
+ //
+ // this.appLightbox = lightbox(this.appServices);
+ // this.appLightbox.initialize({$container: $body});
+ //mainMenu(this.appServices).initialize({$container: $body});
+ this.mobileValidator();
+ // this.isReleasable = this.configService.get('releasable');
+ //
+ // if (this.isReleasable !== null) {
+ // this.appLightbox.setReleasable(this.isReleasable);
+ // }
+ });
+
+ }
+
+ mobileValidator() {
+
+ display_basket();
+
+ /*Get status before send validation*/
+ function _getReseaseStatus(el) {
+ $.ajax({
+ url: '/lightbox/ajax/GET_ELEMENTS/' + $('#basket_validation_id').val() + '/',
+ dataType: 'json',
+ error: function (data) {
+ $('.loader', el).css({
+ visibility: 'hidden'
+ });
+ },
+ timeout: function (data) {
+ $('.loader', el).css({
+ visibility: 'hidden'
+ });
+ },
+ success: function (data) {
+ $('.loader', el).css({
+ visibility: 'hidden'
+ });
+ if (data.datas) {
+ if (data.datas) {
+ if (data.datas.counts.nul == 0) {
+ _setRelease($(this));
+ }
+ else {
+ console.log(data.datas.counts);
+ $("#FeedbackRelease .record_accepted").html(data.datas.counts.yes);
+ $("#FeedbackRelease .record_refused").html(data.datas.counts.no);
+ $("#FeedbackRelease .record_null").html(data.datas.counts.nul);
+ $("#FeedbackRelease").modal("show");
+ }
+ }
+ }
+
+
+ return;
+ }
+ });
+ }
+
+ /*Send validation*/
+ function _setRelease(el) {
+ $.ajax({
+ type: 'POST',
+ url: '/lightbox/ajax/SET_RELEASE/' + $('#basket_validation_id').val() + '/',
+ dataType: 'json',
+ error: (data) => {
+ $('.loader', el).css({
+ visibility: 'hidden'
+ });
+ },
+ timeout: (data) => {
+ $('.loader', el).css({
+ visibility: 'hidden'
+ });
+ },
+ success: (data) => {
+ $('.loader', el).css({
+ visibility: 'hidden'
+ });
+ if (data.datas) {
+ // alert(data.datas);
+ window.location.href = "/lightbox";
+ }
+ if (!data.error) {
+ this.isReleasable = false;
+ //this.appLightbox.setReleasable(this.isReleasable);
+ }
+
+ return;
+ }
+ });
+ };
+
+ $('body').on('touchstart click', '.confirm_report', (event) => {
+ event.preventDefault();
+ const $el = $(event.currentTarget);
+ _getReseaseStatus($el);
+
+
+ return false;
+ });
+ $('body').on('touchstart click', '#validate-release', (event) => {
+ event.preventDefault();
+ $("#FeedbackRelease").modal("hide");
+ _setRelease($(this));
+ console.log('validation is done');
+
+
+ return false;
+ });
+
+ $('body').on('touchstart click', '.agreement_radio', (event) => {
+ event.preventDefault();
+ //$('.agreement_radio').on('mousedown', (event) => {
+ const $el = $(event.currentTarget);
+ var sselcont_id = $el.attr('for').split('_').pop();
+ var agreement = $('#' + $el.attr('for')).val() === 'yes' ? '1' : '-1';
+
+ $.mobile.loading();
+
+ $.ajax({
+ type: 'POST',
+ url: '/lightbox/ajax/SET_ELEMENT_AGREEMENT/' + sselcont_id + '/',
+ dataType: 'json',
+ data: {
+ agreement: agreement
+ },
+ error: function (datas) {
+ console.log('error');
+ $.mobile.loading();
+ },
+ timeout: function (datas) {
+ console.log('error');
+ $.mobile.loading();
+ },
+ success: (datas) => {
+ if (!datas.error) {
+ if (agreement === 1) {
+ $('.valid_choice_' + sselcont_id).removeClass('disagree').addClass('agree');
+ } else {
+ $('.valid_choice_' + sselcont_id).removeClass('agree').addClass('disagree');
+ }
+ $.mobile.loading();
+ if (datas.error) {
+ alert(datas.datas);
+ return;
+ }
+ this.isReleasable = datas.release;
+ //this.appLightbox.setReleasable(this.isReleasable);
+ window.location.reload();
+ } else {
+ console.log(datas.datas);
+ }
+ return;
+ }
+ });
+ //return false;
+
+ });
+
+ $('body').on('touchstart click', '.note_area_validate', (event) => {
+
+ const $el = $(event.currentTarget);
+ var sselcont_id = $el.closest('form').find('input[name="sselcont_id"]').val();
+
+ $.mobile.loading();
+ $.ajax({
+ type: 'POST',
+ url: '/lightbox/ajax/SET_NOTE/' + sselcont_id + '/',
+ dataType: 'json',
+ data: {
+ note: $('#note_form_' + sselcont_id).find('textarea').val()
+ },
+ error: function (datas) {
+ console.log('error');
+ $.mobile.loading();
+ },
+ timeout: function (datas) {
+ console.log('error');
+ $.mobile.loading();
+ },
+ success: function (datas) {
+ $.mobile.loading();
+ if (datas.error) {
+ console.log(datas.datas);
+ return;
+ }
+
+ $('#notes_' + sselcont_id).empty().append(datas.datas);
+ window.location.reload();
+ return;
+ }
+ });
+ return false;
+ });
+
+
+ function display_basket() {
+ let sc_wrapper = $('#sc_wrapper');
+
+
+ $('.basket_element', sc_wrapper).parent()
+ .bind('click', function (event) {
+ scid_click(event, this);
+ adjust_visibility(this);
+ return false;
+ });
+
+ $('.agree_button, .disagree_button', sc_wrapper).bind('click',function (event) {
+
+ var sselcont_id = $(this).closest('.basket_element').attr('id').split('_').pop();
+
+ var agreement = $(this).hasClass('agree_button') ? '1' : '-1';
+
+ set_agreement(event, $(this), sselcont_id, agreement);
+ return false;
+ }).addClass('clickable');
+
+ var n = $('.basket_element', sc_wrapper).length;
+ $('#sc_container').width(n * $('.basket_element_wrapper:first', sc_wrapper).outerWidth() + 1);
+
+ }
+
+ this.validatorLoaded = true;
+ }
+}
+
+const bootstrap = (userConfig) => {
+ return new Bootstrap(userConfig);
+};
+
+export default bootstrap;
diff --git a/Phraseanet-production-client/src/lightbox-mobile/config.js b/Phraseanet-production-client/src/lightbox-mobile/config.js
new file mode 100644
index 0000000000..7b4f8ce1c0
--- /dev/null
+++ b/Phraseanet-production-client/src/lightbox-mobile/config.js
@@ -0,0 +1,7 @@
+let defaultConfig = {
+ locale: 'fr',
+ basePath: '/',
+ translations: '/prod/language/',
+};
+
+export default defaultConfig;
diff --git a/Phraseanet-production-client/src/lightbox-mobile/index.js b/Phraseanet-production-client/src/lightbox-mobile/index.js
new file mode 100644
index 0000000000..397d9ba75a
--- /dev/null
+++ b/Phraseanet-production-client/src/lightbox-mobile/index.js
@@ -0,0 +1,58 @@
+import bootstrap from './bootstrap';
+let lightboxMobileApplication = {
+ bootstrap
+};
+
+if (typeof window !== 'undefined') {
+ window.lightboxMobileApplication = lightboxMobileApplication;
+}
+
+/*resize of PDF */
+$(window).on("load resize ",function(e){
+ if($('.pdf-iframe').length > 0) {
+ var pdfHeight = $('.pdf-iframe').width() / 0.707;
+ $('.pdf-iframe').css('height', pdfHeight);
+ }
+});
+/*resize of VIDEO */
+$(window).on("load resize ",function(e){
+ if($('.video-iframe').length > 0) {
+
+ var $sel = $('.center-image');
+ var $window = $(window).height();
+
+ // V is for "video" ; K is for "container" ; N is for "new"
+ var VH = $('[name=videoHeight]').val();
+ var VW = $('[name=videoWidth]').val();
+ var KW = $sel.width();
+ var KH = $sel.height();
+
+ if ($window <=375) {
+ KH = 150 ;
+ } else {
+ if ( $window > 375 && $window <=480) {
+ KH = 200 ;
+ }
+ if ($window > 480 && $window <=640) {
+ KH = 300 ;
+ }
+
+ if ( $window > 640 && $window <=767) {
+ KH = 400 ;
+ }
+ if ($window > 767) {
+ KH = 550 ;
+ }
+ }
+
+ var NW, NH;
+ if( (NH = (VH / VW) * (NW=KW) ) > KH ) { // try to fit exact horizontally, adjust vertically
+ // too bad... new height overflows container height
+ NW = (VW / VH) * (NH=KH); // so fit exact vertically, adjust horizontally
+ }
+ $(".video-iframe", $sel).css('width', NW).css('height', NH);
+
+ }
+});
+
+module.exports = lightboxMobileApplication;
diff --git a/Phraseanet-production-client/src/lightbox/bootstrap.js b/Phraseanet-production-client/src/lightbox/bootstrap.js
new file mode 100644
index 0000000000..8ace4fe0ee
--- /dev/null
+++ b/Phraseanet-production-client/src/lightbox/bootstrap.js
@@ -0,0 +1,82 @@
+import $ from 'jquery';
+import ConfigService from './../components/core/configService';
+import LocaleService from '../components/locale';
+import defaultConfig from './config';
+import Emitter from '../components/core/emitter';
+import lightbox from './../components/lightbox/index';
+import mainMenu from './../components/mainMenu';
+import merge from 'lodash.merge';
+require('./../phraseanet-common/components/tooltip');
+require('./../phraseanet-common/components/vendors/contextMenu');
+const humane = require('humane-js');
+
+class Bootstrap {
+ app;
+ configService;
+ localeService;
+ appServices;
+ appLightbox;
+
+ constructor(userConfig) {
+
+ const configuration = merge({}, defaultConfig, userConfig);
+
+ this.appEvents = new Emitter();
+ this.configService = new ConfigService(configuration);
+
+ this.localeService = new LocaleService({
+ configService: this.configService
+ });
+
+ this.localeService.fetchTranslations()
+ .then(() => {
+ this.onConfigReady();
+ });
+
+ return this;
+ }
+
+ onConfigReady() {
+ this.appServices = {
+ configService: this.configService,
+ localeService: this.localeService,
+ appEvents: this.appEvents
+ };
+
+ window.bodySize = {
+ x: 0,
+ y: 0
+ };
+
+ /**
+ * add components
+ */
+
+ $(document).ready(() => {
+ let $body = $('body');
+ window.bodySize.y = $body.height();
+ window.bodySize.x = $body.width();
+
+ lightbox(this.appServices).initialize({$container: $body});
+ mainMenu(this.appServices).initialize({$container: $body});
+
+ let isReleasable = this.configService.get('releasable');
+
+ if (isReleasable !== null) {
+ this.appLightbox.setReleasable(isReleasable);
+ }
+
+ humane.infoLarge = humane.spawn({addnCls: 'humane-libnotify-info humane-large', timeout: 5000});
+ humane.info = humane.spawn({addnCls: 'humane-libnotify-info', timeout: 1000});
+ humane.error = humane.spawn({addnCls: 'humane-libnotify-error', timeout: 1000});
+ humane.forceNew = true;
+ });
+
+ }
+}
+
+const bootstrap = (userConfig) => {
+ return new Bootstrap(userConfig);
+};
+
+export default bootstrap;
diff --git a/Phraseanet-production-client/src/lightbox/config.js b/Phraseanet-production-client/src/lightbox/config.js
new file mode 100644
index 0000000000..7b4f8ce1c0
--- /dev/null
+++ b/Phraseanet-production-client/src/lightbox/config.js
@@ -0,0 +1,7 @@
+let defaultConfig = {
+ locale: 'fr',
+ basePath: '/',
+ translations: '/prod/language/',
+};
+
+export default defaultConfig;
diff --git a/Phraseanet-production-client/src/lightbox/index.js b/Phraseanet-production-client/src/lightbox/index.js
new file mode 100644
index 0000000000..59b6df8580
--- /dev/null
+++ b/Phraseanet-production-client/src/lightbox/index.js
@@ -0,0 +1,34 @@
+import bootstrap from './bootstrap';
+let lightboxApplication = {
+ bootstrap
+};
+
+if (typeof window !== 'undefined') {
+ window.lightboxApplication = lightboxApplication;
+}
+
+
+$(window).on("load resize ",function(e) {
+ /* See more basket btn*/
+ $('.see_more_basket').on('click', function (e) {
+ see_more('basket');
+ });
+ $('.see_more_feed').on('click', function (e) {
+ see_more('feed');
+
+ });
+
+ function see_more(target) {
+ $('.other_' + target).toggleClass('hidden');
+ document.getElementById('see_more_' + target).scrollIntoView({
+ behavior: 'smooth'
+ });
+ document.getElementById('see_less_' + target).scrollIntoView({
+ behavior: 'smooth',
+ block: "start"
+ });
+ $('.see_more_' + target).toggleClass('hidden');
+ }
+
+});
+module.exports = lightboxApplication;
diff --git a/Phraseanet-production-client/src/permaview/bootstrap.js b/Phraseanet-production-client/src/permaview/bootstrap.js
new file mode 100644
index 0000000000..e2484e4930
--- /dev/null
+++ b/Phraseanet-production-client/src/permaview/bootstrap.js
@@ -0,0 +1,26 @@
+import ConfigService from './../components/core/configService';
+import defaultConfig from './config';
+import pym from 'pym.js';
+import merge from 'lodash.merge';
+class Bootstrap {
+ app;
+ configService;
+ ready;
+
+ constructor(userConfig) {
+ const configuration = merge({}, defaultConfig, userConfig);
+
+
+ this.configService = new ConfigService(configuration);
+
+ var pymParent = new pym.Parent('phraseanet-embed-frame', this.configService.get('recordUrl'));
+ pymParent.iframe.setAttribute('allowfullscreen', '');
+ return this;
+ }
+}
+
+const bootstrap = (userConfig) => {
+ return new Bootstrap(userConfig);
+};
+
+export default bootstrap;
diff --git a/Phraseanet-production-client/src/permaview/config.js b/Phraseanet-production-client/src/permaview/config.js
new file mode 100644
index 0000000000..9c3b85143b
--- /dev/null
+++ b/Phraseanet-production-client/src/permaview/config.js
@@ -0,0 +1,17 @@
+let defaultConfig = {
+ locale: 'fr',
+ basePath: '/',
+ translations: '/prod/language/',
+ previewSlideshow: {
+ duration: 4000
+ },
+ availableThemes: [{
+ name: '000000'
+ }, {
+ name: '959595'
+ }, {
+ name: 'FFFFFF'
+ }]
+};
+
+export default defaultConfig;
diff --git a/Phraseanet-production-client/src/permaview/index.js b/Phraseanet-production-client/src/permaview/index.js
new file mode 100644
index 0000000000..fa54bc9014
--- /dev/null
+++ b/Phraseanet-production-client/src/permaview/index.js
@@ -0,0 +1,12 @@
+require('./style/main.scss');
+import bootstrap from './bootstrap.js';
+
+let PermaviewApplication = {
+ bootstrap
+};
+
+if (typeof window !== 'undefined') {
+ window.PermaviewApplication = PermaviewApplication;
+}
+
+module.exports = PermaviewApplication;
diff --git a/Phraseanet-production-client/src/permaview/style/main.scss b/Phraseanet-production-client/src/permaview/style/main.scss
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/Phraseanet-production-client/src/phraseanet-common/components/common.js b/Phraseanet-production-client/src/phraseanet-common/components/common.js
new file mode 100644
index 0000000000..786d3179ed
--- /dev/null
+++ b/Phraseanet-production-client/src/phraseanet-common/components/common.js
@@ -0,0 +1,148 @@
+// @TODO enable lints
+/* eslint-disable max-len*/
+/* eslint-disable object-shorthand*/
+/* eslint-disable dot-notation*/
+/* eslint-disable vars-on-top*/
+/* eslint-disable prefer-template*/
+/* eslint-disable prefer-const*/
+/* eslint-disable spaced-comment*/
+/* eslint-disable curly*/
+/* eslint-disable object-curly-spacing*/
+/* eslint-disable spaced-comment*/
+/* eslint-disable prefer-arrow-callback*/
+/* eslint-disable one-var*/
+/* eslint-disable space-in-parens*/
+/* eslint-disable camelcase*/
+/* eslint-disable no-undef*/
+/* eslint-disable quote-props*/
+/* eslint-disable no-shadow*/
+/* eslint-disable no-param-reassign*/
+/* eslint-disable no-unused-expressions*/
+/* eslint-disable no-shadow*/
+/* eslint-disable no-implied-eval*/
+/* eslint-disable brace-style*/
+/* eslint-disable no-unused-vars*/
+/* eslint-disable brace-style*/
+/* eslint-disable no-lonely-if*/
+/* eslint-disable no-inline-comments*/
+/* eslint-disable default-case*/
+/* eslint-disable one-var*/
+/* eslint-disable semi*/
+/* eslint-disable no-throw-literal*/
+/* eslint-disable no-sequences*/
+/* eslint-disable consistent-this*/
+/* eslint-disable no-dupe-keys*/
+/* eslint-disable semi*/
+/* eslint-disable no-loop-func*/
+
+import $ from 'jquery';
+import dialog from './dialog';
+let cookie = require('js-cookie');
+
+const initialize = () => {
+ // $(document).ready(function () {
+
+ let locale = cookie.get('i18next');
+ if (locale === undefined) {
+ locale = 'en-GB';
+ }
+
+ let cache = $('#mainMenu .helpcontextmenu');
+ $('.context-menu-item', cache).hover(function () {
+ $(this).addClass('context-menu-item-hover');
+ }, function () {
+ $(this).removeClass('context-menu-item-hover');
+ });
+};
+
+// @deprecated
+function manageSession(data, showMessages) {
+ if (typeof (showMessages) === 'undefined')
+ showMessages = false;
+
+ if (data.status === 'disconnected' || data.status === 'session') {
+ disconnected();
+ return false;
+ }
+ if (showMessages) {
+ let box = $('#notification_box');
+ box.empty().append(data.notifications);
+
+ if (box.is(':visible'))
+ fix_notification_height();
+
+ if ($('.notification.unread', box).length > 0) {
+ let trigger = $('#notification_trigger');
+ $('.counter', trigger)
+ .empty()
+ .append($('.notification.unread', box).length);
+ $('.counter', trigger).css('visibility', 'visible');
+
+ }
+ else
+ $('#notification_trigger .counter').css('visibility', 'hidden').empty();
+
+ if (data.changed.length > 0) {
+ let current_open = $('.SSTT.ui-state-active');
+ let current_sstt = current_open.length > 0 ? current_open.attr('id').split('_').pop() : false;
+
+ let main_open = false;
+ for (let i = 0; i !== data.changed.length; i++) {
+ let sstt = $('#SSTT_' + data.changed[i]);
+ if (sstt.size() === 0) {
+ if (main_open === false) {
+ $('#baskets .bloc').animate({'top': 30}, function () {
+ $('#baskets .alert_datas_changed:first').show();
+ });
+ main_open = true;
+ }
+ }
+ else {
+ if (!sstt.hasClass('active'))
+ sstt.addClass('unread');
+ else {
+ $('.alert_datas_changed', $('#SSTT_content_' + data.changed[i])).show();
+ }
+ }
+ }
+ }
+ if ($.trim(data.message) !== '') {
+ if ($('#MESSAGE').length === 0)
+ $('body').append('
');
+ $('#MESSAGE')
+ .empty()
+ .append('
' + data.message + ' ' + language.hideMessage + '
')
+ .attr('title', 'Global Message')
+ .dialog({
+ autoOpen: false,
+ closeOnEscape: true,
+ resizable: false,
+ draggable: false,
+ modal: true,
+ close: function () {
+ if ($('.dialog_remove:checked', $(this)).length > 0) {
+ // setTemporaryPref
+ $.ajax({
+ type: 'POST',
+ url: '/user/preferences/temporary/',
+ data: {
+ prop: 'message',
+ value: 0
+ },
+ success: function (data) {
+ return;
+ }
+ });
+ }
+ }
+ })
+ .dialog('open');
+ }
+ }
+ return true;
+}
+
+export default {
+ initialize,
+ manageSession
+};
diff --git a/Phraseanet-production-client/src/phraseanet-common/components/dialog.js b/Phraseanet-production-client/src/phraseanet-common/components/dialog.js
new file mode 100644
index 0000000000..288b520323
--- /dev/null
+++ b/Phraseanet-production-client/src/phraseanet-common/components/dialog.js
@@ -0,0 +1,311 @@
+// @TODO enable lints
+/* eslint-disable max-len*/
+/* eslint-disable object-shorthand*/
+/* eslint-disable dot-notation*/
+/* eslint-disable vars-on-top*/
+/* eslint-disable prefer-template*/
+/* eslint-disable prefer-const*/
+/* eslint-disable spaced-comment*/
+/* eslint-disable curly*/
+/* eslint-disable object-curly-spacing*/
+/* eslint-disable spaced-comment*/
+/* eslint-disable prefer-arrow-callback*/
+/* eslint-disable one-let*/
+/* eslint-disable space-in-parens*/
+/* eslint-disable camelcase*/
+/* eslint-disable no-undef*/
+/* eslint-disable quote-props*/
+/* eslint-disable no-shadow*/
+/* eslint-disable no-param-reassign*/
+/* eslint-disable no-unused-expressions*/
+/* eslint-disable no-shadow*/
+/* eslint-disable no-implied-eval*/
+/* eslint-disable brace-style*/
+/* eslint-disable no-unused-vars*/
+/* eslint-disable brace-style*/
+/* eslint-disable no-lonely-if*/
+/* eslint-disable no-inline-comments*/
+/* eslint-disable default-case*/
+/* eslint-disable one-let*/
+/* eslint-disable semi*/
+/* eslint-disable no-throw-literal*/
+/* eslint-disable no-sequences*/
+/* eslint-disable consistent-this*/
+/* eslint-disable no-dupe-keys*/
+/* eslint-disable semi*/
+/* eslint-disable no-loop-func*/
+import $ from 'jquery';
+// jquery ui dependency
+
+function getLevel(level) {
+
+ level = parseInt(level, 10);
+
+ if (isNaN(level) || level < 1) {
+ return 1;
+ }
+
+ return level;
+}
+
+function getId(level) {
+ return 'DIALOG' + getLevel(level);
+}
+
+function addButtons(buttons, dialog) {
+ if (dialog.options.closeButton === true) {
+ buttons[dialog.services.localeService.t('fermer')] = function () {
+ dialog.close();
+ };
+ }
+ if (dialog.options.cancelButton === true) {
+ buttons[dialog.services.localeService.t('annuler')] = function () {
+ dialog.close();
+ };
+ }
+
+ return buttons;
+}
+
+const PhraseaDialog = function (services, options, level) {
+ const createDialog = function (level) {
+
+ let $dialog = $('#' + getId(level));
+
+ if ($dialog.length > 0) {
+ throw 'Dialog already exists at this level';
+ }
+
+ $dialog = $('
');
+ $('body').append($dialog);
+
+ return $dialog;
+ };
+
+ let defaults = {
+ size: 'Medium',
+ buttons: {},
+ loading: true,
+ title: '',
+ closeOnEscape: true,
+ confirmExit: false,
+ closeCallback: false,
+ closeButton: false,
+ cancelButton: false
+ };
+ let width;
+ let height;
+ let $dialog;
+ const $this = this;
+
+ options = typeof options === 'object' ? options : {};
+
+ this.closing = false;
+
+ this.options = $.extend(defaults, options);
+
+ this.services = services;
+
+ this.level = getLevel(level);
+
+ this.options.buttons = addButtons(this.options.buttons, this);
+
+ if (/\d+x\d+/.test(this.options.size)) {
+ let dimension = this.options.size.split('x');
+ height = dimension[1];
+ width = dimension[0];
+ } else {
+ switch (this.options.size) {
+ case 'Full':
+ height = bodySize.y - 30;
+ width = bodySize.x - 30;
+ break;
+ case 'Medium':
+ width = Math.min(bodySize.x - 30, 730);
+ height = Math.min(bodySize.y - 30, 520);
+ break;
+ default:
+ case 'Small':
+ width = Math.min(bodySize.x - 30, 420);
+ height = Math.min(bodySize.y - 30, 300);
+ break;
+ case 'Alert':
+ width = Math.min(bodySize.x - 30, 300);
+ height = Math.min(bodySize.y - 30, 150);
+ break;
+ case 'Custom':
+ width = Math.min(bodySize.x - 30, this.options.customWidth);
+ height = Math.min(bodySize.y - 30, this.options.customHeight);
+ break;
+ }
+ }
+
+ /*
+ * 3 avaailable dimensions :
+ *
+ * - Full | Full size ()
+ * - Medium | 420 x 450
+ * - Small | 730 x 480
+ *
+ **/
+ this.$dialog = createDialog(this.level);
+ this.zIndex = 5000 + parseInt(this.level, 10); //Math.min(this.level * 2000 + 5000, 32767);
+
+ let CloseCallback = function () {
+ if (typeof $this.options.closeCallback === 'function') {
+ $this.options.closeCallback($this.$dialog);
+ }
+
+ if ($this.closing === false) {
+ $this.closing = true;
+ $this.close();
+ }
+ };
+
+ if (this.$dialog.data('ui-dialog')) {
+ this.$dialog.dialog('destroy');
+ }
+
+ this.$dialog.attr('title', this.options.title)
+ .empty()
+ .dialog({
+ buttons: this.options.buttons,
+ draggable: false,
+ resizable: false,
+ closeOnEscape: this.options.closeOnEscape,
+ modal: true,
+ width: width,
+ height: height,
+ open: (event) => {
+ const $dialogEl = $(event.currentTarget);
+ //$(this)
+ $dialogEl.dialog('widget').css('z-index', this.zIndex);
+ },
+ close: CloseCallback
+ })
+ .dialog('open').addClass('dialog-' + this.options.size);
+
+ if (this.options.loading === true) {
+ this.$dialog.addClass('loading');
+ }
+
+ if (this.options.size === 'Full') {
+ let $this = this;
+ $(window).unbind('resize.DIALOG' + getLevel(level))
+ .bind('resize.DIALOG' + getLevel(level), function () {
+ if ($this.$dialog.data('ui-dialog')) {
+ $this.$dialog.dialog('option', {
+ width: bodySize.x - 30,
+ height: bodySize.y - 30
+ });
+ }
+ });
+ }
+
+ return this;
+};
+
+PhraseaDialog.prototype = {
+ close: function () {
+ dialog.close(this.level);
+ },
+ setContent: function (content) {
+ this.$dialog.removeClass('loading').empty().append(content);
+ },
+ getId: function () {
+ return this.$dialog.attr('id');
+ },
+ load: function (url, method, params) {
+ let $this = this;
+ this.loader = {
+ url: url,
+ method: typeof method === 'undefined' ? 'GET' : method,
+ params: typeof params === 'undefined' ? {} : params
+ };
+
+ $.ajax({
+ type: this.loader.method,
+ url: this.loader.url,
+ dataType: 'html',
+ data: this.loader.params,
+ beforeSend: function () {
+ },
+ success: function (data) {
+ $this.setContent(data);
+ return;
+ }
+ });
+ },
+ refresh: function () {
+ if (typeof this.loader === 'undefined') {
+ throw 'Nothing to refresh';
+ }
+ this.load(this.loader.url, this.loader.method, this.loader.params);
+ },
+ getDomElement: function () {
+ return this.$dialog;
+ },
+ getOption: function (optionName) {
+ if (this.$dialog.data('ui-dialog')) {
+ return this.$dialog.dialog('option', optionName);
+ }
+ return null;
+ },
+ setOption: function (optionName, optionValue) {
+ if (optionName === 'buttons') {
+ optionValue = addButtons(optionValue, this);
+ }
+ if (this.$dialog.data('ui-dialog')) {
+ this.$dialog.dialog('option', optionName, optionValue);
+ }
+ }
+};
+
+const Dialog = function () {
+ this.currentStack = {};
+};
+
+Dialog.prototype = {
+ create: function (services, options, level) {
+
+ if (this.get(level) instanceof PhraseaDialog) {
+ this.get(level).close();
+ }
+
+ let $dialog = new PhraseaDialog(services, options, level);
+
+ this.currentStack[$dialog.getId()] = $dialog;
+
+ return $dialog;
+ },
+ get: function (level) {
+
+ const id = getId(level);
+
+ if (id in this.currentStack) {
+ return this.currentStack[id];
+ }
+
+ return null;
+ },
+ close: function (level) {
+
+ $(window).unbind('resize.DIALOG' + getLevel(level));
+
+ this.get(level).closing = true;
+ let dialog = this.get(level).getDomElement();
+ if (dialog.data('ui-dialog')) {
+ dialog.dialog('close').dialog('destroy');
+ }
+ dialog.remove();
+
+ const id = this.get(level).getId();
+
+ if (id in this.currentStack) {
+ delete this.currentStack.id;
+ }
+ }
+};
+
+const dialog = new Dialog();
+export default dialog;
diff --git a/Phraseanet-production-client/src/phraseanet-common/components/tooltip.js b/Phraseanet-production-client/src/phraseanet-common/components/tooltip.js
new file mode 100644
index 0000000000..3cce6a10d1
--- /dev/null
+++ b/Phraseanet-production-client/src/phraseanet-common/components/tooltip.js
@@ -0,0 +1,970 @@
+// @TODO enable lints
+/* eslint-disable max-len*/
+/* eslint-disable object-shorthand*/
+/* eslint-disable dot-notation*/
+/* eslint-disable vars-on-top*/
+/* eslint-disable prefer-template*/
+/* eslint-disable prefer-const*/
+/* eslint-disable spaced-comment*/
+/* eslint-disable curly*/
+/* eslint-disable object-curly-spacing*/
+/* eslint-disable spaced-comment*/
+/* eslint-disable prefer-arrow-callback*/
+/* eslint-disable one-var*/
+/* eslint-disable space-in-parens*/
+/* eslint-disable camelcase*/
+/* eslint-disable no-undef*/
+/* eslint-disable quote-props*/
+/* eslint-disable no-shadow*/
+/* eslint-disable no-param-reassign*/
+/* eslint-disable no-unused-expressions*/
+/* eslint-disable no-shadow*/
+/* eslint-disable no-implied-eval*/
+/* eslint-disable brace-style*/
+/* eslint-disable no-unused-vars*/
+/* eslint-disable brace-style*/
+/* eslint-disable no-lonely-if*/
+/* eslint-disable no-inline-comments*/
+/* eslint-disable default-case*/
+/* eslint-disable one-var*/
+/* eslint-disable semi*/
+let pym = require('pym.js');
+/*
+ * jQuery Tooltip plugin 1.3
+ *
+ * http://bassistance.de/jquery-plugins/jquery-plugin-tooltip/
+ * http://docs.jquery.com/Plugins/Tooltip
+ *
+ * Copyright (c) 2006 - 2008 J�rn Zaefferer
+ *
+ * $Id: jquery.tooltip.js 5741 2008-06-21 15:22:16Z joern.zaefferer $
+ *
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ */
+($ => {
+ $(document).bind('keydown', function (event) {
+ if ($.tooltip === undefined) return;
+
+ if (event.keyCode === 27 && $.tooltip.blocked === true) {
+ unfixTooltip();
+ }
+ });
+
+ let activeThumbnailFrame;
+ // the tooltip element
+ let helper = {},
+ // the title of the current element, used for restoring
+ title,
+ // timeout id for delayed tooltips
+ tID,
+ // IE 5.5 or 6
+ IE =
+ navigator.userAgent.match(/msie/i) &&
+ /MSIE\s(5\.5|6\.)/.test(navigator.userAgent),
+ // flag for mouse tracking
+ track = false;
+
+ $.tooltip = {
+ blocked: false,
+ ajaxTimeout: false,
+ ajaxRequest: false,
+ ajaxEvent: false,
+ current: null,
+ visible: false,
+ defaults: {
+ delay: 700,
+ fixable: false,
+ fixableIndex: 100,
+ fade: true,
+ showURL: true,
+ outside: true,
+ isBrowsable: false,
+ extraClass: '',
+ top: 15,
+ left: 15,
+ id: 'tooltip'
+ },
+ block: function () {
+ $.tooltip.blocked = !$.tooltip.blocked;
+ },
+
+ delayAjax: function (a, b, c) {
+ let datas = {};
+ $.tooltip.ajaxRequest = $.ajax({
+ url: $.tooltip.current.tooltipSrc,
+ type: 'post',
+ data: datas,
+ success: function (data) {
+ title = data;
+ positioning($.tooltip.ajaxEvent);
+ },
+ error: function () {
+ return;
+ }
+ });
+ }
+ };
+
+ $.fn.extend({
+ tooltip: function (settings) {
+ settings = $.extend({}, $.tooltip.defaults, settings);
+ createHelper(settings);
+ return this.each(function () {
+ $.data(this, 'tooltip', settings);
+ // copy tooltip into its own expando and remove the title
+ this.tooltipText = $(this).attr('title');
+ this.tooltipSrc = $(this).attr('tooltipsrc');
+
+ this.ajaxLoad =
+ $.trim(this.tooltipText) === '' && this.tooltipSrc !== '';
+ this.ajaxTimeout;
+
+ this.orEl = $(this);
+ $(this).removeAttr('title');
+ // also remove alt attribute to prevent default tooltip in IE
+ this.alt = '';
+ })
+ .mouseover(save)
+ .mouseout(hide)
+ .mouseleave(function () {
+ if (settings.isBrowsable) {
+ $.tooltip.currentHover = false;
+ // close caption container after a small delay
+ // (safe travel delay of the mouse between thumbnail and caption / allow user to cross
+ // boundaries without unexpected closing of the catpion)
+ setTimeout(function () {
+ hide();
+ }, 500);
+ }
+ })
+ .mousedown(fix);
+ },
+ fixPNG: IE
+ ? function () {
+ return this.each(function () {
+ let image = $(this).css('backgroundImage');
+ if (image.match(/^url\(["']?(.*\.png)["']?\)$/i)) {
+ image = RegExp.$1;
+ $(this)
+ .css({
+ backgroundImage: 'none',
+ filter:
+ "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" +
+ image +
+ "')"
+ })
+ .each(function () {
+ let position = $(this).css('position');
+ if (
+ position !== 'absolute' &&
+ position !== 'relative'
+ )
+ $(this).css('position', 'relative');
+ });
+ }
+ });
+ }
+ : function () {
+ return this;
+ },
+ unfixPNG: IE
+ ? function () {
+ return this.each(function () {
+ $(this).css({
+ filter: '',
+ backgroundImage: ''
+ });
+ });
+ }
+ : function () {
+ return this;
+ },
+ hideWhenEmpty: function () {
+ return this.each(function () {
+ $(this)[$(this).html() ? 'show' : 'hide']();
+ });
+ },
+ url: function () {
+ return this.attr('href') || this.attr('src');
+ }
+ });
+
+ function createHelper(settings) {
+ // there can be only one tooltip helper
+ if (helper.parent) return;
+ // create the helper, h3 for title, div for url
+ helper.parent = $(
+ ''
+ )
+ // add to document
+ .appendTo(document.body)
+ // hide it at first
+ .hide();
+
+ // apply bgiframe if available
+ if ($.fn.bgiframe) helper.parent.bgiframe();
+
+ // save references to title and url elements
+ helper.title = $('h3', helper.parent);
+ helper.body = $('div.body', helper.parent);
+ helper.url = $('div.url', helper.parent);
+ }
+
+ function settings(element) {
+ return $.data(element, 'tooltip');
+ }
+
+ // main event handler to start showing tooltips
+ function handle(event) {
+ if (
+ $($.tooltip.current).hasClass('SSTT') &&
+ $($.tooltip.current).hasClass('ui-state-active')
+ )
+ return;
+
+ // show helper, either with timeout or on instant
+ if (settings(this).delay)
+ tID = setTimeout(visible, settings(this).delay);
+ else visible();
+ show();
+
+ // if selected, update the helper position when the mouse moves
+ track = !!settings(this).track;
+ $(document.body).bind('mousemove', update);
+
+ // update at least once
+ update(event);
+ }
+
+ // save elements title before the tooltip is displayed
+ function save(event) {
+ // if this is the current source, or it has no title (occurs with click event), stop
+ if (event.stopPropagation) event.stopPropagation();
+
+ event.cancelBubble = true;
+
+ if (
+ $.tooltip.blocked ||
+ this === $.tooltip.current ||
+ (!this.tooltipText &&
+ !this.tooltipSrc &&
+ !settings(this).bodyHandler)
+ )
+ return;
+
+ // save current
+ $.tooltip.current = this;
+ title = this.tooltipText;
+
+ // if element has href or src, add and show it, otherwise hide it
+ if (settings(this).showURL && $(this).url())
+ helper.url.html($(this).url().replace('http://', '')).show();
+ else helper.url.hide();
+ // add an optional class for this tip
+ helper.parent.removeClass();
+ helper.parent.addClass(settings(this).extraClass);
+ if (this.ajaxLoad) {
+ // @TODO debounce instead of timeout
+ clearTimeout($.tooltip.ajaxTimeout);
+ $.tooltip.ajaxTimeout = setTimeout($.tooltip.delayAjax, 300);
+ $.tooltip.ajaxEvent = event;
+ } else {
+ title =
+ '' +
+ '
' +
+ '
' +
+ '
' +
+ title +
+ '
' +
+ '
' +
+ '
';
+
+ positioning.apply(this, arguments);
+ }
+ return;
+ }
+
+ function positioning(event) {
+ helper.body.html(title);
+ helper.body.show();
+ let $this = $.tooltip.current;
+ let tooltipSettings = settings($this) ? settings($this) : {};
+ let fixedPosition = $.tooltip.blocked;
+ // fix PNG background for IE
+ if (tooltipSettings.fixPNG) helper.parent.fixPNG();
+ if (tooltipSettings.outside) {
+ let width = 'auto';
+ let height = 'auto';
+ let tooltipId = tooltipSettings.id;
+ let $defaultTips = $('#' + tooltipId);
+ let customId = 'phraseanet-embed-tooltip-frame';
+ $defaultTips.find('#phraseanet-embed-frame').attr('id', customId);
+
+ let $audioTips = $('#' + tooltipId + ' .audioTips');
+ let $imgTips = $('#' + tooltipId + ' .imgTips');
+ let $videoTips = $('#' + tooltipId + ' .videoTips');
+ let $documentTips = $('#' + tooltipId + ' .documentTips');
+ let shouldResize =
+ $('#' + tooltipId + ' .noToolTipResize').length === 0
+ ? true
+ : false;
+
+ // get image or video original dimensions
+ let recordWidth = 400;
+ let recordHeight = 0;
+ let tooltipVerticalOffset = 75;
+ let tooltipHorizontalOffset = 35;
+ let maxWidthAllowed = 1024;
+ let maxHeightAllowed = 768;
+ let tooltipWidth = 0;
+ let tooltipHeight = 0;
+ let viewportDimensions = viewport();
+ let left = 0;
+ let top = 0;
+ let recordWidthOffset = 0;
+ let recordHeightOffset = 0;
+ let topOffset = 0;
+ let leftOffset = 0;
+ let rightOffset = 0;
+ let bottomOffset = 0;
+ let $selector = $defaultTips;
+
+ if ($imgTips[0] && shouldResize) {
+ recordWidth = parseInt($imgTips[0].style.width, 10);
+ recordHeight = parseInt($imgTips[0].style.height, 10);
+ $imgTips.css({ display: 'block', margin: '0 auto' });
+ $selector = $imgTips;
+ } else if ($documentTips[0] && shouldResize) {
+ let recordUrl = $documentTips.data('src');
+ recordWidth = $documentTips.data('original-width') > 400 ? $documentTips.data('original-width') : 400;
+ recordHeight = $documentTips.data('original-width') > 400 ? $documentTips.data('original-height') : 600;
+ $documentTips.css({ display: 'block', margin: '0 auto' });
+ $selector = $documentTips;
+ activeThumbnailFrame = new pym.Parent(customId, recordUrl);
+ activeThumbnailFrame.iframe.setAttribute('allowfullscreen', '');
+ } else if ($audioTips[0] && shouldResize) {
+ let recordUrl = $audioTips.data('src');
+ recordWidth = 240;
+ recordHeight = 240;
+ $audioTips.css({ display: 'block', margin: '0 auto' });
+ $selector = $audioTips;
+ activeThumbnailFrame = new pym.Parent(customId, recordUrl);
+ activeThumbnailFrame.iframe.setAttribute('allowfullscreen', '');
+ } else if ($videoTips[0] && shouldResize) {
+ let recordUrl = $videoTips.data('src');
+ recordWidth = $videoTips.data('original-width');
+ recordHeight = $videoTips.data('original-height');
+ // limit video to maxWidth:
+ /*if( recordWidth > 720 ) {
+ let limitRatio = recordWidth/recordHeight;
+ recordWidth = 720;
+ recordHeight = recordWidth / limitRatio;
+ }*/
+ $videoTips.css({ display: 'block', margin: '0 auto' });
+ $selector = $videoTips;
+ activeThumbnailFrame = new pym.Parent(customId, recordUrl);
+ activeThumbnailFrame.iframe.setAttribute('allowfullscreen', '');
+ //activeThumbnailFrame.iframe.setAttribute('height', '100%');
+ } else {
+ // handle captions
+ if ($selector.find('.popover').length > 0) {
+ recordWidth =
+ parseInt(
+ $selector.find('.popover')[0].style.width,
+ 10
+ ) || recordWidth;
+ }
+ var contentHeight = $selector.height();
+ shouldResize = false;
+ tooltipVerticalOffset = 13;
+ recordHeight =
+ contentHeight > maxHeightAllowed
+ ? maxHeightAllowed
+ : contentHeight;
+ $selector.css({ height: 'auto' });
+ }
+
+ tooltipWidth = recordWidth + tooltipHorizontalOffset;
+ tooltipHeight = recordHeight + tooltipVerticalOffset;
+
+ let rescale = function (
+ containerWidth,
+ containerHeight,
+ resourceWidth,
+ resourceHeight,
+ maxWidthAllowed,
+ maxHeightAllowed,
+ $selector
+ ) {
+ let resourceRatio = resourceHeight / resourceWidth;
+ let resizeW = resourceWidth;
+ let resizeH = resourceHeight;
+
+ if (resourceWidth > resourceHeight) {
+ // if width still too large:
+ if (resizeW > containerWidth) {
+ resizeW = containerWidth;
+ resizeH = containerWidth * resourceRatio;
+ }
+
+ if (resizeH > containerHeight) {
+ resizeW = containerHeight / resourceRatio;
+ resizeH = containerHeight;
+ }
+ } else {
+ if (resizeH > containerHeight) {
+ resizeW = containerHeight / resourceRatio;
+ resizeH = containerHeight;
+ }
+ }
+
+ if (
+ maxWidthAllowed !== undefined &&
+ maxHeightAllowed !== undefined
+ ) {
+ if (
+ resizeW > maxWidthAllowed ||
+ resizeH > maxHeightAllowed
+ ) {
+ return rescale(
+ maxWidthAllowed,
+ maxHeightAllowed,
+ resourceWidth,
+ resourceHeight
+ );
+ }
+ }
+
+ if ($selector !== undefined) {
+ $selector.css({
+ width: Math.floor(resizeW),
+ height: Math.floor(resizeH)
+ });
+ }
+
+ return {
+ width: Math.floor(resizeW),
+ height: Math.floor(resizeH)
+ };
+ };
+
+ if (event) {
+ let $origEventTarget = $(event.target);
+
+ // previewTips
+
+ // since event target can have different positionning, try to get common closest parent:
+ let $eventTarget = $origEventTarget.closest('.diapo');
+
+ if ($eventTarget.length > 0) {
+ // tooltip from records answer
+ recordWidthOffset = $eventTarget.width() - 2; // remove width with margin/2
+ recordHeightOffset = $eventTarget.height() + 2; // remove height with margin/2
+ // change offsets:
+ topOffset = 14;
+ leftOffset = 1;
+ rightOffset = 2;
+ bottomOffset = -15;
+ } else {
+ // tooltip from workzone (basket)
+ tooltipVerticalOffset = 0;
+ tooltipHorizontalOffset = 0;
+ topOffset = 50;
+ // fallback on original target if nothing found:
+ $eventTarget = $origEventTarget;
+ }
+
+ let recordPosition = $eventTarget.offset();
+
+ let totalViewportWidth = viewportDimensions.x;
+ let totalViewportHeight = viewportDimensions.y;
+
+ //for basket
+ if (recordPosition.left < 30) {
+ leftOffset = $('.insidebloc').width();
+ }
+
+ let leftAvailableSpace = recordPosition.left + leftOffset;
+ let topAvailableSpace = recordPosition.top + topOffset;
+ let rightAvailableSpace =
+ totalViewportWidth -
+ leftAvailableSpace -
+ recordWidthOffset -
+ rightOffset;
+ let bottomAvailableSpace =
+ totalViewportHeight -
+ topAvailableSpace -
+ recordHeightOffset;
+
+ let shouldBeOnTop = false;
+ let availableHeight = bottomAvailableSpace;
+ let tooltipSize = {
+ width: tooltipWidth,
+ height: tooltipHeight
+ };
+ let position = 'top';
+
+ if (topAvailableSpace > bottomAvailableSpace) {
+ shouldBeOnTop = true;
+ availableHeight = topAvailableSpace;
+ }
+
+ if (leftAvailableSpace > rightAvailableSpace) {
+ position = 'left';
+ } else {
+ position = 'right';
+ }
+
+ // prefer bottom position if tooltip is a small caption:
+ if (
+ bottomAvailableSpace > leftAvailableSpace &&
+ bottomAvailableSpace > rightAvailableSpace
+ ) {
+ position = 'bottom';
+ } else if (
+ shouldBeOnTop &&
+ availableHeight > leftAvailableSpace &&
+ availableHeight > rightAvailableSpace
+ ) {
+ position = 'top';
+ }
+
+ if (fixedPosition === true) {
+ leftAvailableSpace = totalViewportWidth;
+ topAvailableSpace = totalViewportHeight;
+ position = 'top';
+ }
+
+ switch (position) {
+ case 'top':
+ tooltipSize = rescale(
+ totalViewportWidth,
+ topAvailableSpace,
+ tooltipWidth,
+ tooltipHeight,
+ maxWidthAllowed,
+ maxHeightAllowed
+ );
+ tooltipWidth = tooltipSize.width;
+ tooltipHeight = tooltipSize.height;
+ left =
+ leftAvailableSpace -
+ tooltipSize.width / 2 +
+ recordWidthOffset / 2;
+ top = topAvailableSpace - tooltipSize.height;
+ break;
+ case 'bottom':
+ tooltipSize = rescale(
+ totalViewportWidth,
+ bottomAvailableSpace,
+ tooltipWidth,
+ tooltipHeight,
+ maxWidthAllowed,
+ maxHeightAllowed
+ );
+ tooltipWidth = tooltipSize.width;
+ tooltipHeight = tooltipSize.height;
+ left =
+ leftAvailableSpace -
+ tooltipSize.width / 2 +
+ recordWidthOffset / 2;
+ top =
+ totalViewportHeight -
+ bottomAvailableSpace +
+ bottomOffset;
+ break;
+ case 'left':
+ tooltipSize = rescale(
+ leftAvailableSpace,
+ totalViewportHeight,
+ tooltipWidth,
+ tooltipHeight,
+ maxWidthAllowed,
+ maxHeightAllowed
+ );
+
+ tooltipWidth = tooltipSize.width;
+ tooltipHeight = tooltipSize.height;
+ left = leftAvailableSpace - tooltipSize.width;
+ break;
+ case 'right':
+ tooltipSize = rescale(
+ rightAvailableSpace,
+ totalViewportHeight,
+ tooltipWidth,
+ tooltipHeight,
+ maxWidthAllowed,
+ maxHeightAllowed
+ );
+ tooltipWidth = tooltipSize.width;
+ tooltipHeight = tooltipSize.height;
+ left =
+ leftAvailableSpace +
+ recordWidthOffset +
+ rightOffset;
+ break;
+ }
+
+ // tooltipHeight = tooltipHeight + 18;
+ // tooltipWidth = tooltipWidth + 28;
+ if (fixedPosition === true) {
+ left = totalViewportWidth / 2 - tooltipWidth / 2;
+ top = totalViewportHeight / 2 - tooltipHeight / 2;
+ } else {
+ // try to vertical center, relative to source:
+ if (position === 'left' || position === 'right') {
+ let verticalSpace =
+ topAvailableSpace +
+ recordHeightOffset / 2 +
+ tooltipHeight / 2;
+ if (verticalSpace < totalViewportHeight) {
+ // tooltip can be aligned vertically
+ top =
+ topAvailableSpace +
+ recordHeightOffset / 2 -
+ tooltipHeight / 2;
+ } else {
+ top = totalViewportHeight - tooltipHeight;
+ }
+ top = top < 0 ? 0 : top;
+ }
+
+ // try to horizontal center, relative to source:
+ if (position === 'top' || position === 'bottom') {
+ // push to left
+ // push to right
+ let takeLeftSpace =
+ tooltipWidth / 2 + leftAvailableSpace;
+ let takeRightSpace =
+ tooltipWidth / 2 + rightAvailableSpace;
+ // if centering on top or bottom and tooltip is offcanvas
+ if (
+ takeLeftSpace > totalViewportWidth ||
+ takeRightSpace > totalViewportWidth
+ ) {
+ if (leftAvailableSpace > totalViewportWidth / 2) {
+ // push at left
+ left = 0;
+ } else {
+ // push at right
+ left = totalViewportWidth - tooltipWidth;
+ }
+ } else {
+ // center
+ left =
+ leftAvailableSpace -
+ tooltipWidth / 2 +
+ recordWidthOffset / 2;
+ }
+ }
+ }
+
+ let resizeProperties = {
+ left: left,
+ top: top
+ };
+
+ if (shouldResize) {
+ // rescale $selector css:
+ rescale(
+ tooltipWidth - tooltipHorizontalOffset,
+ tooltipHeight - tooltipVerticalOffset,
+ recordWidth,
+ recordHeight,
+ maxWidthAllowed,
+ maxHeightAllowed,
+ $selector
+ );
+ // reset non used css properties:
+ resizeProperties['max-width'] = '';
+ resizeProperties['min-width'] = '';
+ } else {
+ // ensure tooltip width match with left position
+ resizeProperties['max-width'] = Math.round(tooltipWidth);
+ resizeProperties['min-width'] = Math.round(tooltipWidth);
+ }
+
+ resizeProperties['width'] = shouldResize
+ ? Math.round(tooltipWidth)
+ : 'auto';
+ resizeProperties['height'] = shouldResize
+ ? Math.round(tooltipHeight)
+ : 'auto';
+
+ helper.parent.css(resizeProperties);
+ }
+ }
+ handle.apply($this, arguments);
+ return;
+ }
+
+ // delete timeout and show helper
+ function show() {
+ tID = null;
+ let isBrowsable = false;
+ if ($.tooltip.current !== null) {
+ isBrowsable = settings($.tooltip.current).isBrowsable;
+ }
+
+ if ((!IE || !$.fn.bgiframe) && settings($.tooltip.current).fade) {
+ if (helper.parent.is(':animated'))
+ helper.parent
+ .stop()
+ .show()
+ .fadeTo(settings($.tooltip.current).fade, 100);
+ else
+ helper.parent.is(':visible')
+ ? helper.parent.fadeTo(
+ settings($.tooltip.current).fade,
+ 100
+ )
+ : helper.parent.fadeIn(settings($.tooltip.current).fade);
+ } else {
+ helper.parent.show();
+ }
+
+ $(helper.parent[0])
+ .unbind('mouseenter')
+ .unbind('mouseleave')
+ .mouseenter(function () {
+ if (isBrowsable) {
+ $.tooltip.currentHover = true;
+ }
+ })
+ .mouseleave(function () {
+ if (isBrowsable) {
+ // if tooltip has scrollable content or selectionnable text - should be closed on mouseleave:
+ $.tooltip.currentHover = false;
+ helper.parent.hide();
+ }
+ });
+
+ update();
+ }
+
+ function fix(event) {
+ if (!$.tooltip.current) {
+ return;
+ }
+ if (!$(this).hasClass('captionTips') || !event.altKey) {
+ if (!settings(this).fixable) {
+ hide(event);
+ return;
+ }
+ }
+ event.cancelBubble = true;
+ if (event.stopPropagation) event.stopPropagation();
+ showOverlay(
+ '_tooltip',
+ 'body',
+ unfixTooltip,
+ settings(this).fixableIndex
+ );
+ $('#tooltip .tooltip_closer').show().bind('click', unfixTooltip);
+ $.tooltip.blocked = true;
+ positioning.apply(this, arguments);
+ }
+
+ function visible() {
+ $.tooltip.visible = true;
+ helper.parent.css({
+ visibility: 'visible'
+ });
+ }
+
+ /**
+ * callback for mousemove
+ * updates the helper position
+ * removes itself when no current element
+ */
+ function update(event) {
+ if ($.tooltip.blocked) return;
+
+ if (event && event.target.tagName === 'OPTION') {
+ return;
+ }
+
+ // stop updating when tracking is disabled and the tooltip is visible
+ if (!track && helper.parent.is(':visible')) {
+ $(document.body).unbind('mousemove', update);
+ $.tooltip.currentHover = true;
+ }
+
+ // if no current element is available, remove this listener
+ if ($.tooltip.current === null) {
+ $(document.body).unbind('mousemove', update);
+ $.tooltip.currentHover = false;
+ return;
+ }
+
+ // remove position helper classes
+ helper.parent
+ .removeClass('viewport-right')
+ .removeClass('viewport-bottom');
+
+ if (!settings($.tooltip.current).outside) {
+ let left = helper.parent[0].offsetLeft;
+ let top = helper.parent[0].offsetTop;
+ helper.parent.width('auto');
+ helper.parent.height('auto');
+ if (event) {
+ // position the helper 15 pixel to bottom right, starting from mouse position
+ left = event.pageX + settings($.tooltip.current).left;
+ top = event.pageY + settings($.tooltip.current).top;
+ let right = 'auto';
+ if (settings($.tooltip.current).positionLeft) {
+ right = $(window).width() - left;
+ left = 'auto';
+ }
+ helper.parent.css({
+ left: left,
+ right: right,
+ top: top
+ });
+ }
+
+ let v = viewport(),
+ h = helper.parent[0];
+ // check horizontal position
+ if (v.x + v.cx < h.offsetLeft + h.offsetWidth) {
+ left -= h.offsetWidth + 20 + settings($.tooltip.current).left;
+ helper.parent
+ .css({
+ left: left + 'px'
+ })
+ .addClass('viewport-right');
+ }
+ // check vertical position
+ if (v.y + v.cy < h.offsetTop + h.offsetHeight) {
+ top -= h.offsetHeight + 20 + settings($.tooltip.current).top;
+ helper.parent
+ .css({
+ top: top + 'px'
+ })
+ .addClass('viewport-bottom');
+ }
+ }
+ }
+
+ function viewport() {
+ return {
+ x: $(window).width(),
+ y: $(window).height(),
+
+ cx: 0,
+ cy: 0
+ };
+ }
+
+ // hide helper and restore added classes and the title
+ function hide(event) {
+ let isBrowsable = false;
+ if ($.tooltip.current !== null) {
+ isBrowsable = settings($.tooltip.current).isBrowsable;
+ }
+ if ($.tooltip.currentHover && isBrowsable) {
+ return;
+ }
+
+ if ($.tooltip.blocked || !$.tooltip.current) return;
+
+ $(helper.parent[0]).unbind('mouseenter').unbind('mouseleave');
+
+ // clear timeout if possible
+ if (tID) clearTimeout(tID);
+ // no more current element
+ $.tooltip.visible = false;
+ let tsettings = settings($.tooltip.current);
+ clearTimeout($.tooltip.ajaxTimeout);
+ if ($.tooltip.ajaxRequest && $.tooltip.ajaxRequest.abort) {
+ $.tooltip.ajaxRequest.abort();
+ }
+
+ helper.body.empty();
+ $.tooltip.current = null;
+ function complete() {
+ helper.parent
+ .removeClass(tsettings.extraClass)
+ .hide()
+ .css('opacity', '');
+ }
+
+ if ((!IE || !$.fn.bgiframe) && tsettings.fade) {
+ if (helper.parent.is(':animated'))
+ helper.parent.stop().fadeTo(tsettings.fade, 0, complete);
+ else helper.parent.stop().fadeOut(tsettings.fade, complete);
+ } else complete();
+
+ if (tsettings.fixPNG) helper.parent.unfixPNG();
+ }
+
+ function unfixTooltip() {
+ $.tooltip.blocked = false;
+ $.tooltip.visible = false;
+ $.tooltip.current = null;
+ $('#tooltip').hide();
+ $('#tooltip .tooltip_closer').hide();
+ hideOverlay('_tooltip');
+ }
+
+ const showOverlay = (n, appendto, callback, zIndex) => {
+ let div = 'OVERLAY';
+ if (typeof n !== 'undefined') div += n;
+ if ($('#' + div).length === 0) {
+ if (typeof appendto === 'undefined') appendto = 'body';
+ $(appendto).append(
+ '
'
+ );
+ }
+
+ let css = {
+ display: 'block',
+ opacity: 0,
+ right: 0,
+ bottom: 0,
+ position: 'absolute',
+ top: 0,
+ zIndex: zIndex,
+ left: 0
+ };
+
+ if (parseInt(zIndex, 10) > 0) css['zIndex'] = parseInt(zIndex, 10);
+
+ if (typeof callback !== 'function') callback = function () {};
+ $('#' + div)
+ .css(css)
+ .addClass('overlay')
+ .fadeTo(500, 0.7)
+ .bind('click', function () {
+ callback();
+ });
+ if (
+ navigator.userAgent.match(/msie/i) &&
+ navigator.userAgent.match(/6/)
+ ) {
+ $('select').css({
+ visibility: 'hidden'
+ });
+ }
+ };
+
+ const hideOverlay = n => {
+ if (
+ navigator.userAgent.match(/msie/i) &&
+ navigator.userAgent.match(/6/)
+ ) {
+ $('select').css({
+ visibility: 'visible'
+ });
+ }
+ let div = 'OVERLAY';
+ if (typeof n !== 'undefined') div += n;
+ $('#' + div).hide().remove();
+ };
+
+ return {
+ unfixTooltip
+ };
+})(jQuery);
diff --git a/Phraseanet-production-client/src/phraseanet-common/components/user.js b/Phraseanet-production-client/src/phraseanet-common/components/user.js
new file mode 100644
index 0000000000..96880da53b
--- /dev/null
+++ b/Phraseanet-production-client/src/phraseanet-common/components/user.js
@@ -0,0 +1,42 @@
+// @TODO enable lints
+/* eslint-disable no-undef*/
+import $ from 'jquery';
+const humane = require('humane-js');
+
+humane.info = humane.spawn({addnCls: 'humane-libnotify-info', timeout: 1000});
+humane.error = humane.spawn({addnCls: 'humane-libnotify-error', timeout: 1000});
+humane.forceNew = true;
+
+function setPref(name, value) {
+ const prefName = `pref_${name}`;
+ if ($.data[prefName] && $.data[prefName].abort) {
+ $.data[prefName].abort();
+ $.data[prefName] = false;
+ }
+ $.data[prefName] = $.ajax({
+ type: 'POST',
+ url: '/user/preferences/',
+ data: {
+ prop: name,
+ value
+ },
+ dataType: 'json',
+ timeout: $.data[prefName] = false,
+ error: $.data[prefName] = false,
+ success: (data) => {
+ if (data.success) {
+ humane.info(data.message);
+ } else {
+ humane.error(data.message);
+ }
+ $.data[prefName] = false;
+ return data;
+ }
+ });
+ return $.data[prefName];
+
+}
+
+export default {setPref};
+
+
diff --git a/Phraseanet-production-client/src/phraseanet-common/components/utils.js b/Phraseanet-production-client/src/phraseanet-common/components/utils.js
new file mode 100644
index 0000000000..d54869cd4f
--- /dev/null
+++ b/Phraseanet-production-client/src/phraseanet-common/components/utils.js
@@ -0,0 +1,118 @@
+// @TODO enable lints
+/* eslint-disable camelcase*/
+/* eslint-disable no-param-reassign*/
+/* eslint-disable one-var*/
+
+const utilsModule = (function () {
+
+
+ function RGBtoHex(R, G, B) {
+ return _toHex(R) + _toHex(G) + _toHex(B);
+ }
+
+ function _toHex(N) {
+ if (N === null) {
+ return '00';
+ }
+ let nInt = parseInt(N, 10);
+ if (nInt === 0 || isNaN(nInt)) {
+ return '00';
+ }
+ nInt = Math.max(0, nInt);
+ nInt = Math.min(nInt, 255);
+ nInt = Math.round(nInt);
+ return '0123456789ABCDEF'.charAt((nInt - nInt % 16) / 16)
+ + '0123456789ABCDEF'.charAt(nInt % 16);
+ }
+
+ function hsl2rgb(h, s, l) {
+ let m1, m2, hue;
+ let r, g, b;
+ // s /= 100;
+ // l /= 100;
+
+ if (s === 0) {
+ r = g = b = (l * 255);
+ } else {
+ if (l <= 0.5) {
+ m2 = l * (s + 1);
+ } else {
+ m2 = l + s - l * s;
+ }
+ m1 = l * 2 - m2;
+ hue = h / 360;
+ r = _HueToRgb(m1, m2, hue + 1 / 3);
+ g = _HueToRgb(m1, m2, hue);
+ b = _HueToRgb(m1, m2, hue - 1 / 3);
+ }
+ return {
+ r,
+ g,
+ b
+ };
+ }
+
+ function _HueToRgb(m1, m2, hue) {
+ let v;
+ if (hue < 0) {
+ hue += 1;
+ } else if (hue > 1) {
+ hue -= 1;
+ }
+
+ if (6 * hue < 1) {
+ v = m1 + (m2 - m1) * hue * 6;
+ } else if (2 * hue < 1) {
+ v = m2;
+ } else if (3 * hue < 2) {
+ v = m1 + (m2 - m1) * (2 / 3 - hue) * 6;
+ } else {
+ v = m1;
+ }
+
+ return 255 * v;
+ }
+
+ function is_ctrl_key(event) {
+ if (event.altKey) {
+ return true;
+ }
+ if (event.ctrlKey) {
+ return true;
+ }
+ // apple key opera
+ if (event.metaKey) {
+ return true;
+ }
+ // apple key opera
+ if (event.keyCode === 17) {
+ return true;
+ }
+ // apple key mozilla
+ if (event.keyCode === 224) {
+ return true;
+ }
+ // apple key safari
+ if (event.keyCode === 91) {
+ return true;
+ }
+
+ return false;
+ }
+
+ function is_shift_key(event) {
+ if (event.shiftKey) {
+ return true;
+ }
+ return false;
+ }
+
+ return {
+ RGBtoHex,
+ hsl2rgb,
+ is_ctrl_key,
+ is_shift_key
+ };
+}());
+
+export default utilsModule;
diff --git a/Phraseanet-production-client/src/phraseanet-common/components/vendors/contextMenu.js b/Phraseanet-production-client/src/phraseanet-common/components/vendors/contextMenu.js
new file mode 100644
index 0000000000..c4f780e59b
--- /dev/null
+++ b/Phraseanet-production-client/src/phraseanet-common/components/vendors/contextMenu.js
@@ -0,0 +1,499 @@
+// @TODO enable lints
+/* eslint-disable max-len*/
+/* eslint-disable object-shorthand*/
+/* eslint-disable dot-notation*/
+/* eslint-disable vars-on-top*/
+/* eslint-disable prefer-template*/
+/* eslint-disable prefer-const*/
+/* eslint-disable spaced-comment*/
+/* eslint-disable curly*/
+/* eslint-disable object-curly-spacing*/
+/* eslint-disable spaced-comment*/
+/* eslint-disable prefer-arrow-callback*/
+/* eslint-disable one-var*/
+/* eslint-disable space-in-parens*/
+/* eslint-disable camelcase*/
+/* eslint-disable no-undef*/
+/* eslint-disable quote-props*/
+/* eslint-disable no-shadow*/
+/* eslint-disable no-param-reassign*/
+/* eslint-disable no-unused-expressions*/
+/* eslint-disable no-shadow*/
+/* eslint-disable no-implied-eval*/
+/* eslint-disable brace-style*/
+/* eslint-disable no-unused-vars*/
+/* eslint-disable brace-style*/
+/* eslint-disable no-lonely-if*/
+/* eslint-disable no-inline-comments*/
+/* eslint-disable default-case*/
+/* eslint-disable one-var*/
+/* eslint-disable semi*/
+/* eslint-disable no-throw-literal*/
+/* eslint-disable no-sequences*/
+/* eslint-disable consistent-this*/
+/* eslint-disable no-dupe-keys*/
+/* eslint-disable semi*/
+/* eslint-disable no-loop-func*/
+/* eslint-disable space-after-keywords*/
+/* eslint-disable no-var*/
+/* eslint-disable quotes*/
+
+
+/**
+ * Copyright (c)2005-2009 Matt Kruse (javascripttoolbox.com)
+ *
+ * Dual licensed under the MIT and GPL licenses.
+ * This basically means you can use this code however you want for
+ * free, but don't claim to have written it yourself!
+ * Donations always accepted: http://www.JavascriptToolbox.com/donate/
+ *
+ * Please do not link to the .js files on javascripttoolbox.com from
+ * your site. Copy the files locally to your server instead.
+ *
+ */
+/**
+ * jquery.contextmenu.js
+ * jQuery Plugin for Context Menus
+ * http://www.JavascriptToolbox.com/lib/contextmenu/
+ *
+ * Copyright (c) 2008 Matt Kruse (javascripttoolbox.com)
+ * Dual licensed under the MIT and GPL licenses.
+ *
+ * @version 1.0
+ * @history 1.0 2008-10-20 Initial Release
+ * @todo slideUp doesn't work in IE - because of iframe?
+ * @todo Hide all other menus when contextmenu is shown?
+ * @todo More themes
+ * @todo Nested context menus
+ */
+
+(function ($) {
+ $.contextMenu = {
+ // props add by Alchemy
+ _showEvent: null, // the original event the caused the menu to show (useful to find the original element clicked)
+ _div: null,
+ //
+ openEvt: "contextmenu", // ouverture sur right-click
+ closeTimer: null, // fermer le menu apres 100ms de mouseout
+
+ shadow: true,
+ dropDown: false,
+ shadowOffset: 0,
+ shadowOffsetX: 5,
+ shadowOffsetY: 5,
+ shadowWidthAdjust: -3,
+ shadowHeightAdjust: -3,
+ shadowOpacity: 0.2,
+ shadowClass: 'context-menu-shadow',
+ shadowColor: 'black',
+
+ offsetX: 0,
+ offsetY: 0,
+ appendTo: 'body',
+ direction: 'down',
+ constrainToScreen: true,
+
+ showTransition: 'show',
+ hideTransition: 'hide',
+ showSpeed: '',
+ hideSpeed: '',
+ showCallback: null,
+ hideCallback: null,
+
+ className: 'context-menu',
+ itemClassName: 'context-menu-item',
+ itemHoverClassName: 'context-menu-item-hover',
+ disabledItemClassName: 'context-menu-item-disabled',
+ disabledItemHoverClassName: 'context-menu-item-disabled-hover',
+ separatorClassName: 'context-menu-separator',
+ innerDivClassName: 'context-menu-item-inner',
+ themePrefix: 'context-menu-theme-',
+ theme: 'default',
+
+ separator: 'context-menu-separator', // A specific key to identify a separator
+ target: null, // The target of the context click, to be populated when triggered
+ menu: null, // The jQuery object containing the HTML object that is the menu itself
+ shadowObj: null, // Shadow object
+ bgiframe: null, // The iframe object for IE6
+ shown: false, // Currently being shown?
+ useIframe: /*@cc_on @*//*@if (@_win32) true, @else @*/false, /*@end @*/ // This is a better check than looking at userAgent!
+
+ // Create the menu instance
+ create: function (menu, opts) {
+ var cmenu = $.extend({}, this, opts); // Clone all default properties to created object
+
+ // If a selector has been passed in, then use that as the menu
+ if (typeof menu === "string") {
+ cmenu.menu = $(menu);
+ }
+ // If a function has been passed in, call it each time the menu is shown to create the menu
+ else if (typeof menu === "function") {
+ cmenu.menuFunction = menu;
+ }
+ // Otherwise parse the Array passed in
+ else {
+ cmenu.menu = cmenu.createMenu(menu, cmenu);
+ }
+ if (cmenu.menu) {
+ cmenu.menu.css({display: 'none'});
+ $(cmenu.appendTo).append(cmenu.menu);
+ }
+
+ // Create the shadow object if shadow is enabled
+ if (cmenu.shadow) {
+ cmenu.createShadow(cmenu); // Extracted to method for extensibility
+ if (cmenu.shadowOffset) {
+ cmenu.shadowOffsetX = cmenu.shadowOffsetY = cmenu.shadowOffset;
+ }
+ }
+ $('body').bind(cmenu.openEvt, function () {
+ cmenu.hide();
+ }); // If right-clicked somewhere else in the document, hide this menu
+ return cmenu;
+ },
+
+ // Create an iframe object to go behind the menu
+ createIframe: function () {
+ return $('');
+ },
+
+ // Accept an Array representing a menu structure and turn it into HTML
+ createMenu: function (menu, cmenu) {
+ var className = cmenu.className;
+ $.each(cmenu.theme.split(","), function (i, n) {
+ className += ' ' + cmenu.themePrefix + n;
+ });
+// var $t = $('').click(function(){cmenu.hide(); return false;}); // We wrap a table around it so width can be flexible
+ var $t = $('').click(function () {
+ cmenu.hide();
+ return false;
+ }); // We wrap a table around it so width can be flexible
+ var $tr = $(' ');
+ var $td = $(' ');
+ var $div = cmenu._div = $('
');
+
+ cmenu._div.hover(
+ function () {
+ if (cmenu.closeTimer) {
+ clearTimeout(cmenu.closeTimer);
+ cmenu.closeTimer = null;
+ }
+ },
+ function () {
+ var myClass = cmenu;
+
+ function timerRelay() {
+ myClass.hide();
+ }
+
+ myClass.closeTimer = setTimeout(timerRelay, 500);
+ }
+ );
+
+ // Each menu item is specified as either:
+ // title:function
+ // or title: { property:value ... }
+ /*
+ for (var i=0; i