<commit_before>/* This file is part of Indico.
 * Copyright (C) 2002 - 2018 European Organization for Nuclear Research (CERN).
 *
 * Indico is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 3 of the
 * License, or (at your option) any later version.
 *
 * Indico is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Indico; if not, see <http://www.gnu.org/licenses/>.
 */

import {createHash} from 'crypto';
import fs from 'fs';
import path from 'path';

import chalk from 'chalk';
import webpack from 'webpack';

import ExtractTextPlugin from 'extract-text-webpack-plugin';
import ManifestPlugin from 'webpack-manifest-plugin';
import ProgressBarPlugin from 'progress-bar-webpack-plugin';
import importOnce from 'node-sass-import-once';

function _resolveTheme(rootPath, indicoClientPath, filePath) {
    const indicoRelativePath = path.resolve(indicoClientPath, filePath);

    if (indicoClientPath && !fs.existsSync(path.resolve(rootPath, filePath)) &&
            fs.existsSync(indicoRelativePath)) {
        return path.resolve(indicoClientPath, filePath);
    }

    return path.resolve(rootPath, filePath);
}

export function getThemeEntryPoints(config, prefix) {
    const themes = config.themes;
    const indicoClientPath = path.join(config.isPlugin ? config.indico.build.clientPath : config.build.clientPath,
                                       'styles');
    const rootPath = path.join(config.build.rootPath);

    return Object.assign(...Object.keys(themes).map((k) => {
        const returnValue = {};
        const escapedKey = k.replace('-', '_');

        returnValue[`themes_${escapedKey}`] = [
            _resolveTheme(rootPath, indicoClientPath, prefix + themes[k].stylesheet)
        ];

        if (themes[k].print_stylesheet) {
            returnValue[`themes_${escapedKey}.print`] = [
                _resolveTheme(rootPath, indicoClientPath, prefix + themes[k].print_stylesheet)
            ];
        }
        return returnValue;
    }));
}

export function generateAssetPath(config, virtualVersion = false) {
    // /css/whatever.css => /css/whatever__v123abcdef.css
    return (file) => {
        const relPath = path.relative(config.build.staticPath, file);
        const {dir, name, ext} = path.parse(relPath);
        const h = createHash('md5');
        h.update(fs.readFileSync(file));
        const hash = h.digest('hex').slice(0, 8);
        // the "virtual version" is used for files that are loaded as-is from the
        // static folder and thus do not actually get the hash in the physical
        // file name. it is distinct from the normal version style so a rule on
        // the web server can strip that version segment
        const fileName = virtualVersion ? `${name}__v${hash}${ext}` : `${name}.${hash}${ext}`;
        // .. -> _, like file-loader does
        return dir.replace(/\.\./g, '_') + path.sep + fileName;
    };
}

export function webpackDefaults(env, config, bundles) {
    const globalBuildConfig = config.indico ? config.indico.build : config.build;
    const currentEnv = (env ? env.NODE_ENV : null) || 'development';
    const nodeModules = [path.join(config.build.indicoSourcePath || path.resolve(config.build.rootPath, '..'),
                                   'node_modules')];

    if (config.isPlugin) {
        // add plugin's node_modules in addition to the core's
        nodeModules.push(path.resolve(config.build.rootPath, '../node_modules'));
    }

    const _cssLoaderOptions = {
        url: true,
    };

    const scssIncludePath = path.join(
        config.isPlugin
            ? path.resolve(config.build.indicoSourcePath, './indico/web/client')
            : path.join(config.build.clientPath),
        'styles'
    );

    function getDevtoolFilename(info) {
        const root = path.resolve(globalBuildConfig.rootPath, '..');
        return path.relative(root, info.absoluteResourcePath);
    }

    /**
     * This function resolves SASS files using a module:path syntax
     */
    function sassResolver(url) {
        const match = url.match(/^(\w+):([\w/-_]+)/);
        if (match) {
            if (config.isPlugin) {
                const {sassOverrides} = bundles;
                if (sassOverrides && sassOverrides[url]) {
                    return {file: path.join(config.build.clientPath, sassOverrides[url])};
                }
            }
            const modPath = path.join(globalBuildConfig.rootPath, 'modules', match[1]);
            return {file: path.join(modPath, 'client', match[2])};
        }
        return null;
    }

    /**
     * This function resolves url(...)s in CSS files using a plugin:path syntax
     */
    function postCSSURLResolver({url}) {
        const m = url.match(/^(\w+):(.*)$/);

        if (!m) {
            return url;
        }

        const [name, relPath] = m.slice(1);
        let prefix;

        if (name === 'static') {
            prefix = globalBuildConfig.staticURL;
        } else {
            prefix = path.join(globalBuildConfig.staticURL, 'static/plugins', name);
        }
        return path.join(prefix, relPath);
    }

    function buildSCSSLoader(cssLoaderOptions = {}) {
        return ExtractTextPlugin.extract({
            fallback: 'style-loader',
            use: [{
                loader: 'css-loader',
                options: {
                    sourceMap: true,
                    url: !config.isPlugin, // FIXME: true breaks plugins, false breaks /indico/ in core
                    ...cssLoaderOptions
                }
            }, {
                loader: 'postcss-loader',
                options: {
                    sourceMap: true,
                    config: {
                        path: path.join(
                            globalBuildConfig.rootPath,
                            'postcss.config.js'
                        ),
                        ctx: {
                            postCSSURLOptions: {
                                url: postCSSURLResolver
                            }
                        }
                    }
                }
            }, {
                loader: 'sass-loader',
                options: {
                    sourceMap: true,
                    includePaths: [scssIncludePath],
                    outputStyle: 'compact',
                    importer: [sassResolver, importOnce],
                }
            }],
        });
    }

    const indicoClientPath = globalBuildConfig.clientPath;
    const urlMapPath = path.resolve(globalBuildConfig.rootPath, '..', 'url_map.json');
    const babelPlugins = [['flask-urls', {
        importPrefix: 'indico-url',
        urlMap: require(urlMapPath).rules,
        basePath: globalBuildConfig.baseURLPath,
    }]];

    return {
        devtool: 'source-map',
        context: config.build.clientPath,
        output: {
            path: config.build.distPath,
            filename: 'js/[name].[chunkhash:8].bundle.js',
            publicPath: config.build.distURL,
            devtoolModuleFilenameTemplate: (info) => `webpack:///${getDevtoolFilename(info)}`,
            devtoolFallbackModuleFilenameTemplate: (info) => `webpack:///${getDevtoolFilename(info)}?${info.hash}`,
        },
        module: {
            rules: [
                {
                    test: /\.js$/,
                    loader: 'babel-loader',
                    exclude: /node_modules/,
                    options: {
                        extends: path.resolve(globalBuildConfig.rootPath,
                                              '..', '.babelrc'),
                        plugins: babelPlugins
                    }
                },
                {
                    test: /\.jsx$/,
                    loader: 'babel-loader',
                    exclude: /node_modules/,
                    options: {
                        extends: path.resolve(globalBuildConfig.rootPath,
                                              '..', '.babelrc'),
                        presets: ['@babel/react'],
                        plugins: babelPlugins
                    }
                },
                {
                    oneOf: [
                        {
                            test: /\.css$/,
                            use: ExtractTextPlugin.extract({
                                fallback: 'style-loader',
                                use: {
                                    loader: 'css-loader',
                                    options: _cssLoaderOptions
                                }
                            })
                        },
                        {
                            test: /\.module\.scss$/,
                            use: buildSCSSLoader({
                                context: path.resolve(globalBuildConfig.clientPath, '../../modules'),
                                modules: true,
                                importLoaders: 1,
                                localIdentName: '[path]___[name]__[local]___[hash:base64:5]'
                            })
                        },
                        {
                            test: /\.scss$/,
                            use: buildSCSSLoader()
                        }
                    ]
                }
            ]
        },
        plugins: [
            new ManifestPlugin({
                fileName: 'manifest.json',
                publicPath: config.build.distURL
            }),
            // Do not load moment locales (we'll load them explicitly)
            new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
            new ExtractTextPlugin({
                filename: 'css/[name].[md5:contenthash:hex:8].css'
            }),
            new ProgressBarPlugin({
                format:
                    // eslint-disable-next-line prefer-template
                    chalk.cyan('Code being sent to the moon and back \u{1f680} \u{1f311}') + '  [:bar] ' +
                    chalk.green.bold(':percent') + ' (:elapsed seconds)'
            })
        ],
        resolve: {
            alias: [
                {name: 'indico', alias: path.join(indicoClientPath, 'js/')}
            ],
            symlinks: false,
            extensions: ['.js', '.json', '.jsx'],
            modules: nodeModules
        },
        resolveLoader: {
            modules: nodeModules
        },
        externals: (context, request, callback) => {
            // tell webpack to make certain packages use window.jQuery (and not load it again)
            if (/^jquery$/.test(request) && /(selectize|fullcalendar)/.test(context)) {
                return callback(null, 'jQuery');
            }
            return callback();
        },
        stats: {
            assets: false,
            children: false,
            modules: false,
            chunks: true,
            chunkModules: false,
            chunkOrigins: false,
            chunksSort: 'name'
        },
        mode: currentEnv,
        optimization: {
            splitChunks: {
                cacheGroups: {
                    // 'common' chunk, which should include common dependencies
                    common: (module) => {
                        return {
                            name: 'common',
                            chunks: 'initial',
                            // theme CSS files shouldn't be included in the
                            // common.css chunk, otherwise they will interfere
                            // with interface CSS
                            minChunks: /styles\/themes/.test(module.request) ? 9999 : 2
                        };
                    },
                    // react/redux and friends since they are pretty big
                    react: {
                        test: /\/node_modules\/(react|redux|prop-types\/|lodash-es\/|fbjs\/)/,
                        name: 'react',
                        chunks: 'initial',
                        priority: 10,
                    },
                    semanticui: {
                        test: /node_modules\/(semantic-ui|indico-sui-theme)/,
                        name: 'semantic-ui',
                        chunks: 'initial',
                        priority: 10,
                    }
                }
            }
        }
    };
}

export function indicoStaticLoader(config) {
    return {
        test: /\/static\/(images|fonts)\/.*\.(jpe?g|png|gif|svg|woff2?|ttf|eot)$/,
        use: {
            loader: 'file-loader',
            options: {
                name: generateAssetPath(config, true),
                context: config.build.staticPath,
                emitFile: false,
                publicPath: config.build.staticURL,
            }
        }
    };
}
<commit_msg>Small code style changes<commit_after>/* This file is part of Indico.
 * Copyright (C) 2002 - 2018 European Organization for Nuclear Research (CERN).
 *
 * Indico is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 3 of the
 * License, or (at your option) any later version.
 *
 * Indico is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Indico; if not, see <http://www.gnu.org/licenses/>.
 */

import {createHash} from 'crypto';
import fs from 'fs';
import path from 'path';

import chalk from 'chalk';
import webpack from 'webpack';

import ExtractTextPlugin from 'extract-text-webpack-plugin';
import ManifestPlugin from 'webpack-manifest-plugin';
import ProgressBarPlugin from 'progress-bar-webpack-plugin';
import importOnce from 'node-sass-import-once';

function _resolveTheme(rootPath, indicoClientPath, filePath) {
    const indicoRelativePath = path.resolve(indicoClientPath, filePath);

    if (indicoClientPath && !fs.existsSync(path.resolve(rootPath, filePath)) &&
            fs.existsSync(indicoRelativePath)) {
        return path.resolve(indicoClientPath, filePath);
    }

    return path.resolve(rootPath, filePath);
}

export function getThemeEntryPoints(config, prefix) {
    const themes = config.themes;
    const indicoClientPath = path.join(config.isPlugin ? config.indico.build.clientPath : config.build.clientPath,
                                       'styles');
    const rootPath = path.join(config.build.rootPath);

    return Object.assign(...Object.keys(themes).map((k) => {
        const returnValue = {};
        const escapedKey = k.replace('-', '_');

        returnValue[`themes_${escapedKey}`] = [
            _resolveTheme(rootPath, indicoClientPath, prefix + themes[k].stylesheet)
        ];

        if (themes[k].print_stylesheet) {
            returnValue[`themes_${escapedKey}.print`] = [
                _resolveTheme(rootPath, indicoClientPath, prefix + themes[k].print_stylesheet)
            ];
        }
        return returnValue;
    }));
}

export function generateAssetPath(config, virtualVersion = false) {
    // /css/whatever.css => /css/whatever__v123abcdef.css
    return (file) => {
        const relPath = path.relative(config.build.staticPath, file);
        const {dir, name, ext} = path.parse(relPath);
        const h = createHash('md5');
        h.update(fs.readFileSync(file));
        const hash = h.digest('hex').slice(0, 8);
        // the "virtual version" is used for files that are loaded as-is from the
        // static folder and thus do not actually get the hash in the physical
        // file name. it is distinct from the normal version style so a rule on
        // the web server can strip that version segment
        const fileName = virtualVersion ? `${name}__v${hash}${ext}` : `${name}.${hash}${ext}`;
        // .. -> _, like file-loader does
        return dir.replace(/\.\./g, '_') + path.sep + fileName;
    };
}

export function webpackDefaults(env, config, bundles) {
    const globalBuildConfig = config.indico ? config.indico.build : config.build;
    const currentEnv = (env ? env.NODE_ENV : null) || 'development';
    const nodeModules = [path.join(config.build.indicoSourcePath || path.resolve(config.build.rootPath, '..'),
                                   'node_modules')];

    if (config.isPlugin) {
        // add plugin's node_modules in addition to the core's
        nodeModules.push(path.resolve(config.build.rootPath, '../node_modules'));
    }

    const _cssLoaderOptions = {
        url: true,
    };

    const scssIncludePath = path.join(
        config.isPlugin
            ? path.resolve(config.build.indicoSourcePath, './indico/web/client')
            : path.join(config.build.clientPath),
        'styles'
    );

    function getDevtoolFilename(info) {
        const root = path.resolve(globalBuildConfig.rootPath, '..');
        return path.relative(root, info.absoluteResourcePath);
    }

    /**
     * This function resolves SASS files using a module:path syntax
     */
    function sassResolver(url) {
        const match = url.match(/^(\w+):([\w/-_]+)/);
        if (match) {
            if (config.isPlugin) {
                const {sassOverrides} = bundles;
                if (sassOverrides && sassOverrides[url]) {
                    return {file: path.join(config.build.clientPath, sassOverrides[url])};
                }
            }
            const modPath = path.join(globalBuildConfig.rootPath, 'modules', match[1]);
            return {file: path.join(modPath, 'client', match[2])};
        }
        return null;
    }

    /**
     * This function resolves url(...)s in CSS files using a plugin:path syntax
     */
    function postCSSURLResolver({url}) {
        const m = url.match(/^(\w+):(.*)$/);

        if (!m) {
            return url;
        }

        const [name, relPath] = m.slice(1);
        let prefix;

        if (name === 'static') {
            prefix = globalBuildConfig.staticURL;
        } else {
            prefix = path.join(globalBuildConfig.staticURL, 'static/plugins', name);
        }
        return path.join(prefix, relPath);
    }

    function buildSCSSLoader(cssLoaderOptions = {}) {
        return ExtractTextPlugin.extract({
            fallback: 'style-loader',
            use: [{
                loader: 'css-loader',
                options: {
                    sourceMap: true,
                    url: !config.isPlugin, // FIXME: true breaks plugins, false breaks /indico/ in core
                    ...cssLoaderOptions
                }
            }, {
                loader: 'postcss-loader',
                options: {
                    sourceMap: true,
                    config: {
                        path: path.join(
                            globalBuildConfig.rootPath,
                            'postcss.config.js'
                        ),
                        ctx: {
                            postCSSURLOptions: {
                                url: postCSSURLResolver
                            }
                        }
                    }
                }
            }, {
                loader: 'sass-loader',
                options: {
                    sourceMap: true,
                    includePaths: [scssIncludePath],
                    outputStyle: 'compact',
                    importer: [sassResolver, importOnce],
                }
            }],
        });
    }

    const indicoClientPath = globalBuildConfig.clientPath;
    const urlMapPath = path.resolve(globalBuildConfig.rootPath, '..', 'url_map.json');
    const babelPlugins = [['flask-urls', {
        importPrefix: 'indico-url',
        urlMap: require(urlMapPath).rules,
        basePath: globalBuildConfig.baseURLPath,
    }]];

    return {
        devtool: 'source-map',
        context: config.build.clientPath,
        output: {
            path: config.build.distPath,
            filename: 'js/[name].[chunkhash:8].bundle.js',
            publicPath: config.build.distURL,
            devtoolModuleFilenameTemplate: (info) => `webpack:///${getDevtoolFilename(info)}`,
            devtoolFallbackModuleFilenameTemplate: (info) => `webpack:///${getDevtoolFilename(info)}?${info.hash}`,
        },
        module: {
            rules: [
                {
                    test: /\.js$/,
                    loader: 'babel-loader',
                    exclude: /node_modules/,
                    options: {
                        extends: path.resolve(globalBuildConfig.rootPath,
                                              '..', '.babelrc'),
                        plugins: babelPlugins
                    }
                },
                {
                    test: /\.jsx$/,
                    loader: 'babel-loader',
                    exclude: /node_modules/,
                    options: {
                        extends: path.resolve(globalBuildConfig.rootPath,
                                              '..', '.babelrc'),
                        presets: ['@babel/react'],
                        plugins: babelPlugins
                    }
                },
                {
                    oneOf: [
                        {
                            test: /\.css$/,
                            use: ExtractTextPlugin.extract({
                                fallback: 'style-loader',
                                use: {
                                    loader: 'css-loader',
                                    options: _cssLoaderOptions
                                }
                            })
                        },
                        {
                            test: /\.module\.scss$/,
                            use: buildSCSSLoader({
                                context: path.resolve(globalBuildConfig.clientPath, '../../modules'),
                                modules: true,
                                importLoaders: 1,
                                localIdentName: '[path]___[name]__[local]___[hash:base64:5]'
                            })
                        },
                        {
                            test: /\.scss$/,
                            use: buildSCSSLoader()
                        }
                    ]
                }
            ]
        },
        plugins: [
            new ManifestPlugin({
                fileName: 'manifest.json',
                publicPath: config.build.distURL
            }),
            // Do not load moment locales (we'll load them explicitly)
            new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
            new ExtractTextPlugin({
                filename: 'css/[name].[md5:contenthash:hex:8].css'
            }),
            new ProgressBarPlugin({
                format:
                    // eslint-disable-next-line prefer-template
                    chalk.cyan('Code being sent to the moon and back \u{1f680} \u{1f311}') + '  [:bar] ' +
                    chalk.green.bold(':percent') + ' (:elapsed seconds)'
            })
        ],
        resolve: {
            alias: [
                {name: 'indico', alias: path.join(indicoClientPath, 'js/')}
            ],
            symlinks: false,
            extensions: ['.js', '.json', '.jsx'],
            modules: nodeModules
        },
        resolveLoader: {
            modules: nodeModules
        },
        externals: (context, request, callback) => {
            // tell webpack to make certain packages use window.jQuery (and not load it again)
            if (/^jquery$/.test(request) && /(selectize|fullcalendar)/.test(context)) {
                return callback(null, 'jQuery');
            }
            return callback();
        },
        stats: {
            assets: false,
            children: false,
            modules: false,
            chunks: true,
            chunkModules: false,
            chunkOrigins: false,
            chunksSort: 'name'
        },
        mode: currentEnv,
        optimization: {
            splitChunks: {
                cacheGroups: {
                    // 'common' chunk, which should include common dependencies
                    common: module => ({
                        name: 'common',
                        chunks: 'initial',
                        // theme CSS files shouldn't be included in the
                        // common.css chunk, otherwise they will interfere
                        // with interface CSS
                        minChunks: /styles\/themes/.test(module.request) ? 9999 : 2
                    }),
                    // react/redux and friends since they are pretty big
                    react: {
                        test: /\/node_modules\/(react|redux|prop-types\/|lodash-es\/|fbjs\/)/,
                        name: 'react',
                        chunks: 'initial',
                        priority: 10,
                    },
                    semanticui: {
                        test: /node_modules\/(semantic-ui|indico-sui-theme)/,
                        name: 'semantic-ui',
                        chunks: 'initial',
                        priority: 10,
                    }
                }
            }
        }
    };
}

export function indicoStaticLoader(config) {
    return {
        test: /\/static\/(images|fonts)\/.*\.(jpe?g|png|gif|svg|woff2?|ttf|eot)$/,
        use: {
            loader: 'file-loader',
            options: {
                name: generateAssetPath(config, true),
                context: config.build.staticPath,
                emitFile: false,
                publicPath: config.build.staticURL,
            }
        }
    };
}
<|endoftext|>


<commit_before>'use strict';

angular.module('copayApp.controllers').controller('preferencesFeeController', function($scope, $timeout, $ionicHistory, lodash, gettextCatalog, configService, feeService, ongoingProcess, popupService) {

  $scope.save = function(newFee) {
    var opts = {
      wallet: {
        settings: {
          feeLevel: newFee
        }
      }
    };

    configService.set(opts, function(err) {
      if (err) $log.debug(err);
      $scope.currentFeeLevel = newFee;
      updateCurrentValues();
      $timeout(function() {
        $scope.$apply();
      });
    });
  };

  $scope.$on("$ionicView.beforeEnter", function(event, data) {
    $scope.feeOpts = feeService.feeOpts;
    $scope.currentFeeLevel = feeService.getCurrentFeeLevel();
    $scope.loadingFee = true;
    feeService.getFeeLevels(function(err, levels) {
      $scope.loadingFee = false;
      if (err) {
        //Error is already formatted
        popupService.showAlert(err);
        return;
      }
      $scope.feeLevels = levels;
      updateCurrentValues();
      $scope.$apply();
    });
  });

  var updateCurrentValues = function() {
    if (lodash.isEmpty($scope.feeLevels) || lodash.isEmpty($scope.currentFeeLevel)) return;
    var feeLevelValue = lodash.find($scope.feeLevels['livenet'], {
      level: $scope.currentFeeLevel
    });
    if (lodash.isEmpty(feeLevelValue)) {
      $scope.feePerKBUnit = null;
      $scope.avgConfirmationTime = null;
      return;
    }
    $scope.feePerKBUnit = feeLevelValue.feePerKBUnit;
    $scope.avgConfirmationTime = feeLevelValue.nbBlocks * 10;
  };
});
<commit_msg>remove tabs from fee policy view when back view is confirm<commit_after>'use strict';

angular.module('copayApp.controllers').controller('preferencesFeeController', function($scope, $rootScope, $timeout, $ionicHistory, lodash, gettextCatalog, configService, feeService, ongoingProcess, popupService) {

  $scope.save = function(newFee) {
    var opts = {
      wallet: {
        settings: {
          feeLevel: newFee
        }
      }
    };

    configService.set(opts, function(err) {
      if (err) $log.debug(err);
      $scope.currentFeeLevel = newFee;
      updateCurrentValues();
      $timeout(function() {
        $scope.$apply();
      });
    });
  };

  function hideTabs() {
    $timeout(function() {
      $rootScope.hideTabs = 'tabs-item-hide';
      $rootScope.$apply();
    });
  };

  $scope.$on("$ionicView.beforeEnter", function(event, data) {

    if ($ionicHistory.backView() && ($ionicHistory.backView().stateName == 'tabs.send.confirm')) hideTabs();
    $scope.feeOpts = feeService.feeOpts;
    $scope.currentFeeLevel = feeService.getCurrentFeeLevel();
    $scope.loadingFee = true;
    feeService.getFeeLevels(function(err, levels) {
      $scope.loadingFee = false;
      if (err) {
        //Error is already formatted
        popupService.showAlert(err);
        return;
      }
      $scope.feeLevels = levels;
      updateCurrentValues();
      $scope.$apply();
    });
  });

  var updateCurrentValues = function() {
    if (lodash.isEmpty($scope.feeLevels) || lodash.isEmpty($scope.currentFeeLevel)) return;
    var feeLevelValue = lodash.find($scope.feeLevels['livenet'], {
      level: $scope.currentFeeLevel
    });
    if (lodash.isEmpty(feeLevelValue)) {
      $scope.feePerKBUnit = null;
      $scope.avgConfirmationTime = null;
      return;
    }
    $scope.feePerKBUnit = feeLevelValue.feePerKBUnit;
    $scope.avgConfirmationTime = feeLevelValue.nbBlocks * 10;
  };
});
<|endoftext|>


<commit_before>import isString from 'lodash/isString';
import isInteger from 'lodash/isInteger';
import isPlainObject from 'lodash/isPlainObject';
import typeOf from 'typeof';
import mysql from 'mysql';
import Connection from 'mysql/lib/Connection';
import Promise from 'bluebird';

Promise.promisifyAll(Connection.prototype);

class MigrationStorage {

  /**
   * Creates a new MigrationStorage instance with the designated properties.
   * @param {Object} props umzug passed properties
   * @param {Object} props.storageOptions storage-specific options
   * @param {string} props.storageOptions.database the name of the database
   * @param {string} [props.storageOptions.host=localhost] optional hostname; defaults to "localhost"
   * @param {number} [props.storageOptions.port=3306] optional port number; defaults to 3306
   * @param {string} [props.storageOptions.user=root] optional user name to access the database; defaults to "root"
   * @param {string} [props.storageOptions.password] optional password to access the database; defaults to "" (i.e. empty string)
   * @param {string} [props.storageOptions.table=migration] optional table name to store migration log; defaults to "migration"
   * @throws {TypeError} if arguments are of invalid type
   * @constructor
   */
  constructor(props) {
    if (!isPlainObject(props)) throw new TypeError(`Invalid "props" param; expected plain object, received ${typeOf(props)}`);

    const { storageOptions } = props;
    if (!isPlainObject(storageOptions)) throw new TypeError(`Invalid "storageOptions" property; expected plain object, received ${typeOf(storageOptions)}`);

    const {
      database,
      host = 'localhost',
      port = 3306,
      user = 'root',
      password = '',
      table = 'migration'
    } = storageOptions;
    if (!isString(database)) throw new TypeError(`Invalid "database" storage option; expected string, received ${typeOf(database)}`);
    if (!isString(host)) throw new TypeError(`Invalid "host" storage option; expected string, received ${typeOf(host)}`);
    if (!isInteger(port)) throw new TypeError(`Invalid "port" storage option; expected integer, received ${typeOf(port)}`);
    if (!isString(user)) throw new TypeError(`Invalid "user" storage option; expected string, received ${typeOf(user)}`);
    if (!isString(password)) throw new TypeError(`Invalid "password" storage option; expected string, received ${typeOf(password)}`);
    if (!isString(table)) throw new TypeError(`Invalid "table" storage option; expected string, received ${typeOf(table)}`);

    this.connectionProperties = { host, port, user, password, database };
    this.tableName = table;
  }

  /**
   * Executes the supplied query.
   * @see {@link https://github.com/mysqljs/mysql#performing-queries} for further info
   * @returns Promise
   * @private
   */
  query(sql, values) {
    const conn = mysql.createConnection(this.connectionProperties);

    return conn.connectAsync()
      .then(() => conn.queryAsync(sql, values))
      .finally(() => conn.end());
  }

  createMetaTableIfNotExists() {
    const sql = `
      CREATE TABLE IF NOT EXISTS ?? (
        \`name\` varchar(100) NOT NULL,
        PRIMARY KEY (\`name\`)
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    `;
    const params = [this.tableName];

    return this.query(sql, params);
  }

  logMigration(migrationName) {
    const sql = 'INSERT INTO ?? SET name = ?;';
    const params = [this.tableName, migrationName];

    return this.createMetaTableIfNotExists()
      .then(() => this.query(sql, params));
  }

  async unlogMigration(migrationName) {
    const sql = 'INSERT FROM ?? WHERE name = ? LIMIT 1;';
    const params = [this.tableName, migrationName];

    return this.createMetaTableIfNotExists()
      .then(() => this.query(sql, params));
  }

  async executed() {
    const sql = 'SELECT name FROM ?? ORDER BY name ASC;';
    const params = [this.tableName];

    return this.createMetaTableIfNotExists()
      .then(() => this.query(sql, params))
      .map((o) => o.name);
  }
}

export default MigrationStorage;
<commit_msg>Bugfix: use DELETE SQL statement with unlogMigration()<commit_after>import isString from 'lodash/isString';
import isInteger from 'lodash/isInteger';
import isPlainObject from 'lodash/isPlainObject';
import typeOf from 'typeof';
import mysql from 'mysql';
import Connection from 'mysql/lib/Connection';
import Promise from 'bluebird';

Promise.promisifyAll(Connection.prototype);

class MigrationStorage {

  /**
   * Creates a new MigrationStorage instance with the designated properties.
   * @param {Object} props umzug passed properties
   * @param {Object} props.storageOptions storage-specific options
   * @param {string} props.storageOptions.database the name of the database
   * @param {string} [props.storageOptions.host=localhost] optional hostname; defaults to "localhost"
   * @param {number} [props.storageOptions.port=3306] optional port number; defaults to 3306
   * @param {string} [props.storageOptions.user=root] optional user name to access the database; defaults to "root"
   * @param {string} [props.storageOptions.password] optional password to access the database; defaults to "" (i.e. empty string)
   * @param {string} [props.storageOptions.table=migration] optional table name to store migration log; defaults to "migration"
   * @throws {TypeError} if arguments are of invalid type
   * @constructor
   */
  constructor(props) {
    if (!isPlainObject(props)) throw new TypeError(`Invalid "props" param; expected plain object, received ${typeOf(props)}`);

    const { storageOptions } = props;
    if (!isPlainObject(storageOptions)) throw new TypeError(`Invalid "storageOptions" property; expected plain object, received ${typeOf(storageOptions)}`);

    const {
      database,
      host = 'localhost',
      port = 3306,
      user = 'root',
      password = '',
      table = 'migration'
    } = storageOptions;
    if (!isString(database)) throw new TypeError(`Invalid "database" storage option; expected string, received ${typeOf(database)}`);
    if (!isString(host)) throw new TypeError(`Invalid "host" storage option; expected string, received ${typeOf(host)}`);
    if (!isInteger(port)) throw new TypeError(`Invalid "port" storage option; expected integer, received ${typeOf(port)}`);
    if (!isString(user)) throw new TypeError(`Invalid "user" storage option; expected string, received ${typeOf(user)}`);
    if (!isString(password)) throw new TypeError(`Invalid "password" storage option; expected string, received ${typeOf(password)}`);
    if (!isString(table)) throw new TypeError(`Invalid "table" storage option; expected string, received ${typeOf(table)}`);

    this.connectionProperties = { host, port, user, password, database };
    this.tableName = table;
  }

  /**
   * Executes the supplied query.
   * @see {@link https://github.com/mysqljs/mysql#performing-queries} for further info
   * @returns Promise
   * @private
   */
  query(sql, values) {
    const conn = mysql.createConnection(this.connectionProperties);

    return conn.connectAsync()
      .then(() => conn.queryAsync(sql, values))
      .finally(() => conn.end());
  }

  createMetaTableIfNotExists() {
    const sql = `
      CREATE TABLE IF NOT EXISTS ?? (
        \`name\` varchar(100) NOT NULL,
        PRIMARY KEY (\`name\`)
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    `;
    const params = [this.tableName];

    return this.query(sql, params);
  }

  logMigration(migrationName) {
    const sql = 'INSERT INTO ?? SET name = ?;';
    const params = [this.tableName, migrationName];

    return this.createMetaTableIfNotExists()
      .then(() => this.query(sql, params));
  }

  unlogMigration(migrationName) {
    const sql = 'DELETE FROM ?? WHERE name = ? LIMIT 1;';
    const params = [this.tableName, migrationName];

    return this.createMetaTableIfNotExists()
      .then(() => this.query(sql, params));
  }

  executed() {
    const sql = 'SELECT name FROM ?? ORDER BY name ASC;';
    const params = [this.tableName];

    return this.createMetaTableIfNotExists()
      .then(() => this.query(sql, params))
      .map((o) => o.name);
  }
}

export default MigrationStorage;
<|endoftext|>


<commit_before>/*
Input Mask plugin extensions
http://github.com/RobinHerbots/jquery.inputmask
Copyright (c) 2010 - 2012 Robin Herbots
Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
Version: 1.3.3

Optional extensions on the jquery.inputmask base
*/
(function ($) {
    //number aliases
    $.extend($.inputmask.defaults.aliases, {
        'decimal': {
            mask: "~",
            placeholder: "",
            repeat: 10,
            greedy: false,
            numericInput: true,
            digits: "*", //numer of digits
            groupSeparator: ",", // | "."
            groupSize: 3,
            autoGroup: false,
            regex: {
                number: function (groupSeparator, groupSize, radixPoint, digits) {
                    var escapedGroupSeparator = $.inputmask.escapeRegex.call(this, groupSeparator);
                    var escapedRadixPoint = $.inputmask.escapeRegex.call(this, radixPoint);
                    var digitExpression = isNaN(digits) ? digits : '{0,' + digits + '}';
                    return new RegExp("^[\+-]?(\\d+|\\d{1," + groupSize + "}((" + escapedGroupSeparator + "\\d{" + groupSize + "})?)+)(" + escapedRadixPoint + "\\d" + digitExpression + ")?$");
                }
            },
            onKeyDown: function (e, opts) {
                var $input = $(this), input = this;
                if (e.keyCode == opts.keyCode.TAB) {
                    var nptStr = input._valueGet();
                    var radixPosition = nptStr.indexOf(opts.radixPoint);
                    if (radixPosition != -1) {
                        for (var i = 1; i < opts.digits; i++) {
                            if (nptStr[radixPosition + i]) nptStr = nptStr + "0";
                        }
                        if (nptStr !== $input.val()) {
                            $input.val(nptStr);
                        }
                    }
                }
            },
            definitions: {
                '~': { //real number
                    validator: function (chrs, buffer, pos, strict, opts) {
                        if (chrs == "") return false;
                        var cbuf = strict ? buffer.slice(0, pos) : buffer.slice();
                        cbuf.splice(pos, 0, chrs);
                        var bufferStr = cbuf.join('');
                        if (opts.autoGroup) //strip groupseparator
                            bufferStr = bufferStr.replace(new RegExp("\\" + opts.groupSeparator, "g"), '');
                        var isValid = opts.regex.number(opts.groupSeparator, opts.groupSize, opts.radixPoint, opts.digits).test(bufferStr);
                        if (!isValid) {
                            //let's help the regex a bit
                            bufferStr += "0";
                            isValid = opts.regex.number(opts.groupSeparator, opts.groupSize, opts.radixPoint, opts.digits).test(bufferStr);
                            if (!isValid) {
                                //make a valid group
                                var lastGroupSeparator = bufferStr.lastIndexOf(opts.groupSeparator);
                                for (i = bufferStr.length - lastGroupSeparator; i <= 3; i++) {
                                    bufferStr += "0";
                                }

                                isValid = opts.regex.number(opts.groupSeparator, opts.groupSize, opts.radixPoint, opts.digits).test(bufferStr);
                                if (!isValid && !strict) {
                                    if (chrs == opts.radixPoint) {
                                        isValid = opts.regex.number(opts.groupSeparator, opts.groupSize, opts.radixPoint, opts.digits).test("0" + bufferStr + "0");
                                        if (isValid) {
                                            buffer[pos] = "0";
                                            pos++;
                                            return { "pos": pos };
                                        }
                                    }
                                }
                            }
                        }

                        if (isValid != false && !strict) {
                            var cbuf = buffer.slice();
                            cbuf.splice(pos, 0, "?"); //set position indicator
                            var bufVal = cbuf.join('');
                            if (opts.autoGroup || bufVal.indexOf(opts.groupSeparator) != -1) {
                                bufVal = bufVal.replace(new RegExp("\\" + opts.groupSeparator, "g"), '');
                                var reg = new RegExp('(-?[\\d?]+)([\\d?]{' + opts.groupSize + '})');
                                while (reg.test(bufVal)) {
                                    bufVal = bufVal.replace(reg, '$1' + opts.groupSeparator + '$2');
                                }
                            }
                            buffer.length = bufVal.length; //align the length
                            for (var i = 0, l = bufVal.length; i < l; i++) {
                                buffer[i] = bufVal.charAt(i);
                            }
                            var newPos = buffer.indexOf("?");
                            buffer.splice(newPos, 1);

                            return { "pos": newPos };
                        }
                        return isValid;
                    },
                    cardinality: 1,
                    prevalidator: null
                }
            },
            insertMode: true,
            autoUnmask: false
        },
        'non-negative-decimal': {
            regex: {
                number: function (groupSeparator, groupSize, radixPoint, digits) {
                    var escapedGroupSeparator = $.inputmask.escapeRegex.call(this, groupSeparator);
                    var escapedRadixPoint = $.inputmask.escapeRegex.call(this, radixPoint);
                    var digitExpression = isNaN(digits) ? digits : '{0,' + digits + '}'
                    return new RegExp("^[\+]?(\\d+|\\d{1," + groupSize + "}((" + escapedGroupSeparator + "\\d{" + groupSize + "})?)+)(" + escapedRadixPoint + "\\d" + digitExpression + ")?$");
                }
            },
            alias: "decimal"
        },
        'integer': {
            regex: {
                number: function (groupSeparator, groupSize) { return new RegExp("^([\+\-]?\\d*)$"); }
            },
            alias: "decimal"
        }
    });
})(jQuery);
<commit_msg>adjust regex of non-negative decimal<commit_after>/*
Input Mask plugin extensions
http://github.com/RobinHerbots/jquery.inputmask
Copyright (c) 2010 - 2012 Robin Herbots
Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
Version: 1.3.3a

Optional extensions on the jquery.inputmask base
*/
(function ($) {
    //number aliases
    $.extend($.inputmask.defaults.aliases, {
        'decimal': {
            mask: "~",
            placeholder: "",
            repeat: 10,
            greedy: false,
            numericInput: true,
            digits: "*", //numer of digits
            groupSeparator: ",", // | "."
            groupSize: 3,
            autoGroup: false,
            regex: {
                number: function (groupSeparator, groupSize, radixPoint, digits) {
                    var escapedGroupSeparator = $.inputmask.escapeRegex.call(this, groupSeparator);
                    var escapedRadixPoint = $.inputmask.escapeRegex.call(this, radixPoint);
                    var digitExpression = isNaN(digits) ? digits : '{0,' + digits + '}';
                    return new RegExp("^[\+-]?(\\d+|\\d{1," + groupSize + "}((" + escapedGroupSeparator + "\\d{" + groupSize + "})?)+)(" + escapedRadixPoint + "\\d" + digitExpression + ")?$");
                }
            },
            onKeyDown: function (e, opts) {
                var $input = $(this), input = this;
                if (e.keyCode == opts.keyCode.TAB) {
                    var nptStr = input._valueGet();
                    var radixPosition = nptStr.indexOf(opts.radixPoint);
                    if (radixPosition != -1) {
                        for (var i = 1; i < opts.digits; i++) {
                            if (nptStr[radixPosition + i]) nptStr = nptStr + "0";
                        }
                        if (nptStr !== $input.val()) {
                            $input.val(nptStr);
                        }
                    }
                }
            },
            definitions: {
                '~': { //real number
                    validator: function (chrs, buffer, pos, strict, opts) {
                        if (chrs == "") return false;
                        var cbuf = strict ? buffer.slice(0, pos) : buffer.slice();
                        cbuf.splice(pos, 0, chrs);
                        var bufferStr = cbuf.join('');
                        if (opts.autoGroup) //strip groupseparator
                            bufferStr = bufferStr.replace(new RegExp("\\" + opts.groupSeparator, "g"), '');
                        var isValid = opts.regex.number(opts.groupSeparator, opts.groupSize, opts.radixPoint, opts.digits).test(bufferStr);
                        if (!isValid) {
                            //let's help the regex a bit
                            bufferStr += "0";
                            isValid = opts.regex.number(opts.groupSeparator, opts.groupSize, opts.radixPoint, opts.digits).test(bufferStr);
                            if (!isValid) {
                                //make a valid group
                                var lastGroupSeparator = bufferStr.lastIndexOf(opts.groupSeparator);
                                for (i = bufferStr.length - lastGroupSeparator; i <= 3; i++) {
                                    bufferStr += "0";
                                }

                                isValid = opts.regex.number(opts.groupSeparator, opts.groupSize, opts.radixPoint, opts.digits).test(bufferStr);
                                if (!isValid && !strict) {
                                    if (chrs == opts.radixPoint) {
                                        isValid = opts.regex.number(opts.groupSeparator, opts.groupSize, opts.radixPoint, opts.digits).test("0" + bufferStr + "0");
                                        if (isValid) {
                                            buffer[pos] = "0";
                                            pos++;
                                            return { "pos": pos };
                                        }
                                    }
                                }
                            }
                        }

                        if (isValid != false && !strict) {
                            var cbuf = buffer.slice();
                            cbuf.splice(pos, 0, "?"); //set position indicator
                            var bufVal = cbuf.join('');
                            if (opts.autoGroup || bufVal.indexOf(opts.groupSeparator) != -1) {
                                bufVal = bufVal.replace(new RegExp("\\" + opts.groupSeparator, "g"), '');
                                var reg = new RegExp('(-?[\\d?]+)([\\d?]{' + opts.groupSize + '})');
                                while (reg.test(bufVal)) {
                                    bufVal = bufVal.replace(reg, '$1' + opts.groupSeparator + '$2');
                                }
                            }
                            buffer.length = bufVal.length; //align the length
                            for (var i = 0, l = bufVal.length; i < l; i++) {
                                buffer[i] = bufVal.charAt(i);
                            }
                            var newPos = buffer.indexOf("?");
                            buffer.splice(newPos, 1);

                            return { "pos": newPos };
                        }
                        return isValid;
                    },
                    cardinality: 1,
                    prevalidator: null
                }
            },
            insertMode: true,
            autoUnmask: false
        },
        'non-negative-decimal': {
            regex: {
                number: function (groupSeparator, groupSize, radixPoint, digits) {
                    var escapedGroupSeparator = $.inputmask.escapeRegex.call(this, groupSeparator);
                    var escapedRadixPoint = $.inputmask.escapeRegex.call(this, radixPoint);
                    var digitExpression = isNaN(digits) ? digits : '{0,' + digits + '}'
                    return new RegExp("^[\+]?(\\d+|\\d{1," + groupSize + "}((" + escapedGroupSeparator + "\\d{" + groupSize + "})?)+)(" + escapedRadixPoint + "\\d" + digitExpression + ")?$");
                }
            },
            alias: "decimal"
        },
        'integer': {
            regex: {
                number: function (groupSeparator, groupSize) { return new RegExp("^([\+\-]?\\d*)$"); }
            },
            alias: "decimal"
        }
    });
})(jQuery);
<|endoftext|>


<commit_before>/*
 *   Initializes a new instance of the Blaze class.
 */
function Blaze(coordinate) {
    GameObject.call(this, coordinate);
    this.bullets = Blaze.CONFIG.get('MAX_BULLETS_COUNT');
    this.score = 0;
}

/*
 *   Inherits GameObject
 */
Blaze.prototype = new GameObject();

/*
 *   Corrects the constructor pointer.
 */
Blaze.prototype.constructor = Blaze;

/*
 *   Shoots and lowers the count of the total bullets.
 */
Blaze.prototype.shoot = function (target) {
    this.bullets--;
    if (this.bullets === Blaze.CONFIG.get('MIN_BULLETS_COUNT')) {
        this.reload();
    }

    if (target.position.x <= this.position.x && this.position.x <= target.position.x + target.width
        && target.position.y <= this.position.y && this.position.y <= target.position.y + target.height) {
        //console.log('hit at x:' + this.position.x + " y:" + this.position.y);
        target.Hit();
        this.score += target.score;
        //console.log(target.score);
    }
};

/*
 *   Reloads the bullets to max bullet count.
 */
Blaze.prototype.reload = function () {
    this.bullets = Blaze.CONFIG.get('MAX_BULLETS_COUNT');
};

/*
 *   Constants for the Blaze object.
 */
Blaze.CONFIG = function () {
    var constants = {
        'MAX_BULLETS_COUNT': 3,
        'MIN_BULLETS_COUNT': 0,
        'RELOADING_TIME': 3000

    };

    return {
        get: function (name) {
            return constants[name];
        }
    };
}();

/*
 *   Prints Blaze's properties on the console.
 */
Blaze.prototype.toString = function () {
    return "Blaze:\n" + GameObject.prototype.toString.call(this);
};

/*
 *   Updates the state of Blaze.
 */
Blaze.prototype.update = function (controller, eggman) {

    if (controller.mousePosition !== null) {
        //  console.log(controller.mousePosition);
        GameObject.prototype.update.call(this, controller.mousePosition);
    }

    if (controller.mouseClick !== null) {
        this.shoot(eggman);
        // console.log(controller.mouseClick);
        controller.mouseClick = null;
    }
};<commit_msg>created a constant INITIAL_SCORE in blaze.js<commit_after>/*
 *   Initializes a new instance of the Blaze class.
 */
function Blaze(coordinate) {
    GameObject.call(this, coordinate);
    this.bullets = Blaze.CONFIG.get('MAX_BULLETS_COUNT');
    this.score = Blaze.CONFIG.get('INITIAL_SCORE');
}

/*
 *   Inherits GameObject
 */
Blaze.prototype = new GameObject();

/*
 *   Corrects the constructor pointer.
 */
Blaze.prototype.constructor = Blaze;

/*
 *   Shoots and lowers the count of the total bullets.
 */
Blaze.prototype.shoot = function (target) {
    this.bullets--;
    if (this.bullets === Blaze.CONFIG.get('MIN_BULLETS_COUNT')) {
        this.reload();
    }

    if (target.position.x <= this.position.x && this.position.x <= target.position.x + target.width
        && target.position.y <= this.position.y && this.position.y <= target.position.y + target.height) {
        //console.log('hit at x:' + this.position.x + " y:" + this.position.y);
        target.Hit();
        this.score += target.score;
        //console.log(target.score);
    }
};

/*
 *   Reloads the bullets to max bullet count.
 */
Blaze.prototype.reload = function () {
    this.bullets = Blaze.CONFIG.get('MAX_BULLETS_COUNT');
};

/*
 *   Constants for the Blaze object.
 */
Blaze.CONFIG = function () {
    var constants = {
        'MAX_BULLETS_COUNT': 3,
        'MIN_BULLETS_COUNT': 0,
        'RELOADING_TIME': 3000,
        'INITIAL_SCORE': 0

    };

    return {
        get: function (name) {
            return constants[name];
        }
    };
}();

/*
 *   Prints Blaze's properties on the console.
 */
Blaze.prototype.toString = function () {
    return "Blaze:\n" + GameObject.prototype.toString.call(this);
};

/*
 *   Updates the state of Blaze.
 */
Blaze.prototype.update = function (controller, eggman) {

    if (controller.mousePosition !== null) {
        //  console.log(controller.mousePosition);
        GameObject.prototype.update.call(this, controller.mousePosition);
    }

    if (controller.mouseClick !== null) {
        this.shoot(eggman);
        // console.log(controller.mouseClick);
        controller.mouseClick = null;
    }
};<|endoftext|>


<commit_before>'use strict'; define('web-ext-utils/utils', function() {

const escape = string => string.replace(/[\-\[\]\{\}\(\)\*\+\?\.\,\\\^\$\|\#]/g, '\\$&');

const matchPattern = (/^(?:(\*|http|https|file|ftp):\/\/(\*|(?:\*\.)?[^\/\*]+|)\/(.*))$/);

function matchPatternToRegExp(pattern) {
	const [ , sheme, host, path, ] = matchPattern.exec(pattern);
	return new RegExp('^(?:'+
		(sheme === '*' ? 'https?' : escape(sheme))
		+':\/\/'+
		escape(host).replace(/\\\*/g, '[^\/]*')
		+'\/'+
		escape(path).replace(/\\\*/g, '.*')
	+')$');
}

return {
	matchPatternToRegExp,
};

});
<commit_msg>add utils/attachAllContentScripts()<commit_after>'use strict'; define('web-ext-utils/utils', [
	'web-ext-utils/chrome'
], function(
	{ Tabs, }
) {

const escape = string => string.replace(/[\-\[\]\{\}\(\)\*\+\?\.\,\\\^\$\|\#]/g, '\\$&');

const matchPattern = (/^(?:(\*|http|https|file|ftp):\/\/(\*|(?:\*\.)?[^\/\*]+|)\/(.*))$/);

function matchPatternToRegExp(pattern) {
	const [ , sheme, host, path, ] = matchPattern.exec(pattern);
	return new RegExp('^(?:'+
		(sheme === '*' ? 'https?' : escape(sheme))
		+':\/\/'+
		escape(host).replace(/\\\*/g, '[^\/]*')
		+'\/'+
		escape(path).replace(/\\\*/g, '.*')
	+')$');
}

/**
 * Can be called during the extension startup to immediately attach all content scripts as they are specified in the 'manifest.json'.
 * Supported keys for each content script are 'js', 'css', 'matches' and 'exclude_matches'. Globs are not supported.
 * @param  {object}    options          Optional options object
 * @param  {function}  options.cleanup  Optional function whose code is executed in each included tab before each content script to remove old versions of the script.
 * @return {Promise([ natural, ])}      Promise that resolves once the cleanup function ran in all included tabs. The numbers are the number of tabs each content script is applied to.
 *                                      Note, that the content scripts themselves have not necessarily been executed yet
 */
function attachAllContentScripts({ cleanup, } = { }) {
	if (typeof (cleanup = cleanup || (() => void 0)) !== 'function') { throw new TypeError('"Cleanup" paramter must be a function or falsey'); }

	return Tabs.query({ }).then(tabs => {
		return Promise.all(chrome.runtime.getManifest().content_scripts.map(({ js, css, matches, exclude_matches, }) => {
			const includes = (matches || [ ]).map(pattern => pattern === '<all_urls>' ? (/./) : matchPatternToRegExp(pattern));
			const excludes = (exclude_matches || [ ]).map(matchPatternToRegExp);
			return Promise.all(tabs.map(({ id, url, }) => {
				if (!url || !includes.some(exp => exp.test(url)) || excludes.some(exp => exp.test(url))) { return; }
				return Tabs.executeScript(id, { code: `(${ cleanup })();`, })
				.then(() => {
					css && css.forEach(file => chrome.tabs.insertCSS(id, { file, }));
					js && js.forEach(file => chrome.tabs.executeScript(id, { file, }));
					return true;
				})
				.catch(error => console.log('skipped tab', error)); // not allowed to execute
			})).then(_=>_.filter(_=>_).length);
		}));
	});
}

return {
	matchPatternToRegExp,
	attachAllContentScripts,
};

});
<|endoftext|>


<commit_before>import GraphicsHelper from 'helpers/GraphicsHelper';
import Deferred from 'dojo/Deferred';
import Request from 'utils/request';
import {errors} from 'js/config';

const AnalysisHelper = {

  findWatershed: pointGeometry => {
    brApp.debug('AnalysisHelper >>> findWatershed');
    let deferred = new Deferred();
    Request.getWatershedByGeometry(pointGeometry).then(feature => {
      if (feature) {
        deferred.resolve(feature);
        brApp.map.centerAndZoom(pointGeometry, 8);
        GraphicsHelper.addCustomPoint(pointGeometry);
      } else {
        deferred.reject(errors.featureNotFound);
      }
    }, err => {
      console.error(err);
      deferred.reject(err);
    });
    return deferred;
  },

  performUpstreamAnalysis: geometry => {
    brApp.debug('AnalysisHelper >>> performUpstreamAnalysis');
    let deferred = new Deferred();
    Request.getUpstreamAnalysis(geometry).then(dataValue => {
      if (dataValue.features.length === 1) {
        dataValue.features.forEach(GraphicsHelper.addUpstreamGraphic);
        deferred.resolve(dataValue.features[0]);
      }
    }, deferred.reject);
    return deferred;
  }

};

export { AnalysisHelper as default };
<commit_msg>testing fix<commit_after>import GraphicsHelper from 'helpers/GraphicsHelper';
import Deferred from 'dojo/Deferred';
import Request from 'utils/request';
import {errors} from 'js/config';

const AnalysisHelper = {

  findWatershed: pointGeometry => {
    brApp.debug('AnalysisHelper >>> findWatershed');
    let deferred = new Deferred();
    Request.getWatershedByGeometry(pointGeometry).then(feature => {
      if (feature) {
        deferred.resolve(feature);
        brApp.map.centerAndZoom(pointGeometry, 8);
        GraphicsHelper.addCustomPoint(pointGeometry);
      } else {
        deferred.reject(errors.featureNotFound);
      }
    }, err => {
      console.error(err);
      deferred.reject(err);
    });
    return deferred;
  },

  performUpstreamAnalysis: geometry => {
    brApp.debug('AnalysisHelper >>> performUpstreamAnalysis');
    let deferred = new Deferred();
    Request.getUpstreamAnalysis(geometry).then(dataValue => {
      if (dataValue.features.length === 1) {
        dataValue.features.forEach(GraphicsHelper.addUpstreamGraphic);
        deferred.resolve(dataValue.features[0]);
      }
    });
    return deferred;
  }

};

export { AnalysisHelper as default };
<|endoftext|>


<commit_before>/*
Input Mask plugin extentions
http://github.com/RobinHerbots/jquery.inputmask
Copyright (c) 2010 - 2012 Robin Herbots
Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
Version: 1.0.2

Optional extentions on the jquery.inputmask base
*/
(function($) {
                    //number aliases
                    $.extend($.inputmask.defaults, {
                        radixPoint: "\.", // | ","
                        digits: "*", //numer of digits
                        groupSeparator: ",", // | "\."
                        groupSize: 3,
                        definitions: {
                           '9': {
                                  validator: function(chrs, buffer, pos, strict, opts) {
                                        var isValid = opts.definitions['9'].regex.test(chrs);
                                        if(isValid){
                                          //do some grouping
                                        }
                                        return isValid;
                                  },
                                  cardinality: 1,
                                  regex:  new RegExp("[0-9]")
                            }
                        }
                    });
                    $.extend($.inputmask.defaults.aliases, {
                        'decimal': {
                            mask: "~",
                            placeholder: "",
                            repeat: 10,
                            greedy: false,
                            numericInput: true,
                            regex: {
                                number: function(radixPoint, digits) { return new RegExp("^[\+\\d\-]{1}\\d*[" + radixPoint + "]?\\d" + digits + "$"); }
                            },
                            onKeyDown: function(e, opts) {
                                var $input = $(this), input = this;
                                if (e.keyCode == opts.keyCode.TAB) {
                                    var nptStr = input._valueGet();
                                    var radixPosition = nptStr.indexOf(opts.radixPoint[opts.radixPoint.length -1]);
                                    if(radixPosition != -1){
                                    	for(var i = 1; i < opts.digits; i++) {
                                    		if(nptStr[radixPosition + i]) nptStr = nptStr + "0";
                                    	}
                                    	$input.val(nptStr);
                                    }
                                }
                            },
                            definitions: {
                                '~': { //real number
                                    validator: function(chrs, buffer, pos, strict, opts) {
                                        function digitExpression() {
                                            return isNaN(opts.digits) ? opts.digits : '{0,' + opts.digits + '}';
                                        }
                                        var cbuf = buffer.slice();
                                        cbuf.splice(pos, 0, chrs);
                                        var bufferStr = cbuf.join('');
                                        var isValid = opts.regex.number(opts.radixPoint, digitExpression()).test(bufferStr);
                                        if (!isValid) {
                                            if (strict) { //shiftL & shiftR use strict only validate from 0 to position
                                                var cbuf = buffer.slice(0, pos);
                                                cbuf.splice(pos, 0, chrs);
                                                var bufferStr = cbuf.join('');
                                                var isValid = opts.regex.number(opts.radixPoint, digitExpression()).test(bufferStr);
                                            }
                                            else {
                                                if (bufferStr == opts.radixPoint) {
                                                    isValid = opts.regex.number(opts.radixPoint, digitExpression()).test("0" + bufferStr);
                                                    if (isValid) {
                                                        buffer[pos] = "0";
                                                        pos++;
                                                        return pos;
                                                    }
                                                }
                                            }
                                        }
                                        //todo grouping, radixpoint positioning
                                        return isValid;
                                    },
                                    cardinality: 1,
                                    prevalidator: null
                                }
                            },
                            insertMode: true
                        },
                        'non-negative-decimal': {
                            regex: {
                                number: function(radixPoint, digits) { return new RegExp("^\\d+[" + radixPoint + "]?\\d" + digits + "$"); }
                            },
                            alias: "decimal"
                        },
                        'integer': {
                            regex: {
                                number: function() { return new RegExp("^([\+\-]?\\d*)$"); }
                            },
                            alias: "decimal"
                        }
                    });
})(jQuery);<commit_msg>add autoGroup property<commit_after>/*
Input Mask plugin extentions
http://github.com/RobinHerbots/jquery.inputmask
Copyright (c) 2010 - 2012 Robin Herbots
Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
Version: 1.0.2

Optional extentions on the jquery.inputmask base
*/
(function($) {
                    //number aliases
                    $.extend($.inputmask.defaults, {
                        radixPoint: "\.", // | ","
                        digits: "*", //numer of digits
                        groupSeparator: ",", // | "\."
                        groupSize: 3,
                        autoGroup: false,
                        definitions: {
                           '9': {
                                  validator: function(chrs, buffer, pos, strict, opts) {
                                        var isValid = opts.definitions['9'].regex.test(chrs);
                                        if(isValid){
                                          //do some grouping
                                        }
                                        return isValid;
                                  },
                                  cardinality: 1,
                                  regex:  new RegExp("[0-9]")
                            }
                        }
                    });
                    $.extend($.inputmask.defaults.aliases, {
                        'decimal': {
                            mask: "~",
                            placeholder: "",
                            repeat: 10,
                            greedy: false,
                            numericInput: true,
                            regex: {
                                number: function(radixPoint, digits) { return new RegExp("^[\+\\d\-]{1}\\d*[" + radixPoint + "]?\\d" + digits + "$"); }
                            },
                            onKeyDown: function(e, opts) {
                                var $input = $(this), input = this;
                                if (e.keyCode == opts.keyCode.TAB) {
                                    var nptStr = input._valueGet();
                                    var radixPosition = nptStr.indexOf(opts.radixPoint[opts.radixPoint.length -1]);
                                    if(radixPosition != -1){
                                    	for(var i = 1; i < opts.digits; i++) {
                                    		if(nptStr[radixPosition + i]) nptStr = nptStr + "0";
                                    	}
                                    	$input.val(nptStr);
                                    }
                                }
                            },
                            definitions: {
                                '~': { //real number
                                    validator: function(chrs, buffer, pos, strict, opts) {
                                        function digitExpression() {
                                            return isNaN(opts.digits) ? opts.digits : '{0,' + opts.digits + '}';
                                        }
                                        var cbuf = buffer.slice();
                                        cbuf.splice(pos, 0, chrs);
                                        var bufferStr = cbuf.join('');
                                        var isValid = opts.regex.number(opts.radixPoint, digitExpression()).test(bufferStr);
                                        if (!isValid) {
                                            if (strict) { //shiftL & shiftR use strict only validate from 0 to position
                                                var cbuf = buffer.slice(0, pos);
                                                cbuf.splice(pos, 0, chrs);
                                                var bufferStr = cbuf.join('');
                                                var isValid = opts.regex.number(opts.radixPoint, digitExpression()).test(bufferStr);
                                            }
                                            else {
                                                if (bufferStr == opts.radixPoint) {
                                                    isValid = opts.regex.number(opts.radixPoint, digitExpression()).test("0" + bufferStr);
                                                    if (isValid) {
                                                        buffer[pos] = "0";
                                                        pos++;
                                                        return pos;
                                                    }
                                                }
                                            }
                                        }
                                        //todo grouping, radixpoint positioning
                                        return isValid;
                                    },
                                    cardinality: 1,
                                    prevalidator: null
                                }
                            },
                            insertMode: true
                        },
                        'non-negative-decimal': {
                            regex: {
                                number: function(radixPoint, digits) { return new RegExp("^\\d+[" + radixPoint + "]?\\d" + digits + "$"); }
                            },
                            alias: "decimal"
                        },
                        'integer': {
                            regex: {
                                number: function() { return new RegExp("^([\+\-]?\\d*)$"); }
                            },
                            alias: "decimal"
                        }
                    });
})(jQuery);<|endoftext|>


<commit_before>'use strict';

var path = require('path');
var config = require('./config');
var babel = require('./babel');

class Utils {

    /**
     * load webpack:
     *     @task dev: add dev-server and enable HMR, according to mock config, enable mock
     *     @task release: add uglifyjs
     * @return config
     */
    loadWebpack(target) {
        var webpack = require('webpack');
        var conf = config.loadConfig();

        switch (target) {
            case 'dev':
                var pack_config = this.mergeConfig(true);
                pack_config.devtool = 'eval';

                if (conf.mock === true) {
                    var babelQueryStr = babel(true);
                    var entryPath = [];
                    if (conf.webpack && conf.webpack.entry) {
                        for (var entry in conf.webpack.entry) {
                            entryPath.push(path.resolve(process.cwd(), entry + '.js'));
                        }
                    }

                    //load mock.js before all
                    pack_config.module.loaders.push({
                        test: new RegExp(entryPath.join('|')),
                        exclude: /(node_modules|bower_components)/,
                        loaders: ['imports?Mock=./mock/mock.js', `babel?${babelQueryStr}`]
                    });
                }

                // add plugin
                pack_config.plugins.push(new webpack.HotModuleReplacementPlugin());

                return pack_config;
            case 'release':
                var ExtractTextPlugin = require('extract-text-webpack-plugin');
                var pack_config = this.mergeConfig();
                // source map for production
                pack_config.devtool = 'source-map';
                pack_config.module.loaders.forEach((loader) => {
                    if (loader.test.test('*.less')) {
                        loader.loader = ExtractTextPlugin.extract('style', 'css?source-map!postcss!less');
                    }
                })
                pack_config.plugins.push(new webpack.optimize.UglifyJsPlugin());
                pack_config.plugins.push(new ExtractTextPlugin('[name].[hash].css'));

                return pack_config;
            default:
                break;
        }

        return null;
    }

    /**
     * parse entry
     * @param  {[string]} dev:
     *     dev: add dev server and HMR entries
     *     release: do nothing with enties expcet convert string to array
     * @return {[type]}
     */
    parseEntry(entry, dev, depth) {
        var conf = config.loadConfig();
        if (entry) {
            var type = Object.prototype.toString.call(entry);
            if (type === '[object String]') {
                entry = [entry];
                if (dev) {
                    entry.unshift(`webpack-dev-server/client?http://localhost:${conf.port}`, 'webpack/hot/dev-server');
                }
            } else if (type === '[object Array]') {
                if (dev) {
                    entry.unshift(`webpack-dev-server/client?http://localhost:${conf.port}`, 'webpack/hot/dev-server');
                }
            } else {
                for (var key in entry) {
                    entry[key] = this.parseEntry(entry[key], dev);
                }
            }

            return entry;
        } else {
            console.error('[kil]: No entry is found!'.to.bold.red.color);
        }
    }

    /**
     * merge webpack default config, user's config, and config from package.json
     * @param  {Boolean} isDebug : is debug mode, add dev-sever or not
     * @return {[Object]}
     */
    mergeConfig(isDebug) {
        var pack_def = require('./pack');
        var pack = this.mergeJsonConfig();

        if (!pack) {
            return pack_def;
        } else {
            var pack_config = pack;
            if (!pack.entry) {
                pack_config.entry = pack_def.entry;
            }
            pack_config.entry = this.parseEntry(pack_config.entry, isDebug);
            // use kil default webpack config, for build use
            pack_config.output = pack_def.output;

            if (pack_config.module && pack_config.module.loaders) {
                Array.prototype.push.apply(pack_def.module.loaders, pack_config.module.loaders);
            } else {
                pack_config.module = {};
            }

            pack_config.module.loaders = pack_def.module.loaders;
            pack_config.module.loaders.push({
                test: /\.jsx?$/,
                exclude: /(node_modules|bower_components)/,
                loaders: [`babel?${babel(isDebug)}`]
            });

            pack_config.resolve = pack.resolve || pack_def.resolve;
            pack_config.resolveLoader = pack.resolveLoader || pack_def.resolveLoader;

            if (pack_config.plugins) {
                Array.prototype.push.apply(pack_def.plugins, pack_config.plugins);
            }
            pack_config.plugins = pack_def.plugins;

            if (pack_config.externals) {
                Array.prototype.push.apply(pack_def.externals, pack_config.externals);
            }

            pack_config.externals = pack_def.externals;
            pack_config.postcss = pack_def.postcss;

            pack_config.module.loaders.push({
                test: /\.vue$/,
                exclude: /(node_modules|bower_components)/,
                loaders: ['vue']
            });
            pack_config.vue = {
                loaders: {
                    js: `babel?${babel(isDebug)}`,
                }
            }

            return pack_config;
        }
    }

    /**
     * if pack.js not exist, read config from package.json
     * @return {[Object]}  : config json
     */
    mergeJsonConfig() {
        var pack;
        try {
            pack = require(`${process.cwd()}/pack`);
        } catch (e) {
            console.info('Error: %s'.to.bold.blue.color, e.message);
            console.info('Info: use default pack.js provided by kil.'.to.bold.blue.color);
        }

        if (!pack) {
            var conf = config.loadConfig().webpack;
            pack = {
                entry: conf.entry || 'main',
                plugins: conf.plugins
            }
        }

        return pack;
    }

}

module.exports = new Utils();
<commit_msg>remove hash when develop<commit_after>'use strict';

var path = require('path');
var config = require('./config');
var babel = require('./babel');

class Utils {

    /**
     * load webpack:
     *     @task dev: add dev-server and enable HMR, according to mock config, enable mock
     *     @task release: add uglifyjs
     * @return config
     */
    loadWebpack(target) {
        var webpack = require('webpack');
        var conf = config.loadConfig();

        switch (target) {
            case 'dev':
                var pack_config = this.mergeConfig(true);
                pack_config.devtool = 'eval';

                if (conf.mock === true) {
                    var babelQueryStr = babel(true);
                    var entryPath = [];
                    if (conf.webpack && conf.webpack.entry) {
                        for (var entry in conf.webpack.entry) {
                            entryPath.push(path.resolve(process.cwd(), entry + '.js'));
                        }
                    }

                    //load mock.js before all
                    pack_config.module.loaders.push({
                        test: new RegExp(entryPath.join('|')),
                        exclude: /(node_modules|bower_components)/,
                        loaders: ['imports?Mock=./mock/mock.js', `babel?${babelQueryStr}`]
                    });
                }

                // add plugin
                pack_config.plugins.push(new webpack.HotModuleReplacementPlugin());
                pack_config.output.filename = '[name].js';
                pack_config.output.chunkFilename = '[id].js';

                return pack_config;
            case 'release':
                var ExtractTextPlugin = require('extract-text-webpack-plugin');
                var pack_config = this.mergeConfig();
                // source map for production
                pack_config.devtool = 'source-map';
                pack_config.module.loaders.forEach((loader) => {
                    if (loader.test.test('*.less')) {
                        loader.loader = ExtractTextPlugin.extract('style', 'css?source-map!postcss!less');
                    }
                    if (loader.test.test('*.css')) {
                        loader.loader = ExtractTextPlugin.extract('style', 'css?source-map!postcss');
                    }
                })
                pack_config.plugins.push(new webpack.optimize.UglifyJsPlugin());
                pack_config.plugins.push(new ExtractTextPlugin('[name].[hash].css'));

                pack_config.output.filename = '[name].[hash].js';
                pack_config.output.chunkFilename = '[id].[hash].js';

                return pack_config;
            default:
                break;
        }

        return null;
    }

    /**
     * parse entry
     * @param  {[string]} dev:
     *     dev: add dev server and HMR entries
     *     release: do nothing with enties expcet convert string to array
     * @return {[type]}
     */
    parseEntry(entry, dev, depth) {
        var conf = config.loadConfig();
        if (entry) {
            var type = Object.prototype.toString.call(entry);
            if (type === '[object String]') {
                entry = [entry];
                if (dev) {
                    entry.unshift(`webpack-dev-server/client?http://localhost:${conf.port}`, 'webpack/hot/dev-server');
                }
            } else if (type === '[object Array]') {
                if (dev) {
                    entry.unshift(`webpack-dev-server/client?http://localhost:${conf.port}`, 'webpack/hot/dev-server');
                }
            } else {
                for (var key in entry) {
                    entry[key] = this.parseEntry(entry[key], dev);
                }
            }

            return entry;
        } else {
            console.error('[kil]: No entry is found!'.to.bold.red.color);
        }
    }

    /**
     * merge webpack default config, user's config, and config from package.json
     * @param  {Boolean} isDebug : is debug mode, add dev-sever or not
     * @return {[Object]}
     */
    mergeConfig(isDebug) {
        var pack_def = require('./pack');
        var pack = this.mergeJsonConfig();

        if (!pack) {
            return pack_def;
        } else {
            var pack_config = pack;
            if (!pack.entry) {
                pack_config.entry = pack_def.entry;
            }
            pack_config.entry = this.parseEntry(pack_config.entry, isDebug);
            // use kil default webpack config, for build use
            pack_config.output = pack_def.output;

            if (pack_config.module && pack_config.module.loaders) {
                Array.prototype.push.apply(pack_def.module.loaders, pack_config.module.loaders);
            } else {
                pack_config.module = {};
            }

            pack_config.module.loaders = pack_def.module.loaders;
            pack_config.module.loaders.push({
                test: /\.jsx?$/,
                exclude: /(node_modules|bower_components)/,
                loaders: [`babel?${babel(isDebug)}`]
            });

            pack_config.resolve = pack.resolve || pack_def.resolve;
            pack_config.resolveLoader = pack.resolveLoader || pack_def.resolveLoader;

            if (pack_config.plugins) {
                Array.prototype.push.apply(pack_def.plugins, pack_config.plugins);
            }
            pack_config.plugins = pack_def.plugins;

            if (pack_config.externals) {
                Array.prototype.push.apply(pack_def.externals, pack_config.externals);
            }

            pack_config.externals = pack_def.externals;
            pack_config.postcss = pack_def.postcss;

            pack_config.module.loaders.push({
                test: /\.vue$/,
                exclude: /(node_modules|bower_components)/,
                loaders: ['vue']
            });
            pack_config.vue = {
                loaders: {
                    js: `babel?${babel(isDebug)}`,
                }
            }

            return pack_config;
        }
    }

    /**
     * if pack.js not exist, read config from package.json
     * @return {[Object]}  : config json
     */
    mergeJsonConfig() {
        var pack;
        try {
            pack = require(`${process.cwd()}/pack`);
        } catch (e) {
            console.info('Error: %s'.to.bold.blue.color, e.message);
            console.info('Info: use default pack.js provided by kil.'.to.bold.blue.color);
        }

        if (!pack) {
            var conf = config.loadConfig().webpack;
            pack = {
                entry: conf.entry || 'main',
                plugins: conf.plugins
            }
        }

        return pack;
    }

}

module.exports = new Utils();
<|endoftext|>


<commit_before>/*
Input Mask plugin extentions
http://github.com/RobinHerbots/jquery.inputmask
Copyright (c) 2010 - 2012 Robin Herbots
Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
Version: 1.0.3

Optional extentions on the jquery.inputmask base
*/
            (function($) {
                //number aliases
                $.extend($.inputmask.defaults, {
                    definitions: {
                        '9': {
                            validator: function(chrs, buffer, pos, strict, opts) {
                                var isValid = opts.definitions['9'].regex.test(chrs);
                                if (isValid) {
                                    //do some grouping
                                }
                                return isValid;
                            },
                            cardinality: 1,
                            regex: new RegExp("[0-9]")
                        }
                    }
                });
                $.extend($.inputmask.defaults.aliases, {
                    'decimal': {
                        mask: "~",
                        placeholder: "",
                        repeat: 10,
                        greedy: false,
                        numericInput: true,
                        regex: {
                            number: function(radixPoint, digits) { return new RegExp("^[\+\\d\-]{1}\\d*[" + radixPoint + "]?\\d" + digits + "$"); }
                        },
                        onKeyDown: function(e, opts) {
                            var $input = $(this), input = this;
                            if (e.keyCode == opts.keyCode.TAB) {
                                var nptStr = input._valueGet();
                                var radixPosition = nptStr.indexOf(opts.radixPoint[opts.radixPoint.length - 1]);
                                if (radixPosition != -1) {
                                    for (var i = 1; i < opts.digits; i++) {
                                        if (nptStr[radixPosition + i]) nptStr = nptStr + "0";
                                    }
                                    $input.val(nptStr);
                                }
                            }
                        },
                        definitions: {
                            '~': { //real number
                                validator: function(chrs, buffer, pos, strict, opts) {
                                    function digitExpression() {
                                        return isNaN(opts.digits) ? opts.digits : '{0,' + opts.digits + '}';
                                    }
                                    var cbuf = buffer.slice();
                                    cbuf.splice(pos, 0, chrs);
                                    var bufferStr = cbuf.join('');
                                    var isValid = opts.regex.number(opts.radixPoint, digitExpression()).test(bufferStr);
                                    if (!isValid) {
                                        if (strict) { //shiftL & shiftR use strict only validate from 0 to position
                                            var cbuf = buffer.slice(0, pos);
                                            cbuf.splice(pos, 0, chrs);
                                            var bufferStr = cbuf.join('');
                                            var isValid = opts.regex.number(opts.radixPoint, digitExpression()).test(bufferStr);
                                        }
                                        else {
                                            if (bufferStr == opts.radixPoint) {
                                                isValid = opts.regex.number(opts.radixPoint, digitExpression()).test("0" + bufferStr);
                                                if (isValid) {
                                                    buffer[pos] = "0";
                                                    pos++;
                                                    return { "pos": pos };
                                                }
                                            }
                                        }
                                    }
                                    //todo grouping, radixpoint positioning
                                    return isValid;
                                },
                                cardinality: 1,
                                prevalidator: null
                            }
                        },
                        insertMode: true
                    },
                    'non-negative-decimal': {
                        regex: {
                            number: function(radixPoint, digits) { return new RegExp("^\\d+[" + radixPoint + "]?\\d" + digits + "$"); }
                        },
                        alias: "decimal"
                    },
                    'integer': {
                        regex: {
                            number: function() { return new RegExp("^([\+\-]?\\d*)$"); }
                        },
                        alias: "decimal"
                    }
                });
            })(jQuery);<commit_msg>fix and comment out new 9 definition<commit_after>/*
Input Mask plugin extentions
http://github.com/RobinHerbots/jquery.inputmask
Copyright (c) 2010 - 2012 Robin Herbots
Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)
Version: 1.0.4

Optional extentions on the jquery.inputmask base
*/
            (function($) {
                //number aliases
                //$.extend($.inputmask.defaults.definitions, {
                //    '9': {
                //        validator: function(chrs, buffer, pos, strict, opts) {
                //            var isValid = opts.definitions['9'].regex.test(chrs);
                //            if (isValid) {
                                //do some grouping
                //            }
                //            return isValid;
                //        },
                //        cardinality: 1,
                //        regex: new RegExp("[0-9]")
                //    }
                //});
                $.extend($.inputmask.defaults.aliases, {
                    'decimal': {
                        mask: "~",
                        placeholder: "",
                        repeat: 10,
                        greedy: false,
                        numericInput: true,
                        regex: {
                            number: function(radixPoint, digits) { return new RegExp("^[\+\\d\-]{1}\\d*[" + radixPoint + "]?\\d" + digits + "$"); }
                        },
                        onKeyDown: function(e, opts) {
                            var $input = $(this), input = this;
                            if (e.keyCode == opts.keyCode.TAB) {
                                var nptStr = input._valueGet();
                                var radixPosition = nptStr.indexOf(opts.radixPoint[opts.radixPoint.length - 1]);
                                if (radixPosition != -1) {
                                    for (var i = 1; i < opts.digits; i++) {
                                        if (nptStr[radixPosition + i]) nptStr = nptStr + "0";
                                    }
                                    $input.val(nptStr);
                                }
                            }
                        },
                        definitions: {
                            '~': { //real number
                                validator: function(chrs, buffer, pos, strict, opts) {
                                    function digitExpression() {
                                        return isNaN(opts.digits) ? opts.digits : '{0,' + opts.digits + '}';
                                    }
                                    var cbuf = buffer.slice();
                                    cbuf.splice(pos, 0, chrs);
                                    var bufferStr = cbuf.join('');
                                    var isValid = opts.regex.number(opts.radixPoint, digitExpression()).test(bufferStr);
                                    if (!isValid) {
                                        if (strict) { //shiftL & shiftR use strict only validate from 0 to position
                                            var cbuf = buffer.slice(0, pos);
                                            cbuf.splice(pos, 0, chrs);
                                            var bufferStr = cbuf.join('');
                                            var isValid = opts.regex.number(opts.radixPoint, digitExpression()).test(bufferStr);
                                        }
                                        else {
                                            if (bufferStr == opts.radixPoint) {
                                                isValid = opts.regex.number(opts.radixPoint, digitExpression()).test("0" + bufferStr);
                                                if (isValid) {
                                                    buffer[pos] = "0";
                                                    pos++;
                                                    return { "pos": pos };
                                                }
                                            }
                                        }
                                    }
                                    //todo grouping, radixpoint positioning
                                    return isValid;
                                },
                                cardinality: 1,
                                prevalidator: null
                            }
                        },
                        insertMode: true
                    },
                    'non-negative-decimal': {
                        regex: {
                            number: function(radixPoint, digits) { return new RegExp("^\\d+[" + radixPoint + "]?\\d" + digits + "$"); }
                        },
                        alias: "decimal"
                    },
                    'integer': {
                        regex: {
                            number: function() { return new RegExp("^([\+\-]?\\d*)$"); }
                        },
                        alias: "decimal"
                    }
                });
            })(jQuery);<|endoftext|>