<commit_before>define(
  'ephox.echo.api.AriaRegister',

  [
    'ephox.classify.Type',
    'ephox.compass.Arr',
    'ephox.compass.Obj',
    'ephox.echo.api.Styles',
    'ephox.epithet.Id',
    'ephox.highway.Merger',
    'ephox.peanut.Fun',
    'ephox.sugar.api.Attr',
    'ephox.sugar.api.Class',
    'ephox.sugar.api.Element',
    'ephox.sugar.api.Insert',
    'ephox.sugar.api.InsertAll'
  ],

  function (Type, Arr, Obj, Styles, Id, Merger, Fun, Attr, Class, Element, Insert, InsertAll) {
    var helpStyle = Styles.resolve('aria-help');
    var helpVisibleStyle = Styles.resolve('aria-help-visible');

    var roleDocument = function (element) {
      Attr.set(element, 'role', 'document');
    };

    var presentation = function (element) {
    // https://www.w3.org/TR/wai-aria/roles#presentation
      Attr.set(element, 'role', 'presentation');
    };

    var editor = function (container, editor, label, ariaHelp, showHelpHint) {
      // Set role=region: https://www.w3.org/TR/wai-aria/roles#region
      // on editor for better user navigation modes, as it is mostly text content.
      // Better than role=application which constrains the reader navigation
      // - https://www.w3.org/TR/wai-aria/roles#application
      Attr.setAll(container, {
        'role': 'region',
        'aria-label': label
      });

      ariaHelp.each(function (helpText) {
        var aria = Element.fromTag('span');
        presentation(aria);
        Insert.append(aria, Element.fromText(helpText));
        var labelId = Id.generate('ephox-aria');
        Attr.set(aria, 'id', labelId);
        describedBy(editor, labelId);
        Class.add(aria, helpStyle);
        if (showHelpHint === true) Class.add(aria, helpVisibleStyle);
        Insert.append(container, aria);
      });

      // content attributes - surprisingly helps in both classic and inline
      var attrs = {
        'aria-multiline': 'true',
        'aria-label': label,
        title: label
      };

      Attr.setAll(editor, attrs);

      var destroy = function () {
        var removeFromEditor = Fun.curry(Attr.remove, editor);
        Arr.each(Obj.keys(attrs), removeFromEditor);
        removeFromEditor('aria-describedby');
      };

      return {
        destroy: destroy
      };
    };

    // Set the role 'group'
    var group = function (element) {
      Attr.set(element, 'role', 'group');
    };

    // Sets the role 'group', with a label
    var toolbar = function (element, label) {
      Attr.setAll(element, {
        'role': 'group',
        'aria-label': label
      });
    };

    var menu = function (element, label) {
      Attr.setAll(element, {
        'aria-label': label,
        'role': 'menu'
      });
    };

    var textButton = function (element, contentElement) {
      // Add 'button' roleto a pastry button, and 'presentation' role
      // to the contentElement that contains the button text.
      Attr.set(element, 'role', 'button');
      presentation(contentElement);
    };

    // Set the role 'button'
    var toolbarButton = function (element, label, hasPopup, isToggle) {
      Attr.setAll(element, {
        'role': 'button',
        'aria-label': label,
        'aria-haspopup': '' + hasPopup
      });
      if (isToggle) Attr.set(element, 'aria-pressed', 'false');
      if (hasPopup) Attr.set(element, 'aria-expanded', 'false');
    };

    // Set the role 'toolbar' and aria-label if provided
    var toolbarGroup = function (element, label) {
      // TODO: duplicated from 'ephox.polish.alien.Query', consolidate isEmpty();
      var isEmpty = function (val) {
        // TODO: Move to compass Arr and violin Strings
        return (val === null) || (val === undefined) || (val === '') || (Type.isArray(val) && val.length === 0);
      };
      // End TODO

      Attr.set(element, 'role', 'toolbar');

      // customer groups may have empty label, don't use it
      if (!isEmpty(label)) {
        Attr.set(element, 'aria-label', label);
      }
    };

    var menuItem = function (element, label, hasPopup) {
      var labelTxt = label.map(function (txt) {
        return { 'aria-label': txt };
      }).getOr({});

      Attr.setAll(element, Merger.merge(labelTxt, {
        'role': 'menuitem',
        'aria-haspopup': hasPopup.getOr(false)
      }));
    };

    var menuItemCheckbox = function (element) {
      Attr.setAll(element, {
        'role': 'menuitemcheckbox',
        'aria-checked': false
      });
    };

    var checkbox = function (element, label) {
      Attr.setAll(element, {
        'role': 'checkbox',
        'aria-label': label,
        'aria-checked': false
      });
    };

    var dialog = function (element, label) {
      Attr.setAll(element, {
        'role': 'dialog',
        'aria-label': label
      });
    };

    var button = function (element, label) {
      Attr.setAll(element, {
        'aria-label': label,
        'role': 'button'
      });
    };

    // return a container object with methods {element, field} containing an html field and label
    var labelledField = function (field, name, labelText) {
      var container = Element.fromTag('div');
      presentation(container);
      var id = name + Id.generate('');
      var label = Element.fromHtml('' + labelText + '');
      Attr.set(label, 'for', id);
      Attr.set(field, 'id', id);
      InsertAll.append(container, [ label, field ]);

      return {
        element: Fun.constant(container),
        field:   Fun.constant(field)
      };
    };

    var textarea = function (element) {
      Attr.setAll(element, {
        'aria-multiline': 'true',
        'role': 'textbox'
      });
    };

    var widget = function (element) {
      Attr.set(element, 'role', 'widget');
    };

    var listBox = function (element) {
      Attr.set(element, 'role', 'listbox');
    };

    var tabList = function (element) {
      Attr.set(element, 'role', 'tablist');
    };

    var tabButton = function (element, label) {
      Attr.setAll(element, {
        'aria-label': label,
        'role': 'tab'
      });
    };

    var tabPanel = function (element) {
      Attr.setAll(element, {
        'role': 'tabpanel'
      });
    };

    var linkTabToPanel = function (tab, panel) {
      var id = Id.generate('ephox-aria');
      Attr.set(panel, 'id', id);
      Attr.setAll(tab, {
        'aria-controls': id
      });
    };

    var describedBy = function (element, id) {
      Attr.set(element, 'aria-describedby', id);
    };

    var labelledBy = function (element, id) {
      Attr.set(element, 'aria-labelledby', id);
    };

    var live = function (element, id, _priority) {
      var priority = _priority ? _priority : 'polite';
      Attr.setAll(element, {
        'aria-live': priority,
        'id': id
      });
    };

    var controls = function (element, id) {
      Attr.set(element, 'aria-controls', id);
    };

    var required = function (element) {
      Attr.set(element, 'aria-required', 'true');
    };

    // TODO: Implement form ARIA support
    // var form = function (element, label) {
    //   throw 'Form ARIA support not implemented yet.';
    // };

    var label = function (element, label) {
      Attr.set(element, 'aria-label', label);
    };

    var option = function (element) {
      Attr.set(element, 'role', 'option');
    };

    // TODO: Implement link ARIA support
    // var link = function (element) {
    //   throw 'Link ARIA support not implemented yet.';
    // };

    // TODO: Implement other ARIA support
    // var other = function () {
    //   throw 'Other ARIA support not implemented yet.';
    // };

    var hidden = function (element, status) {
      // Note: aria-hidden=true says this element and all of its descendents are not percievable
      // https://www.w3.org/TR/wai-aria/states_and_properties#aria-hidden
      if (status) {
        Attr.set(element, 'aria-hidden', status);
      } else {
        Attr.remove(element, 'aria-hidden'); // same as setting aria-hidden:false
      }
    };

    return {
      document: roleDocument,
      presentation: presentation,
      controls: controls,
      editor: editor,
      group: group,
      toolbar: toolbar,
      toolbarGroup: toolbarGroup,
      toolbarButton: toolbarButton,
      textButton: textButton,
      menu: menu,
      menuItem: menuItem,
      menuItemCheckbox: menuItemCheckbox,
      checkbox: checkbox,
      dialog: dialog,
      button: button,
      labelledField: labelledField,
      textarea: textarea,
      label: label,
      widget: widget,
      option: option,
      listBox: listBox,
      live: live,
      tabList: tabList,
      tabButton: tabButton,
      tabPanel: tabPanel,
      linkTabToPanel: linkTabToPanel,
      describedBy: describedBy,
      labelledBy: labelledBy,
      required: required,
      hidden: hidden
    };
  }
);<commit_msg>TBIO-4293: add aria invalid for the font stepper<commit_after>define(
  'ephox.echo.api.AriaRegister',

  [
    'ephox.classify.Type',
    'ephox.compass.Arr',
    'ephox.compass.Obj',
    'ephox.echo.api.Styles',
    'ephox.epithet.Id',
    'ephox.highway.Merger',
    'ephox.peanut.Fun',
    'ephox.sugar.api.Attr',
    'ephox.sugar.api.Class',
    'ephox.sugar.api.Element',
    'ephox.sugar.api.Insert',
    'ephox.sugar.api.InsertAll'
  ],

  function (Type, Arr, Obj, Styles, Id, Merger, Fun, Attr, Class, Element, Insert, InsertAll) {
    var helpStyle = Styles.resolve('aria-help');
    var helpVisibleStyle = Styles.resolve('aria-help-visible');

    var roleDocument = function (element) {
      Attr.set(element, 'role', 'document');
    };

    var presentation = function (element) {
    // https://www.w3.org/TR/wai-aria/roles#presentation
      Attr.set(element, 'role', 'presentation');
    };

    var editor = function (container, editor, label, ariaHelp, showHelpHint) {
      // Set role=region: https://www.w3.org/TR/wai-aria/roles#region
      // on editor for better user navigation modes, as it is mostly text content.
      // Better than role=application which constrains the reader navigation
      // - https://www.w3.org/TR/wai-aria/roles#application
      Attr.setAll(container, {
        'role': 'region',
        'aria-label': label
      });

      ariaHelp.each(function (helpText) {
        var aria = Element.fromTag('span');
        presentation(aria);
        Insert.append(aria, Element.fromText(helpText));
        var labelId = Id.generate('ephox-aria');
        Attr.set(aria, 'id', labelId);
        describedBy(editor, labelId);
        Class.add(aria, helpStyle);
        if (showHelpHint === true) Class.add(aria, helpVisibleStyle);
        Insert.append(container, aria);
      });

      // content attributes - surprisingly helps in both classic and inline
      var attrs = {
        'aria-multiline': 'true',
        'aria-label': label,
        title: label
      };

      Attr.setAll(editor, attrs);

      var destroy = function () {
        var removeFromEditor = Fun.curry(Attr.remove, editor);
        Arr.each(Obj.keys(attrs), removeFromEditor);
        removeFromEditor('aria-describedby');
      };

      return {
        destroy: destroy
      };
    };

    // Set the role 'group'
    var group = function (element) {
      Attr.set(element, 'role', 'group');
    };

    // Sets the role 'group', with a label
    var toolbar = function (element, label) {
      Attr.setAll(element, {
        'role': 'group',
        'aria-label': label
      });
    };

    var menu = function (element, label) {
      Attr.setAll(element, {
        'aria-label': label,
        'role': 'menu'
      });
    };

    var textButton = function (element, contentElement) {
      // Add 'button' roleto a pastry button, and 'presentation' role
      // to the contentElement that contains the button text.
      Attr.set(element, 'role', 'button');
      presentation(contentElement);
    };

    // Set the role 'button'
    var toolbarButton = function (element, label, hasPopup, isToggle) {
      Attr.setAll(element, {
        'role': 'button',
        'aria-label': label,
        'aria-haspopup': '' + hasPopup
      });
      if (isToggle) Attr.set(element, 'aria-pressed', 'false');
      if (hasPopup) Attr.set(element, 'aria-expanded', 'false');
    };

    // Set the role 'toolbar' and aria-label if provided
    var toolbarGroup = function (element, label) {
      // TODO: duplicated from 'ephox.polish.alien.Query', consolidate isEmpty();
      var isEmpty = function (val) {
        // TODO: Move to compass Arr and violin Strings
        return (val === null) || (val === undefined) || (val === '') || (Type.isArray(val) && val.length === 0);
      };
      // End TODO

      Attr.set(element, 'role', 'toolbar');

      // customer groups may have empty label, don't use it
      if (!isEmpty(label)) {
        Attr.set(element, 'aria-label', label);
      }
    };

    var menuItem = function (element, label, hasPopup) {
      var labelTxt = label.map(function (txt) {
        return { 'aria-label': txt };
      }).getOr({});

      Attr.setAll(element, Merger.merge(labelTxt, {
        'role': 'menuitem',
        'aria-haspopup': hasPopup.getOr(false)
      }));
    };

    var menuItemCheckbox = function (element) {
      Attr.setAll(element, {
        'role': 'menuitemcheckbox',
        'aria-checked': false
      });
    };

    var checkbox = function (element, label) {
      Attr.setAll(element, {
        'role': 'checkbox',
        'aria-label': label,
        'aria-checked': false
      });
    };

    var dialog = function (element, label) {
      Attr.setAll(element, {
        'role': 'dialog',
        'aria-label': label
      });
    };

    var button = function (element, label) {
      Attr.setAll(element, {
        'aria-label': label,
        'role': 'button'
      });
    };

    // return a container object with methods {element, field} containing an html field and label
    var labelledField = function (field, name, labelText) {
      var container = Element.fromTag('div');
      presentation(container);
      var id = name + Id.generate('');
      var label = Element.fromHtml('' + labelText + '');
      Attr.set(label, 'for', id);
      Attr.set(field, 'id', id);
      InsertAll.append(container, [ label, field ]);

      return {
        element: Fun.constant(container),
        field:   Fun.constant(field)
      };
    };

    var textarea = function (element) {
      Attr.setAll(element, {
        'aria-multiline': 'true',
        'role': 'textbox'
      });
    };

    var widget = function (element) {
      Attr.set(element, 'role', 'widget');
    };

    var listBox = function (element) {
      Attr.set(element, 'role', 'listbox');
    };

    var tabList = function (element) {
      Attr.set(element, 'role', 'tablist');
    };

    var tabButton = function (element, label) {
      Attr.setAll(element, {
        'aria-label': label,
        'role': 'tab'
      });
    };

    var tabPanel = function (element) {
      Attr.setAll(element, {
        'role': 'tabpanel'
      });
    };

    var linkTabToPanel = function (tab, panel) {
      var id = Id.generate('ephox-aria');
      Attr.set(panel, 'id', id);
      Attr.setAll(tab, {
        'aria-controls': id
      });
    };

    var describedBy = function (element, id) {
      Attr.set(element, 'aria-describedby', id);
    };

    var labelledBy = function (element, id) {
      Attr.set(element, 'aria-labelledby', id);
    };

    var live = function (element, id, _priority) {
      var priority = _priority ? _priority : 'polite';
      Attr.setAll(element, {
        'aria-live': priority,
        'id': id
      });
    };

    var controls = function (element, id) {
      Attr.set(element, 'aria-controls', id);
    };

    var required = function (element) {
      Attr.set(element, 'aria-required', 'true');
    };

    // TODO: Implement form ARIA support
    // var form = function (element, label) {
    //   throw 'Form ARIA support not implemented yet.';
    // };

    var label = function (element, label) {
      Attr.set(element, 'aria-label', label);
    };

    var option = function (element) {
      Attr.set(element, 'role', 'option');
    };

    // TODO: Implement link ARIA support
    // var link = function (element) {
    //   throw 'Link ARIA support not implemented yet.';
    // };

    // TODO: Implement other ARIA support
    // var other = function () {
    //   throw 'Other ARIA support not implemented yet.';
    // };

    var hidden = function (element, status) {
      // Note: aria-hidden=true says this element and all of its descendents are not percievable
      // https://www.w3.org/TR/wai-aria/states_and_properties#aria-hidden
      if (status) {
        Attr.set(element, 'aria-hidden', status);
      } else {
        Attr.remove(element, 'aria-hidden'); // same as setting aria-hidden:false
      }
    };

    var invalid = function (element, status) {
      if (status === true) {
        Attr.set(element, 'aria-invalid', 'true');
      } else {
        Attr.remove(element, 'aria-invalid');
      }
    };

    return {
      document: roleDocument,
      presentation: presentation,
      controls: controls,
      editor: editor,
      group: group,
      toolbar: toolbar,
      toolbarGroup: toolbarGroup,
      toolbarButton: toolbarButton,
      textButton: textButton,
      menu: menu,
      menuItem: menuItem,
      menuItemCheckbox: menuItemCheckbox,
      checkbox: checkbox,
      dialog: dialog,
      button: button,
      labelledField: labelledField,
      textarea: textarea,
      label: label,
      widget: widget,
      option: option,
      listBox: listBox,
      live: live,
      tabList: tabList,
      tabButton: tabButton,
      tabPanel: tabPanel,
      linkTabToPanel: linkTabToPanel,
      describedBy: describedBy,
      labelledBy: labelledBy,
      required: required,
      hidden: hidden,
      invalid: invalid
    };
  }
);<|endoftext|>


<commit_before>#!/usr/bin/env node
const program = require('commander');
const path = require('path');
const Config = require('../lib/config');
const Codecept = require('../lib/codecept');
const print = require('../lib/output');
const fileExists = require('../lib/utils').fileExists;
const fs = require('fs');

program.command('init [path]')
  .description('Creates dummy config in current dir or [path]')
  .action(require('../lib/command/init'));

program.command('shell [path]')
  .alias('sh')
  .description('Interactive shell')
  .option('--verbose', 'output internal logging information')
  .option('--profile [value]', 'configuration profile to be used')
  .action(require('../lib/command/interactive'));

program.command('list [path]')
  .alias('l')
  .description('List all actions for I.')
  .action(require('../lib/command/list'));

program.command('def [path]')
  .description('List all actions for I.')
  .action(require('../lib/command/definitions'));

program.command('generate:test [path]')
  .alias('gt')
  .description('Generates an empty test')
  .action(require('../lib/command/generate').test);

program.command('generate:pageobject [path]')
  .alias('gpo')
  .description('Generates an empty page object')
  .action(require('../lib/command/generate').pageObject);

program.command('generate:object [path]')
  .alias('go')
  .option('--type, -t [kind]', 'type of object to be created')
  .description('Generates an empty support object (page/step/fragment)')
  .action(require('../lib/command/generate').pageObject);

program.command('generate:helper [path]')
  .alias('gh')
  .description('Generates a new helper')
  .action(require('../lib/command/generate').helper);

program.command('run [test]')
  .description('Executes tests')

  // codecept-only options
  .option('--steps', 'show step-by-step execution')
  .option('--debug', 'output additional information')
  .option('--verbose', 'output internal logging information')
  .option('-o, --override [value]', 'override current config options')
  .option('--profile [value]', 'configuration profile to be used')
  .option('-c, --config [file]', 'configuration file to be used')

  // mocha options
  .option('--colors', 'force enabling of colors')
  .option('--no-colors', 'force disabling of colors')
  .option('-G, --growl', 'enable growl notification support')
  .option('-O, --reporter-options <k=v,k2=v2,...>', 'reporter-specific options')
  .option('-R, --reporter <name>', 'specify the reporter to use')
  .option('-S, --sort', 'sort test files')
  .option('-b, --bail', 'bail after first test failure')
  .option('-d, --debug', "enable node's debugger, synonym for node --debug")
  .option('-g, --grep <pattern>', 'only run tests matching <pattern>')
  .option('-f, --fgrep <string>', 'only run tests containing <string>')
  .option('-i, --invert', 'inverts --grep and --fgrep matches')
  .option('--full-trace', 'display the full stack trace')
  .option('--compilers <ext>:<module>,...', 'use the given module(s) to compile files')
  .option('--debug-brk', "enable node's debugger breaking on the first line")
  .option('--inline-diffs', 'display actual/expected differences inline within each string')
  .option('--no-exit', 'require a clean shutdown of the event loop: mocha will not call process.exit')
  .option('--recursive', 'include sub directories')
  .option('--trace', 'trace function calls')
  .option('--child <string>', 'option for child processes')

  .action(require('../lib/command/run'));

program.command('run-multiple [suites...]')
  .description('Executes tests multiple')
  .option('-c, --config [file]', 'configuration file to be used')
  .option('--all', 'run all suites')
  .option('-g, --grep <pattern>', 'only run tests matching <pattern>')
  .option('-f, --fgrep <string>', 'only run tests containing <string>')
  .option('--steps', 'show step-by-step execution')
  .option('--verbose', 'output internal logging information')
  .option('--debug', 'output additional information')
  .option('-o, --override [value]', 'override current config options')
  .option('-O, --reporter-options <k=v,k2=v2,...>', 'reporter-specific options')
  .option('-R, --reporter <name>', 'specify the reporter to use')
  .option('--recursive', 'include sub directories')

  .action(require('../lib/command/run-multiple'));

if (process.argv.length <= 2) {
  console.log(`CodeceptJS v${Codecept.version()}`);
  program.outputHelp();
}
program.parse(process.argv);
<commit_msg>added --profile to run-multiple (#849)<commit_after>#!/usr/bin/env node
const program = require('commander');
const path = require('path');
const Config = require('../lib/config');
const Codecept = require('../lib/codecept');
const print = require('../lib/output');
const fileExists = require('../lib/utils').fileExists;
const fs = require('fs');

program.command('init [path]')
  .description('Creates dummy config in current dir or [path]')
  .action(require('../lib/command/init'));

program.command('shell [path]')
  .alias('sh')
  .description('Interactive shell')
  .option('--verbose', 'output internal logging information')
  .option('--profile [value]', 'configuration profile to be used')
  .action(require('../lib/command/interactive'));

program.command('list [path]')
  .alias('l')
  .description('List all actions for I.')
  .action(require('../lib/command/list'));

program.command('def [path]')
  .description('List all actions for I.')
  .action(require('../lib/command/definitions'));

program.command('generate:test [path]')
  .alias('gt')
  .description('Generates an empty test')
  .action(require('../lib/command/generate').test);

program.command('generate:pageobject [path]')
  .alias('gpo')
  .description('Generates an empty page object')
  .action(require('../lib/command/generate').pageObject);

program.command('generate:object [path]')
  .alias('go')
  .option('--type, -t [kind]', 'type of object to be created')
  .description('Generates an empty support object (page/step/fragment)')
  .action(require('../lib/command/generate').pageObject);

program.command('generate:helper [path]')
  .alias('gh')
  .description('Generates a new helper')
  .action(require('../lib/command/generate').helper);

program.command('run [test]')
  .description('Executes tests')

  // codecept-only options
  .option('--steps', 'show step-by-step execution')
  .option('--debug', 'output additional information')
  .option('--verbose', 'output internal logging information')
  .option('-o, --override [value]', 'override current config options')
  .option('--profile [value]', 'configuration profile to be used')
  .option('-c, --config [file]', 'configuration file to be used')

  // mocha options
  .option('--colors', 'force enabling of colors')
  .option('--no-colors', 'force disabling of colors')
  .option('-G, --growl', 'enable growl notification support')
  .option('-O, --reporter-options <k=v,k2=v2,...>', 'reporter-specific options')
  .option('-R, --reporter <name>', 'specify the reporter to use')
  .option('-S, --sort', 'sort test files')
  .option('-b, --bail', 'bail after first test failure')
  .option('-d, --debug', "enable node's debugger, synonym for node --debug")
  .option('-g, --grep <pattern>', 'only run tests matching <pattern>')
  .option('-f, --fgrep <string>', 'only run tests containing <string>')
  .option('-i, --invert', 'inverts --grep and --fgrep matches')
  .option('--full-trace', 'display the full stack trace')
  .option('--compilers <ext>:<module>,...', 'use the given module(s) to compile files')
  .option('--debug-brk', "enable node's debugger breaking on the first line")
  .option('--inline-diffs', 'display actual/expected differences inline within each string')
  .option('--no-exit', 'require a clean shutdown of the event loop: mocha will not call process.exit')
  .option('--recursive', 'include sub directories')
  .option('--trace', 'trace function calls')
  .option('--child <string>', 'option for child processes')

  .action(require('../lib/command/run'));

program.command('run-multiple [suites...]')
  .description('Executes tests multiple')
  .option('-c, --config [file]', 'configuration file to be used')
  .option('--profile [value]', 'configuration profile to be used')
  .option('--all', 'run all suites')
  .option('-g, --grep <pattern>', 'only run tests matching <pattern>')
  .option('-f, --fgrep <string>', 'only run tests containing <string>')
  .option('--steps', 'show step-by-step execution')
  .option('--verbose', 'output internal logging information')
  .option('--debug', 'output additional information')
  .option('-o, --override [value]', 'override current config options')
  .option('-O, --reporter-options <k=v,k2=v2,...>', 'reporter-specific options')
  .option('-R, --reporter <name>', 'specify the reporter to use')
  .option('--recursive', 'include sub directories')

  .action(require('../lib/command/run-multiple'));

if (process.argv.length <= 2) {
  console.log(`CodeceptJS v${Codecept.version()}`);
  program.outputHelp();
}
program.parse(process.argv);
<|endoftext|>


<commit_before>// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt

cur_frm.add_fetch("customer", "customer_group", "customer_group" );
cur_frm.add_fetch("supplier", "supplier_type", "supplier_type" );

frappe.ui.form.on("Tax Rule", "tax_type", function(frm) {
	frm.toggle_reqd("sales_tax_template", frm.doc.tax_type=="Sales");
	frm.toggle_reqd("purchase_tax_template", frm.doc.tax_type=="Purchase");
})

frappe.ui.form.on("Tax Rule", "onload", function(frm) {
	if(frm.doc.__islocal) {
		frm.set_value("use_for_shopping_cart", 1);
	}
})

frappe.ui.form.on("Tax Rule", "refresh", function(frm) {
	frappe.ui.form.trigger("Tax Rule", "tax_type");
})

frappe.ui.form.on("Tax Rule", "customer", function(frm) {
	if(frm.doc.customer) {
		frappe.call({
			method:"erpnext.accounts.doctype.tax_rule.tax_rule.get_party_details",
			args: {
				"party": frm.doc.customer,
				"party_type": "customer"
			},
			callback: function(r) {
				if(!r.exc) {
					$.each(r.message, function(k, v) {
						frm.set_value(k, v);
					});
				}
			}
		});
	}
});

frappe.ui.form.on("Tax Rule", "supplier", function(frm) {
	frappe.call({
		method:"erpnext.accounts.doctype.tax_rule.tax_rule.get_party_details",
		args: {
			"party": frm.doc.supplier,
			"party_type": "supplier"
		},
		callback: function(r) {
			if(!r.exc) {
				$.each(r.message, function(k, v) {
					frm.set_value(k, v);
				});
			}
		}
	});
});
<commit_msg>[fix] check if supplier value exists (#13616)<commit_after>// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt

cur_frm.add_fetch("customer", "customer_group", "customer_group" );
cur_frm.add_fetch("supplier", "supplier_type", "supplier_type" );

frappe.ui.form.on("Tax Rule", "tax_type", function(frm) {
	frm.toggle_reqd("sales_tax_template", frm.doc.tax_type=="Sales");
	frm.toggle_reqd("purchase_tax_template", frm.doc.tax_type=="Purchase");
})

frappe.ui.form.on("Tax Rule", "onload", function(frm) {
	if(frm.doc.__islocal) {
		frm.set_value("use_for_shopping_cart", 1);
	}
})

frappe.ui.form.on("Tax Rule", "refresh", function(frm) {
	frappe.ui.form.trigger("Tax Rule", "tax_type");
})

frappe.ui.form.on("Tax Rule", "customer", function(frm) {
	if(frm.doc.customer) {
		frappe.call({
			method:"erpnext.accounts.doctype.tax_rule.tax_rule.get_party_details",
			args: {
				"party": frm.doc.customer,
				"party_type": "customer"
			},
			callback: function(r) {
				if(!r.exc) {
					$.each(r.message, function(k, v) {
						frm.set_value(k, v);
					});
				}
			}
		});
	}
});

frappe.ui.form.on("Tax Rule", "supplier", function(frm) {
	if(frm.doc.supplier) {
		frappe.call({
			method:"erpnext.accounts.doctype.tax_rule.tax_rule.get_party_details",
			args: {
				"party": frm.doc.supplier,
				"party_type": "supplier"
			},
			callback: function(r) {
				if(!r.exc) {
					$.each(r.message, function(k, v) {
						frm.set_value(k, v);
					});
				}
			}
		});
	}
});
<|endoftext|>


<commit_before>const _ = require('underscore');
const md5 = require('md5');
const { extend } = require('underscore');
const Promise = require('./promise');
const AV = require('./av');
const { getSessionToken, ajax } = require('./utils');

// 计算 X-LC-Sign 的签名方法
const sign = (key, isMasterKey) => {
  const now = new Date().getTime();
  const signature = md5(now + key);
  if (isMasterKey) {
    return `${signature},${now},master`;
  }
  return `${signature},${now}`;
};

const setAppKey = (headers, signKey) => {
  if (signKey) {
    headers['X-LC-Sign'] = sign(AV.applicationKey);
  } else {
    headers['X-LC-Key'] = AV.applicationKey;
  }
};

const setHeaders = (authOptions = {}, signKey) => {
  const headers = {
    'X-LC-Id': AV.applicationId,
    'Content-Type': 'application/json;charset=UTF-8',
  };
  let useMasterKey = false;
  if (typeof authOptions.useMasterKey === 'boolean') {
    useMasterKey = authOptions.useMasterKey;
  } else if (typeof AV._config.useMasterKey === 'boolean') {
    useMasterKey = AV._config.useMasterKey;
  }
  if (useMasterKey) {
    if (AV.masterKey) {
      if (signKey) {
        headers['X-LC-Sign'] = sign(AV.masterKey, true);
      } else {
        headers['X-LC-Key'] = `${AV.masterKey},master`;
      }
    } else {
      console.warn('masterKey is not set, fall back to use appKey');
      setAppKey(headers, signKey);
    }
  } else {
    setAppKey(headers, signKey);
  }
  if (AV.hookKey) {
    headers['X-LC-Hook-Key'] = AV.hookKey;
  }
  if (AV._config.production !== null) {
    headers['X-LC-Prod'] = String(AV._config.production);
  }
  headers[!process.env.CLIENT_PLATFORM ? 'User-Agent' : 'X-LC-UA'] =
    AV._sharedConfig.userAgent;

  return Promise.resolve().then(() => {
    // Pass the session token
    const sessionToken = getSessionToken(authOptions);
    if (sessionToken) {
      headers['X-LC-Session'] = sessionToken;
    } else if (!AV._config.disableCurrentUser) {
      return AV.User.currentAsync().then(currentUser => {
        if (currentUser && currentUser._sessionToken) {
          headers['X-LC-Session'] = currentUser._sessionToken;
        }
        return headers;
      });
    }
    return headers;
  });
};

const createApiUrl = ({
  service = 'api',
  version = '1.1',
  path,
  // query, // don't care
  // method, // don't care
  // data, // don't care
}) => {
  let apiURL = AV._config.serverURLs[service];

  if (!apiURL) throw new Error(`undefined server URL for ${service}`);

  if (apiURL.charAt(apiURL.length - 1) !== '/') {
    apiURL += '/';
  }
  apiURL += version;
  if (path) {
    apiURL += path;
  }

  return apiURL;
};

/**
 * Low level REST API client. Call REST endpoints with authorization headers.
 * @function AV.request
 * @since 3.0.0
 * @param {Object} options
 * @param {String} options.method HTTP method
 * @param {String} options.path endpoint path, e.g. `/classes/Test/55759577e4b029ae6015ac20`
 * @param {Object} [options.query] query string dict
 * @param {Object} [options.data] HTTP body
 * @param {AuthOptions} [options.authOptions]
 * @param {String} [options.service = 'api']
 * @param {String} [options.version = '1.1']
 */
const request = ({
  service,
  version,
  method,
  path,
  query,
  data = {},
  authOptions,
  signKey = true,
}) => {
  if (!(AV.applicationId && (AV.applicationKey || AV.masterKey))) {
    throw new Error('Not initialized');
  }
  AV._appRouter.refresh();
  const { requestTimeout: timeout } = AV._config;
  const url = createApiUrl({ service, path, version });
  return setHeaders(authOptions, signKey).then(headers =>
    ajax({ method, url, query, data, headers, timeout }).catch(error => {
      let errorJSON = {
        code: error.code || -1,
        error: error.message || error.responseText,
      };
      if (error.response && error.response.code) {
        errorJSON = error.response;
      } else if (error.responseText) {
        try {
          errorJSON = JSON.parse(error.responseText);
        } catch (e) {
          // If we fail to parse the error text, that's okay.
        }
      }
      errorJSON.rawMessage = errorJSON.rawMessage || errorJSON.error;
      if (!AV._sharedConfig.keepErrorRawMessage) {
        errorJSON.error += ` [${error.statusCode || 'N/A'} ${method} ${url}]`;
      }
      // Transform the error into an instance of AVError by trying to parse
      // the error string as JSON.
      const err = new Error(errorJSON.error);
      delete errorJSON.error;
      throw _.extend(err, errorJSON);
    })
  );
};

// lagecy request
const _request = (
  route,
  className,
  objectId,
  method,
  data = {},
  authOptions,
  query
) => {
  let path = '';
  if (route) path += `/${route}`;
  if (className) path += `/${className}`;
  if (objectId) path += `/${objectId}`;
  // for migeration
  if (data && data._fetchWhenSave)
    throw new Error('_fetchWhenSave should be in the query');
  if (data && data._where) throw new Error('_where should be in the query');
  if (method && method.toLowerCase() === 'get') {
    query = extend({}, query, data);
    data = null;
  }
  return request({
    method,
    path,
    query,
    data,
    authOptions,
  });
};

AV.request = request;

module.exports = {
  _request,
  request,
};
<commit_msg>fix: keep the undefined `data` for AV.request<commit_after>const _ = require('underscore');
const md5 = require('md5');
const { extend } = require('underscore');
const Promise = require('./promise');
const AV = require('./av');
const { getSessionToken, ajax } = require('./utils');

// 计算 X-LC-Sign 的签名方法
const sign = (key, isMasterKey) => {
  const now = new Date().getTime();
  const signature = md5(now + key);
  if (isMasterKey) {
    return `${signature},${now},master`;
  }
  return `${signature},${now}`;
};

const setAppKey = (headers, signKey) => {
  if (signKey) {
    headers['X-LC-Sign'] = sign(AV.applicationKey);
  } else {
    headers['X-LC-Key'] = AV.applicationKey;
  }
};

const setHeaders = (authOptions = {}, signKey) => {
  const headers = {
    'X-LC-Id': AV.applicationId,
    'Content-Type': 'application/json;charset=UTF-8',
  };
  let useMasterKey = false;
  if (typeof authOptions.useMasterKey === 'boolean') {
    useMasterKey = authOptions.useMasterKey;
  } else if (typeof AV._config.useMasterKey === 'boolean') {
    useMasterKey = AV._config.useMasterKey;
  }
  if (useMasterKey) {
    if (AV.masterKey) {
      if (signKey) {
        headers['X-LC-Sign'] = sign(AV.masterKey, true);
      } else {
        headers['X-LC-Key'] = `${AV.masterKey},master`;
      }
    } else {
      console.warn('masterKey is not set, fall back to use appKey');
      setAppKey(headers, signKey);
    }
  } else {
    setAppKey(headers, signKey);
  }
  if (AV.hookKey) {
    headers['X-LC-Hook-Key'] = AV.hookKey;
  }
  if (AV._config.production !== null) {
    headers['X-LC-Prod'] = String(AV._config.production);
  }
  headers[!process.env.CLIENT_PLATFORM ? 'User-Agent' : 'X-LC-UA'] =
    AV._sharedConfig.userAgent;

  return Promise.resolve().then(() => {
    // Pass the session token
    const sessionToken = getSessionToken(authOptions);
    if (sessionToken) {
      headers['X-LC-Session'] = sessionToken;
    } else if (!AV._config.disableCurrentUser) {
      return AV.User.currentAsync().then(currentUser => {
        if (currentUser && currentUser._sessionToken) {
          headers['X-LC-Session'] = currentUser._sessionToken;
        }
        return headers;
      });
    }
    return headers;
  });
};

const createApiUrl = ({
  service = 'api',
  version = '1.1',
  path,
  // query, // don't care
  // method, // don't care
  // data, // don't care
}) => {
  let apiURL = AV._config.serverURLs[service];

  if (!apiURL) throw new Error(`undefined server URL for ${service}`);

  if (apiURL.charAt(apiURL.length - 1) !== '/') {
    apiURL += '/';
  }
  apiURL += version;
  if (path) {
    apiURL += path;
  }

  return apiURL;
};

/**
 * Low level REST API client. Call REST endpoints with authorization headers.
 * @function AV.request
 * @since 3.0.0
 * @param {Object} options
 * @param {String} options.method HTTP method
 * @param {String} options.path endpoint path, e.g. `/classes/Test/55759577e4b029ae6015ac20`
 * @param {Object} [options.query] query string dict
 * @param {Object} [options.data] HTTP body
 * @param {AuthOptions} [options.authOptions]
 * @param {String} [options.service = 'api']
 * @param {String} [options.version = '1.1']
 */
const request = ({
  service,
  version,
  method,
  path,
  query,
  data,
  authOptions,
  signKey = true,
}) => {
  if (!(AV.applicationId && (AV.applicationKey || AV.masterKey))) {
    throw new Error('Not initialized');
  }
  AV._appRouter.refresh();
  const { requestTimeout: timeout } = AV._config;
  const url = createApiUrl({ service, path, version });
  return setHeaders(authOptions, signKey).then(headers =>
    ajax({ method, url, query, data, headers, timeout }).catch(error => {
      let errorJSON = {
        code: error.code || -1,
        error: error.message || error.responseText,
      };
      if (error.response && error.response.code) {
        errorJSON = error.response;
      } else if (error.responseText) {
        try {
          errorJSON = JSON.parse(error.responseText);
        } catch (e) {
          // If we fail to parse the error text, that's okay.
        }
      }
      errorJSON.rawMessage = errorJSON.rawMessage || errorJSON.error;
      if (!AV._sharedConfig.keepErrorRawMessage) {
        errorJSON.error += ` [${error.statusCode || 'N/A'} ${method} ${url}]`;
      }
      // Transform the error into an instance of AVError by trying to parse
      // the error string as JSON.
      const err = new Error(errorJSON.error);
      delete errorJSON.error;
      throw _.extend(err, errorJSON);
    })
  );
};

// lagecy request
const _request = (
  route,
  className,
  objectId,
  method,
  data,
  authOptions,
  query
) => {
  let path = '';
  if (route) path += `/${route}`;
  if (className) path += `/${className}`;
  if (objectId) path += `/${objectId}`;
  // for migeration
  if (data && data._fetchWhenSave)
    throw new Error('_fetchWhenSave should be in the query');
  if (data && data._where) throw new Error('_where should be in the query');
  if (method && method.toLowerCase() === 'get') {
    query = extend({}, query, data);
    data = null;
  }
  return request({
    method,
    path,
    query,
    data,
    authOptions,
  });
};

AV.request = request;

module.exports = {
  _request,
  request,
};
<|endoftext|>


<commit_before>var feeds = require('./feeds')
var express = require('express')
var path = require('path')
var redis = require("./redis")

var exWrap = function(res, promise) {
	promise.catch(function(err) {
		console.log(err)
		return res.send(500)
	})
}

var server = function(db) {
	var app = express()
	var servDir = path.join(__dirname, '../../../web/build')

	app.use(function(req, res, next) {
		console.log("%s - %s", req.method, req.url)

		return next()
	})

	app.use(express.json())
	app.use(express.compress())

	app.post('/api/feed/add', function(req, res) {
		var url = req.body['url']
		if (!url) {
			return res.send(400, 'Error')
		}

		exWrap(feeds.add(db, url).then(function() {
			res.send(200)
		}))
	})

	app.get('/api/channels', function(req, res) {
		exWrap(res, db.getChannels().then(function(result) {
			var chans = result.map(function(chan) {
				chan.id = chan.channel_id
				delete chan.channel_id

				return chan
			})

			return res.json(200, chans)
		}))
	})

  // TODO: Replace this with DELETE
 //  app.post('/api/feed/:id', function(req, res) {
	// var id = req.params['id']

	// res.send(id)
 //  })

	// TODO: Move this to Redis!
	var feedCache = {}
	app.get('/api/feed/:id', function(req, res) {
		var id = req.params.id
		if(!id) {
			return res.send(400)
		}

		var modSince = req.get("If-Modified-Since")

		redis.getFeedLatest(id).then(function(cached) {

			if(cached) {
				if(modSince >= cached) {
					return res.send(304)
				}
			}
		})

		exWrap(res, db.getFeed(id).then(function(feeds) {
			// todo: Only send feeds which are pubed >= If-Modified-Since
			var last

			feeds = feeds.map(function(feed) {
				feed.id = feed.item_id

				if(!last || feed.published > last) {
					last = feed.published
				}

				delete feed.item_id
				delete feed.hash

				return feed
			})

			if(!last) {
				last = modSince
			}

			res.set({
			 	"Last-Modified": last,
			 	"Cache-Control": "public, max-age=300"
			})

			redis.setFeedLatest(id, last)
			res.send(200, feeds)
		}))
	})

	app.get('/api/feed/:id/read', function(req, res) {
		var id = req.params.id
		if(!id) {
			return res.send(400)
		}

		exWrap(res, db.markRead(id).then(db.getFeedItem(id).then(function(items) {
			var item = items[0]
			item.id = item.item_id

			delete item.hash
			delete item.item_id

			res.json(200, item)
		})))
	})

	app.get('/api/feed/unread/:id', function(req, res) {
		var id = req.params.id
	})

	app.use(function(req, res, next) {
		return res.send(404)
	})

	var port = 3000
	app.listen(port)

	console.log("listening on port " + port)

	return app
}

module.exports = {
	server: server
}
<commit_msg>use json instead of send<commit_after>var feeds = require('./feeds')
var express = require('express')
var path = require('path')
var redis = require("./redis")

var exWrap = function(res, promise) {
	promise.catch(function(err) {
		console.log(err)
		return res.send(500)
	})
}

var server = function(db) {
	var app = express()
	var servDir = path.join(__dirname, '../../../web/build')

	app.use(function(req, res, next) {
		console.log("%s - %s", req.method, req.url)

		return next()
	})

	app.use(express.json())
	app.use(express.compress())

	app.post('/api/feed/add', function(req, res) {
		var url = req.body['url']
		if (!url) {
			return res.send(400, 'Error')
		}

		exWrap(feeds.add(db, url).then(function() {
			res.send(200)
		}))
	})

	app.get('/api/channels', function(req, res) {
		exWrap(res, db.getChannels().then(function(result) {
			var chans = result.map(function(chan) {
				chan.id = chan.channel_id
				delete chan.channel_id

				return chan
			})

			return res.json(200, chans)
		}))
	})

  // TODO: Replace this with DELETE
 //  app.post('/api/feed/:id', function(req, res) {
	// var id = req.params['id']

	// res.send(id)
 //  })

	// TODO: Move this to Redis!
	var feedCache = {}
	app.get('/api/feed/:id', function(req, res) {
		var id = req.params.id
		if(!id) {
			return res.send(400)
		}

		var modSince = req.get("If-Modified-Since")

		redis.getFeedLatest(id).then(function(cached) {

			if(cached) {
				if(modSince >= cached) {
					return res.send(304)
				}
			}
		})

		exWrap(res, db.getFeed(id).then(function(feeds) {
			// todo: Only send feeds which are pubed >= If-Modified-Since
			var last

			feeds = feeds.map(function(feed) {
				feed.id = feed.item_id

				if(!last || feed.published > last) {
					last = feed.published
				}

				delete feed.item_id
				delete feed.hash

				return feed
			})

			if(!last) {
				last = modSince
			}

			res.set({
			 	"Last-Modified": last,
			 	"Cache-Control": "public, max-age=300"
			})

			redis.setFeedLatest(id, last)
			res.json(200, feeds)
		}))
	})

	app.get('/api/feed/:id/read', function(req, res) {
		var id = req.params.id
		if(!id) {
			return res.send(400)
		}

		exWrap(res, db.markRead(id).then(db.getFeedItem(id).then(function(items) {
			var item = items[0]
			item.id = item.item_id

			delete item.hash
			delete item.item_id

			res.json(200, item)
		})))
	})

	app.get('/api/feed/unread/:id', function(req, res) {
		var id = req.params.id
	})

	app.use(function(req, res, next) {
		return res.send(404)
	})

	var port = 3000
	app.listen(port)

	console.log("listening on port " + port)

	return app
}

module.exports = {
	server: server
}
<|endoftext|>


<commit_before>#!/usr/local/bin/node

var http = require('http'),
    fs = require('fs'),
    _ = require('lodash');

// TODO: allow the directory of which to service the static requests to be changed
// for PUT or POST requests, it might make sense to dynamically add and update the list
// allow file extensions options
// allow an option to read from configuration file
var getFileName = function(method, url) {
  var urlParts = _.compact(url.split('/')),
      fileName = [method.toLowerCase()];

  fileName = fileName.concat(urlParts).join('.') + '.json';
  return fileName;
};

var getResponsePath = function(fileName) {
  var indexOfResponsePath,
      responsePath,
      responseDirWithoutSlashes;

  indexOfResponsePath = process.argv.indexOf('-path');

  if (indexOfResponsePath != -1 && indexOfResponsePath <= process.argv.length - 1) {
    responseDirWithoutSlashes = process.argv[indexOfResponsePath + 1].replace(/\//g, '');
    responsePath = [process.cwd(), responseDirWithoutSlashes].join('/');
  } else {
    responsePath = './responses';
  }

  return [responsePath, fileName].join('/');
};

var server = http.createServer(function(request, response) {
  var fileName = getFileName(request.method, request.url);
  if (request.url !== '/favicon.ico') {
    fs.readFile(getResponsePath(fileName), function(err, data) {
      response.writeHead(200, {"Content-Type": "text/json"});
      response.write(data);
      response.end();
    });
  }
});

// TODO: allow the ports to be changed
server.listen('8080');
console.log('Listening to port 8080...');<commit_msg>remove trailing and leading slashes instead and added a 404 error<commit_after>#!/usr/local/bin/node

var http = require('http'),
    fs = require('fs'),
    _ = require('lodash');

// TODO: allow the directory of which to service the static requests to be changed
// for PUT or POST requests, it might make sense to dynamically add and update the list
// allow file extensions options
// allow an option to read from configuration file
var getFileName = function(method, url) {
  var urlParts = _.compact(url.split('/')),
      fileName = [method.toLowerCase()];

  fileName = fileName.concat(urlParts).join('.') + '.json';
  return fileName;
};

var getResponseDirPath = function(fileName) {
  var indexOfResponsePath,
      responsePath,
      responseDirWithoutSlashes;

  indexOfResponsePath = process.argv.indexOf('-path');

  if (indexOfResponsePath != -1 && indexOfResponsePath <= process.argv.length - 1) {
    responseDirWithoutSlashes = process.argv[indexOfResponsePath + 1].replace(/(^\/)|(\/$)/g, '');
    responsePath = [process.cwd(), responseDirWithoutSlashes].join('/');
  } else {
    responsePath = './responses';
  }

  return [responsePath, fileName].join('/');
};

var sendResponse = function(responseFilePath, response) {
  return function(exists) {
    if (exists) {
      fs.readFile(responseFilePath, function(err, data) {
        response.writeHead(200, {"Content-Type": "text/json"});
        response.write(data);
        response.end();
      });
    } else {
      response.writeHead(404);
      response.write({
        status: 404,
        message: "Not Found"
      });
      response.end();
    }
  }
};

var server = http.createServer(function(request, response) {
  var fileName = getFileName(request.method, request.url),
    responseFilePath = getResponseDirPath(fileName);
  if (request.url !== '/favicon.ico') {
    fs.exists(responseFilePath, sendResponse(responseFilePath, response));
  }
});

// TODO: allow the ports to be changed
server.listen('8080');
console.log('Listening to port 8080...');<|endoftext|>


<commit_before>Array.prototype.randomElement = function () {
    return this[Math.floor(Math.random() * this.length)]
}

function generateModel(corpus, n) {
    var ngramsCounted = {};
    for (var i = 0; i < corpus.length - n + 1; i++) {
        var ngram = corpus.substring(i, i + n);
        if (!ngramsCounted[ngram]) {
            ngramsCounted[ngram] = [];
        }
        ngramsCounted[ngram].push(corpus.charAt(i+n));

    }
    //console.log(ngramsCounted);
    return ngramsCounted;
}

function generateText(model, length, start) {
    if (!start) {
        start = Object.keys(model).randomElement();
    }
    var currentNgram = start;
    n = currentNgram.length;

    var result = currentNgram;
    for (var i = 0; i < length; i++) {
        // console.log("model:", model);
        // console.log("model[result]:", model[result]);
        currentNgram = result.substring(result.length - n)
        var possibilities = model[currentNgram];
        var next = possibilities.randomElement();
        result = result + next;
        //console.log(i, possibilities, next, "'", result, "'");
        //console.log(result);
    }

    return result;
}
<commit_msg>customization of Markov chain code<commit_after>Array.prototype.randomElement = function () {
    return this[Math.floor(Math.random() * this.length)]
}

var corpus_Banggood = "Aomway,Anet,ARILUX,ANENG,Astrolux,ALZRC,AOTDDOR,Archeer,AONIJIE,AUDEW,Alocs,ARCHON,Arsuxeo,Aputure,AMKOV,BlitzWolf,Bakeey,BULLCAPTAIN,BROPPE,BIKIGHT,Baseus,Baofeng,BrotherHobby,Broadlink,BOSI,Beelink,BSIDE,BEWELL,Bestrunner,BOYA,BOBING,Blackview,Cube,CHUWI,Charsoon,Convoy,CJMCU,Charmkpr,CURREN,CaseMe,Comfast,Celmia,Caden,CAMTOA,DJI,DANIU,DIGOO,DOOGEE,Drillpro,DYS,DT NO I,DQG,DANCINGNAIL,Eachine,EleksMaker,Emax,EKEN,ECUBEE,Ekphero,ESCAM,Excellway,Egrow,Effetool,ELEGIANT,EDUP,FlySky,FrSky,Fatshark,Foxeer,FNF,Feiyue,Feiyu Tech,Fenix,FXT,Fotga,Geekcreit,GPD,Geeetech,Gemfan,Gaoneng,GitUp,Gracila,GOPHERT,GARMIN,GUANQIN,GOLF,Hubsan,Huawei,Honana,HILDA,Hobbywing,Hawkeye,HANTEK,Hiland,HaikeLite,HOCO,IPRee,ISDT,Immersionrc,iMars,iRangeX,Inbike,IMALENT,INALIS,JJRC,JYE Tech,Jumper,JKM,JAKEMY,JARAGAR,JETBEAM,JASSY,Kingkong,KCASA,KALOAD,Klarus,KZ,Keith,KING DO WAY,KINGMAX,KUNIU,Lenovo,LeTV,Lemfo,Loskii,LUSTREON,Lumintop,LIVOLO,LuckyFine,LD,LEO,Matek,MUSTOOL,MantisTek,MACHIFIT,MOTOSPEED,Mixza,Meco,MEGIR,MASTECH,Mohoo,Mofi,M Way,Meizu,NILLKIN,NITECORE,Naturehike,NAVIFORCE,NightEye Auto Lighting,NORTH,Onda,Onyx Boox,Orange Pi,O NEWE,Orico,OCHSTIN,Onchoice,Orvibo,OHSEN,OUKITEL,Paron,PIPO,Pro sKit,PODOM,Panda,PEAKMETER,Pro biker,Pag,POFAN,Pisen,QCY,QKZ,QIPAI,Racerstar,Realacc,Runcam,Raspberry Pi,Raitool,RadioLink,REMAX,ROCKBROS,RUNDONG AUTO ACCESSORIES,ROCK,SONOFF,Suleve,Skyzone,SJcam,Syma,Soloop,Socofy,Seaknight,SKMEI,SANDA,SANWU,SINOBI,Scoyco,SEWOR,SOOCOO,SKILHUNT,SANRENMU,Sunwayman,Teclast,ThorFire,Tarot,Turbowing,TELESIN,Tenda,UMI,Ulefone,UNI T,VOYO,VIOFO,Vstarcam,Vvcare,Vention,VICTOR,Wltoys,Walkera,Water Ice Levin,Wemos,Wavlink,WINNER,Wanscam,Warsun,Wosawe,WEIDE,XIAOMI,XANES,XK,XF POWER,Y F M,YIHUA,Yani,YAZOLE,YunTeng,Yongnuo,YUEYIN,Yoobao,ZOP Power,Zeblaze,ZANLURE,ZK,ZX LED LIGHT"

function cleanCorpus(corpus) {
    corpus = corpus.toLowerCase();
    return corpus;
}

function generateModel(corpus, n) {
    var ngramsCounted = {};

    // Analyzing per name
    corpus = corpus.split(",");
    for (var i = 0; i < corpus.length; i++) {
        var thisName = corpus[i];
        // console.log(thisName);
        if (thisName.length < n) break;
        for (var j = 0; j < thisName.length - n + 1; j++) {
            var ngram = thisName.substring(j, j + n);
            // console.log(" ", j, ngram);
            if (!ngramsCounted[ngram]) {
                ngramsCounted[ngram] = [];
            }
            ngramsCounted[ngram].push(thisName.charAt(j + n));
        }
    }
    // console.log(ngramsCounted);

    // Old way: Analyzing as one string but rejecting any ngram with a comma in it
    // for (var i = 0; i < corpus.length - n + 1; i++) {
    //     var ngram = corpus.substring(i, i + n);
    //     if (!ngramsCounted[ngram]) {
    //         ngramsCounted[ngram] = [];
    //     }
    //     // if (ngram.split(",") === 1) {
    //         ngramsCounted[ngram].push(corpus.charAt(i+n));
    //     // }
    // }

    return ngramsCounted;
}

function generateText(model, length, start) {
    // TODO: check that start, if it's provided, is long enough for the model

    // Pick a starting string if the caller didn't provide one
    while (!start) {
        var startCandidate = Object.keys(model).randomElement();
        if (startCandidate.split(",").length === 1) {
            start = startCandidate;
        }
        console.log(start);
    }
    // if (!start) {
    //     start = Object.keys(model).randomElement();
    // }
    // console.log(start);

    var currentNgram;
    n = start.length;

    // Initialize the result with the starting string
    var result = start;
    for (var i = 0; i < length; i++) {
        // Take the current ngram (last n letters of the string being built)
        currentNgram = result.substring(result.length - n)

        // Get the possible next letters
        var possibilities = model[currentNgram];
        console.log(possibilities);

        // Pick one
        var next = possibilities.randomElement();

        // Stop when we reach a comma
        if (next === ",") break;

        // Append the chosen letter, if we didn't break
        result = result + next;
    }

    return result;
}

var model = generateModel(cleanCorpus(corpus_Banggood), 3);
<|endoftext|>


<commit_before>import Ticker from '../lib/src/util/Ticker.js';

/**
 * @customElement
 * Element triggering a requestAnimationFrame on it's update method.
 */
export default class AnimationTickerElement extends HTMLElement {
  constructor() {
    super();

    this._paused = true;
    this._pausedByUser = true;
    this._pausedByBlur = false;

    this._updateBinded = this.update.bind(this);
    this._onFocusChangeBinded = this._onFocusChange.bind(this);
  }

  connectedCallback() {
    this._autoplay = this.hasAttribute('autoplay');
    this._background = this.hasAttribute('background');

    if (!this._background) {
      window.top.addEventListener('blur', this._onFocusChangeBinded);
      window.top.addEventListener('focus', this._onFocusChangeBinded);
      document.addEventListener('visibilitychange', this._onFocusChangeBinded);
    }
    if (this._autoplay) {
      this.play();
    }
  }

  disconnectedCallback() {
    this._pausedByBlur = true;
    window.top.removeEventListener('blur', this._onFocusChangeBinded);
    window.top.removeEventListener('focus', this._onFocusChangeBinded);
    document.removeEventListener('visibilitychange', this._onFocusChangeBinded);
  }

  /**
   * @type {Boolean}
   * @readonly
   * @description Tells whether the element is paused
   */
  get paused() {
    return this._paused;
  }

  get _pausedByUser() {
    return this.__pausedByUser;
  }

  set _pausedByUser(value) {
    this.__pausedByUser = value;
    this._updatePlaybackState();
  }

  get _pausedByBlur() {
    return this.__pausedByBlur;
  }

  set _pausedByBlur(value) {
    this.__pausedByBlur = value;
    this._updatePlaybackState();
  }

  _onFocusChange(event) {
    switch (event.type) {
      case 'visibilitychange':
        if (document.visibilityState !== 'visible') {
          this._pausedByBlur = true;
        }
        break;
      case 'blur':
        this._pausedByBlur = true;
        break;
      case 'focus':
        this._pausedByBlur = false;
        break;
    }
  }

  _updatePlaybackState() {
    const paused = this._pausedByUser || this._pausedByBlur;

    if (paused === this._paused) {
      return;
    }

    this._paused = paused;

    if (this._paused) {
      Ticker.delete(this._updateBinded);
      this.dispatchEvent(new Event('pause'));
    } else {
      Ticker.add(this._updateBinded);
      this.dispatchEvent(new Event('play'));
    }
  }

  /**
   * Play element animation
   */
  play() {
    this._pausedByUser = false;
    if (!window.top.document.hasFocus() && !this._background) {
      this._pausedByBlur = true;
      requestAnimationFrame(this._updateBinded);
    }
  }

  /**
   * Pause element animation
   */
  pause() {
    this._pausedByUser = true;
  }

  update() { }
}
<commit_msg>simplify animation-ticker element<commit_after>import Ticker from '../lib/src/util/Ticker.js';

const PAUSED_BY_USER = 1;
const PAUSED_BY_INTERSECTION = 2;
const PAUSED_BY_VISIBILITY = 4;

/**
 * @customElement
 * Element triggering requestAnimationFrame on it's update method.
 */
export default class AnimationTickerElement extends HTMLElement {
  constructor() {
    super();

    this.autoplay = false;

    this._pauseFlag = PAUSED_BY_USER;

    this._updateBinded = this.update.bind(this);

    document.addEventListener('visibilitychange', () => {
      if (document.hidden) {
        this._pauseFlag |= PAUSED_BY_VISIBILITY;
      } else {
        this._pauseFlag &= ~PAUSED_BY_VISIBILITY;
      }
    });
    const observer = new IntersectionObserver((entries) => {
      if (!entries[0].isIntersecting) {
        this._pauseFlag |= PAUSED_BY_INTERSECTION;
      } else {
        this._pauseFlag &= ~PAUSED_BY_INTERSECTION;
      }
    });
    observer.observe(this);
  }

  connectedCallback() {
    if (this.autoplay) {
      this._pauseFlag &= ~PAUSED_BY_USER;
    }
  }

  disconnectedCallback() {
    Ticker.delete(this._updateBinded);
  }

  get _pauseFlag() {
    return this.__pauseFlag;
  }

  set _pauseFlag(value) {
    if (this.__pauseFlag === value) {
      return;
    }
    this.__pauseFlag = value;
    if (this.__pauseFlag) {
      Ticker.delete(this._updateBinded);
    } else if (!this._paused) {
      Ticker.add(this._updateBinded);
    }
  }

  /**
   * Indicating whether element should automatically play
   * @type {Boolean}
   */
  get autoplay() {
    return this.hasAttribute('autoplay');
  }

  set autoplay(value) {
    if (value) {
      this.setAttribute('autoplay', '');
    } else {
      this.removeAttribute('autoplay');
    }
  }

  /**
   * Play element animation
   */
  play() {
    this._pauseFlag &= ~PAUSED_BY_USER;
  }

  /**
   * Pause element animation
   */
  pause() {
    this._pauseFlag |= PAUSED_BY_USER;
  }

  /**
   * Tells whether the media element is paused.
   * @type {Boolean}
   * @readonly
   */
  get paused() {
    return !!this._pauseFlag;
  }

  update() { }
}
<|endoftext|>


<commit_before>'use strict';

angular.module('flowsimUiApp')
  .factory('UInt', function() {

var Pattern = /^(0x)?[0-9a-fA-F]+$/;

function padZeros(input, len) {
  len -= input.length;
  if(len < 1) { return input; }
  return _(len).times(function() {
    return '0';
  }).join('') + input;
}

function howManyBits(val) {
  if(val === 0) { return 1; }
  return Math.floor((Math.log(val) / Math.LN2) + 1);
}

function howManyBytes(val) {
  if(val === 0) { return 1; }
  return Math.ceil(howManyBits(val) / 8);
}

function maxFromBits(val) {
  return Math.ceil(Math.pow(2, val) - 1);
}

function maxFromBytes(val) {
  return Math.ceil(maxFromBits(8*val));
}

function is(bits) {
  return function(val) {
    var tmp, pos;
    if(_.isFinite(val) && (val % 1 === 0)) {
      return 0 <= val && val <= maxFromBits(bits);
    } else if(_.isString(val) && Pattern.test(val)) {
      if(bits <= 32) {
        tmp = parseInt(val);
        return 0 <= tmp && tmp <= maxFromBits(bits);
      } else {
        //FIXME
        pos = val.indexOf('0x');
        pos = pos === -1 ? 0 : 2;
        tmp = val.substring(pos, bits-(bits/4));
      }
    }
    return false;
  };
}

// Construct a function that converts a string to a value with a specific
// underlying bit precision. If the bit precision is 32 or less, the result
// is a natural number. If the bit precision is greater than 32, the result
// is an array of natural numbers where each cell is [0..255].
//
// consStr :: String -> Nat | [Nat] if bits > 32
//
function consStr(bits) {
  var bytes = Math.ceil(bits / 8);
  var hbytes = Math.ciel(bits / 4);
  return function(val) {
    var i;
    var array = [];
    // We should not have bad input at this point
    if(!Pattern.test(val)) {
      throw 'Bad consStr('+bits+')('+val+')';
    }
    // Return the value if the precision is 32 or under
    val = parseInt(val);
    if(val <= maxFromBits(32) && bits <= 32) {
      return val;
    }
    // Throw an execption if the value is too large for the precision
    if(bits <= 32) {
      throw 'Bad consStr('+bits+')('+val+')';
    }
    // Return the easy case of 0
    if(val === '0') {
      return _(bytes).range(function() {
        return 0;
      });
    }
    // Otherwise must be hex
    if(/^0x/.test(val)) {
      // Chop the '0x' prefix for easier handling
      val.splice(0, 2);
      // Input is larger than allowable
      if(val.length > hbytes) {
        throw 'Bad consStr('+bits+')('+val+')';
      }
      // Work from the back of the input
      val.reverse();
      for(i=0; i<bytes; ++i) {
        // We are out of input just return a 0
        if(val.length === 0) {
          array.push(0);
        // We only have a half-octect of input
        } else if(val.length === 1) {
          // parse just a half-octect and remove
          array.push(parseInt(val.splice(0, 1), 16));
        // Otherwise we have a full octet of input
        } else {
          // parse a full octect and remove
          array.push(parseInt(val.splice(0, 2), 16));
        }
      }
      // Fix the array orientation and return
      array.reverse();
      return array;
    } else {
      // We don't know what it is ... hard fail
      throw 'Bad consStr('+bits+')('+val+')';
    }
  };
}

// Construct a funtion that converts either a natural number or array of natural
// numbers to a user display string.
//
// toString :: Nat | [Nat] -> String
//
function toString(bits) {
  return function(value, base) {
    if(_(value).isArray()) {
      return '0x'+_(value).map(function(octet) {
        return UInt.padZeros(octet.toString(16), 2);
      });
    } else if(_(value).isFinite()) {
      if(base === 16) {
        return '0x'+UInt.padZeros(value.toString(16), 2*(bits/8));
      } else {
        return value.toString(base);
      }
    } else {
      throw 'toString on bad value: '+value;
    }
  };
}

function UInt(uint, value, bytes) {
  if(_.isObject(uint)) {
    if(uint.bytes > 4) {
      this.value = _.clone(uint.value);
    } else {
      this.value = uint.value;
    }
    this.bytes = uint.bytes;
  } else if(_.isString(value) && Pattern.test(value) && bytes) {
    if(bytes < 5) {
      this.value = parseInt(value);
    } else {
      // Cannot construct from string for larger than 4 bytes
      throw 'UInt('+uint+', '+value+', '+bytes+')';
    }
    this.bytes = bytes;
  } else if(_.isArray(value)) {
    this.value = value;
    this.bytes = bytes ? _.max([bytes, value.length]) : value.length;
  } else if(_.isFinite(value) && (value % 1 === 0)) {
    this.value = value;
    this.bytes = bytes ? bytes : 4;
  } else if((_.isUndefined(value) || _.isNull(value)) && bytes && bytes > 0) {
    if(bytes < 5) {
      this.value = 0;
      this.bytes = bytes;
    } else {
      this.value = _(bytes).times(function() { return 0; });
      this.bytes = bytes;
    }
  } else {
    throw 'UInt('+uint+', '+value+', '+bytes+')';
  }
  // If converted value is wider than limit throw exception
  if(this.bytes < 5 && howManyBytes(this.value) > this.bytes) {
    throw 'UInt('+uint+', '+value+', '+bytes+')';
  } else if(this.bytes > 4 && this.value.length > this.bytes) {
    throw 'UInt('+uint+', '+value+', '+bytes+')';
  }
  // If converted value is negative, throw exception
  // warning: can only check 1, 2, 3 byte uints for negativity...
  if (this.bytes < 4 && this.value < 0) {
    throw 'UInt('+uint+', '+value+', '+bytes+')';
  }
}

UInt.prototype.clone = function() {
  return new UInt(this);
};

UInt.prototype.and = function(rhs) {
  if(this.bytes !== rhs.bytes) {
    throw '.and('+this.bytes+', '+rhs.bytes+')';
  }
  if(this.bytes < 5) {
    this.value = (this.value & rhs.value) >>> 0;
  } else {
    this.value = _.map(_.zip(this.value, rhs.value), function(pair) {
      return (pair[0] & pair[1]) >>> 0;
    });
  }
  return this;
};

UInt.prototype.or = function(rhs) {
  if(this.bytes !== rhs.bytes) {
    throw '.or('+this.bytes+', '+rhs.bytes+')';
  }
  if(this.bytes < 5) {
    this.value = (this.value | rhs.value) >>> 0;
  } else {
    this.value = _.map(_.zip(this.value, rhs.value), function(pair) {
      return (pair[0] | pair[1]) >>> 0;
    });
  }
  return this;
};

UInt.prototype.xor = function(rhs) {
  if(this.bytes !== rhs.bytes) {
    throw '.xor('+this.bytes+', '+rhs.bytes+')';
  }
  if(this.bytes < 5) {
    this.value = (this.value ^ rhs.value) >>> 0;
  } else {
    this.value = _.map(_.zip(this.value, rhs.value), function(pair) {
      return (pair[0] ^ pair[1]) >>> 0;
    });
  }
  return this;
};

UInt.prototype.neg = function() {
  var mask;
  if(this.bytes < 5) {
    mask = 0xffffffff >>> (32 - (8*this.bytes));
    this.value = mask & (~this.value) >>> 0;
  } else {
    this.value = _(this.value).map(function(v) {
      return 0xff & (~v) >>> 0;
    });
  }
  return this;
};

UInt.prototype.mask = function(src, mask) {
  if(this.bytes !== src.bytes || this.bytes !== mask.bytes) {
    throw '.mask('+this.bytes+', '+src.bytes+', '+mask.bytes+')';
  }
  if(this.bytes < 5) {
    this.value = ((this.value & ~mask.value) | (src.value & mask.value)) >>> 0;
  } else {
    this.value = _.map(_.zip(this.value, src.value, mask.value),
                       function(triple) {
      return ((triple[0] & ~triple[2]) | (triple[1] & triple[2])) >>> 0;
    });
  }
  return this;
};

UInt.prototype.toString = function(base, sep) {
  var prefix = base === 16 ? '0x' : '';
  sep = sep ? sep : '';
  if(this.bytes < 5) {
    if(base === 16) {
      return prefix + padZeros(this.value.toString(base), 2*this.bytes);
    } else {
      return prefix + this.value.toString(base);
    }
  } else {
    return prefix + _(this.value).map(function(v) {
      return padZeros(v.toString(base), 2);
    }).join(sep);
  }
};

UInt.prototype.equal = function(uint){
  return this.bytes === uint.bytes && _.isEqual(this, uint);
};

function equal(lhs, rhs) {
  if(lhs.bytes !== rhs.bytes) {
    throw 'equal('+lhs.bytes+', '+rhs.bytes+')';
  }
  return lhs.bytes === rhs.bytes && _.isEqual(lhs, rhs);
}

function neg(val) {
  var result = new UInt(val);
  return result.neg();
}

function and(lhs, rhs) {
  var result = new UInt(lhs);
  return result.and(rhs);
}

function or(lhs, rhs) {
  var result = new UInt(lhs);
  return result.or(rhs);
}

function xor(lhs, rhs) {
  var result = new UInt(lhs);
  return result.xor(rhs);
}

function mask(tgt, src, msk) {
  var result = new UInt(tgt);
  return result.mask(src, msk);
}

function Match(match, value, mask) {
  if(_.isObject(match)) {
    this.value = new UInt(match.value);
    this.mask  = new UInt(match.mask);
  } else if(value.bytes === mask.bytes) {
    this.value = new UInt(value);
    this.mask  = new UInt(mask);
    this.value = this.value.and(this.mask);
  } else {
    throw 'Match('+match+', '+value+', '+mask+')';
  }
}

Match.prototype.clone = function() {
  return new Match(this);
};

Match.prototype.toString = function(base) {
  return this.value.toString(base) + '/' + this.mask.toString(base);
};

Match.prototype.equal = function(match) {
  return equal(this.value, match.value) && equal(this.mask, match.mask);
};

Match.mkWildcard = function(uint) {
  var bytes;
  if(uint instanceof UInt) {
    bytes = uint.bytes;
  } else {
    bytes = uint;
  }
  return new Match(null,
    new UInt(null, null, bytes),
    new UInt(null, null, bytes));
};

Match.mkExact = function(uint) {
  return new Match(null,
    uint,
    (new UInt(null, null, uint.bytes)).neg());
};

Match.prototype.match = function(val) {
  if(this.value.bytes !== val.bytes) {
    throw 'Match.match('+this.value.bytes+', '+val.bytes+')';
  } else if(this.value.bytes < 5) {
    return ((val.value & this.mask.value) >>> 0) === this.value.value;
  } else {
    return _.reduce(_.zip(val.value, this.mask.value, this.value.value),
      function(pass, triple) {
        return !pass ? false : ((triple[0] & triple[1]) >>> 0) === triple[2];
      }, true);
  }
};

return {
  padZeros: padZeros,
  HexPattern: Pattern,
  howManyBits: howManyBits,
  howManyBytes: howManyBytes,
  maxFromBits: maxFromBits,
  maxFromBytes: maxFromBytes,
  is: is,
  consStr: consStr,
  toString: toString,
  UInt: UInt,
  and: and,
  or: or,
  xor: xor,
  neg: neg,
  mask: mask,
  equal: equal,
  Match: Match,
  mkExact: Match.mkExact
};

});
<commit_msg>Fixing body of UInt.is<commit_after>'use strict';

angular.module('flowsimUiApp')
  .factory('UInt', function() {

var Pattern = /^(0x)?[0-9a-fA-F]+$/;

function padZeros(input, len) {
  len -= input.length;
  if(len < 1) { return input; }
  return _(len).times(function() {
    return '0';
  }).join('') + input;
}

function howManyBits(val) {
  if(val === 0) { return 1; }
  return Math.floor((Math.log(val) / Math.LN2) + 1);
}

function howManyBytes(val) {
  if(val === 0) { return 1; }
  return Math.ceil(howManyBits(val) / 8);
}

function maxFromBits(val) {
  return Math.ceil(Math.pow(2, val) - 1);
}

function maxFromBytes(val) {
  return Math.ceil(maxFromBits(8*val));
}

function is(bits) {
  return function(val) {
    // Test the numeric range if a number
    if(_.isFinite(val) && (val % 1 === 0)) {
      return 0 <= val && val <= maxFromBits(bits);
    // Othrwise validate is an actual string
    } else if(_(val).isString() && Pattern.test(val)) {
      // Check is simple range check if under 32 bits
      if(bits <= 32) {
        val = parseInt(val);
        return val <= maxFromBits(bits);
      // If over 32 bits its a little more complex
      } else {
        // Allow zero without '0x' prefix
        if(val === '0') { return true; }
        // Otherwise require the '0x' prefix for > 32 bit values
        if(!/^0x/.test(val)) { return false; }
        // Remove the '0x' prefix
        val.splice(0, 2);
        // Technically this will not be accurate for bit counts with
        // modulo 1, 2, and 3 .... FIXME
        return val.length <= Math.ceil(bits/4);
      }
    }
    return false;
  };
}

// Construct a function that converts a string to a value with a specific
// underlying bit precision. If the bit precision is 32 or less, the result
// is a natural number. If the bit precision is greater than 32, the result
// is an array of natural numbers where each cell is [0..255].
//
// consStr :: String -> Nat | [Nat] if bits > 32
//
function consStr(bits) {
  var bytes = Math.ceil(bits / 8);
  var hbytes = Math.ciel(bits / 4);
  return function(val) {
    var i;
    var array = [];
    // We should not have bad input at this point
    if(!Pattern.test(val)) {
      throw 'Bad consStr('+bits+')('+val+')';
    }
    // Return the value if the precision is 32 or under
    val = parseInt(val);
    if(val <= maxFromBits(32) && bits <= 32) {
      return val;
    }
    // Throw an execption if the value is too large for the precision
    if(bits <= 32) {
      throw 'Bad consStr('+bits+')('+val+')';
    }
    // Return the easy case of 0
    if(val === '0') {
      return _(bytes).range(function() {
        return 0;
      });
    }
    // Otherwise must be hex
    if(/^0x/.test(val)) {
      // Chop the '0x' prefix for easier handling
      val.splice(0, 2);
      // Input is larger than allowable
      if(val.length > hbytes) {
        throw 'Bad consStr('+bits+')('+val+')';
      }
      // Work from the back of the input
      val.reverse();
      for(i=0; i<bytes; ++i) {
        // We are out of input just return a 0
        if(val.length === 0) {
          array.push(0);
        // We only have a half-octect of input
        } else if(val.length === 1) {
          // parse just a half-octect and remove
          array.push(parseInt(val.splice(0, 1), 16));
        // Otherwise we have a full octet of input
        } else {
          // parse a full octect and remove
          array.push(parseInt(val.splice(0, 2), 16));
        }
      }
      // Fix the array orientation and return
      array.reverse();
      return array;
    } else {
      // We don't know what it is ... hard fail
      throw 'Bad consStr('+bits+')('+val+')';
    }
  };
}

// Construct a funtion that converts either a natural number or array of natural
// numbers to a user display string.
//
// toString :: Nat | [Nat] -> String
//
function toString(bits) {
  return function(value, base) {
    if(_(value).isArray()) {
      return '0x'+_(value).map(function(octet) {
        return UInt.padZeros(octet.toString(16), 2);
      });
    } else if(_(value).isFinite()) {
      if(base === 16) {
        return '0x'+UInt.padZeros(value.toString(16), 2*(bits/8));
      } else {
        return value.toString(base);
      }
    } else {
      throw 'toString on bad value: '+value;
    }
  };
}

function UInt(uint, value, bytes) {
  if(_.isObject(uint)) {
    if(uint.bytes > 4) {
      this.value = _.clone(uint.value);
    } else {
      this.value = uint.value;
    }
    this.bytes = uint.bytes;
  } else if(_.isString(value) && Pattern.test(value) && bytes) {
    if(bytes < 5) {
      this.value = parseInt(value);
    } else {
      // Cannot construct from string for larger than 4 bytes
      throw 'UInt('+uint+', '+value+', '+bytes+')';
    }
    this.bytes = bytes;
  } else if(_.isArray(value)) {
    this.value = value;
    this.bytes = bytes ? _.max([bytes, value.length]) : value.length;
  } else if(_.isFinite(value) && (value % 1 === 0)) {
    this.value = value;
    this.bytes = bytes ? bytes : 4;
  } else if((_.isUndefined(value) || _.isNull(value)) && bytes && bytes > 0) {
    if(bytes < 5) {
      this.value = 0;
      this.bytes = bytes;
    } else {
      this.value = _(bytes).times(function() { return 0; });
      this.bytes = bytes;
    }
  } else {
    throw 'UInt('+uint+', '+value+', '+bytes+')';
  }
  // If converted value is wider than limit throw exception
  if(this.bytes < 5 && howManyBytes(this.value) > this.bytes) {
    throw 'UInt('+uint+', '+value+', '+bytes+')';
  } else if(this.bytes > 4 && this.value.length > this.bytes) {
    throw 'UInt('+uint+', '+value+', '+bytes+')';
  }
  // If converted value is negative, throw exception
  // warning: can only check 1, 2, 3 byte uints for negativity...
  if (this.bytes < 4 && this.value < 0) {
    throw 'UInt('+uint+', '+value+', '+bytes+')';
  }
}

UInt.prototype.clone = function() {
  return new UInt(this);
};

UInt.prototype.and = function(rhs) {
  if(this.bytes !== rhs.bytes) {
    throw '.and('+this.bytes+', '+rhs.bytes+')';
  }
  if(this.bytes < 5) {
    this.value = (this.value & rhs.value) >>> 0;
  } else {
    this.value = _.map(_.zip(this.value, rhs.value), function(pair) {
      return (pair[0] & pair[1]) >>> 0;
    });
  }
  return this;
};

UInt.prototype.or = function(rhs) {
  if(this.bytes !== rhs.bytes) {
    throw '.or('+this.bytes+', '+rhs.bytes+')';
  }
  if(this.bytes < 5) {
    this.value = (this.value | rhs.value) >>> 0;
  } else {
    this.value = _.map(_.zip(this.value, rhs.value), function(pair) {
      return (pair[0] | pair[1]) >>> 0;
    });
  }
  return this;
};

UInt.prototype.xor = function(rhs) {
  if(this.bytes !== rhs.bytes) {
    throw '.xor('+this.bytes+', '+rhs.bytes+')';
  }
  if(this.bytes < 5) {
    this.value = (this.value ^ rhs.value) >>> 0;
  } else {
    this.value = _.map(_.zip(this.value, rhs.value), function(pair) {
      return (pair[0] ^ pair[1]) >>> 0;
    });
  }
  return this;
};

UInt.prototype.neg = function() {
  var mask;
  if(this.bytes < 5) {
    mask = 0xffffffff >>> (32 - (8*this.bytes));
    this.value = mask & (~this.value) >>> 0;
  } else {
    this.value = _(this.value).map(function(v) {
      return 0xff & (~v) >>> 0;
    });
  }
  return this;
};

UInt.prototype.mask = function(src, mask) {
  if(this.bytes !== src.bytes || this.bytes !== mask.bytes) {
    throw '.mask('+this.bytes+', '+src.bytes+', '+mask.bytes+')';
  }
  if(this.bytes < 5) {
    this.value = ((this.value & ~mask.value) | (src.value & mask.value)) >>> 0;
  } else {
    this.value = _.map(_.zip(this.value, src.value, mask.value),
                       function(triple) {
      return ((triple[0] & ~triple[2]) | (triple[1] & triple[2])) >>> 0;
    });
  }
  return this;
};

UInt.prototype.toString = function(base, sep) {
  var prefix = base === 16 ? '0x' : '';
  sep = sep ? sep : '';
  if(this.bytes < 5) {
    if(base === 16) {
      return prefix + padZeros(this.value.toString(base), 2*this.bytes);
    } else {
      return prefix + this.value.toString(base);
    }
  } else {
    return prefix + _(this.value).map(function(v) {
      return padZeros(v.toString(base), 2);
    }).join(sep);
  }
};

UInt.prototype.equal = function(uint){
  return this.bytes === uint.bytes && _.isEqual(this, uint);
};

function equal(lhs, rhs) {
  if(lhs.bytes !== rhs.bytes) {
    throw 'equal('+lhs.bytes+', '+rhs.bytes+')';
  }
  return lhs.bytes === rhs.bytes && _.isEqual(lhs, rhs);
}

function neg(val) {
  var result = new UInt(val);
  return result.neg();
}

function and(lhs, rhs) {
  var result = new UInt(lhs);
  return result.and(rhs);
}

function or(lhs, rhs) {
  var result = new UInt(lhs);
  return result.or(rhs);
}

function xor(lhs, rhs) {
  var result = new UInt(lhs);
  return result.xor(rhs);
}

function mask(tgt, src, msk) {
  var result = new UInt(tgt);
  return result.mask(src, msk);
}

function Match(match, value, mask) {
  if(_.isObject(match)) {
    this.value = new UInt(match.value);
    this.mask  = new UInt(match.mask);
  } else if(value.bytes === mask.bytes) {
    this.value = new UInt(value);
    this.mask  = new UInt(mask);
    this.value = this.value.and(this.mask);
  } else {
    throw 'Match('+match+', '+value+', '+mask+')';
  }
}

Match.prototype.clone = function() {
  return new Match(this);
};

Match.prototype.toString = function(base) {
  return this.value.toString(base) + '/' + this.mask.toString(base);
};

Match.prototype.equal = function(match) {
  return equal(this.value, match.value) && equal(this.mask, match.mask);
};

Match.mkWildcard = function(uint) {
  var bytes;
  if(uint instanceof UInt) {
    bytes = uint.bytes;
  } else {
    bytes = uint;
  }
  return new Match(null,
    new UInt(null, null, bytes),
    new UInt(null, null, bytes));
};

Match.mkExact = function(uint) {
  return new Match(null,
    uint,
    (new UInt(null, null, uint.bytes)).neg());
};

Match.prototype.match = function(val) {
  if(this.value.bytes !== val.bytes) {
    throw 'Match.match('+this.value.bytes+', '+val.bytes+')';
  } else if(this.value.bytes < 5) {
    return ((val.value & this.mask.value) >>> 0) === this.value.value;
  } else {
    return _.reduce(_.zip(val.value, this.mask.value, this.value.value),
      function(pass, triple) {
        return !pass ? false : ((triple[0] & triple[1]) >>> 0) === triple[2];
      }, true);
  }
};

return {
  padZeros: padZeros,
  HexPattern: Pattern,
  howManyBits: howManyBits,
  howManyBytes: howManyBytes,
  maxFromBits: maxFromBits,
  maxFromBytes: maxFromBytes,
  is: is,
  consStr: consStr,
  toString: toString,
  UInt: UInt,
  and: and,
  or: or,
  xor: xor,
  neg: neg,
  mask: mask,
  equal: equal,
  Match: Match,
  mkExact: Match.mkExact
};

});
<|endoftext|>


<commit_before>#!/usr/bin/env node
const program = require('commander');
const path = require('path');
const Config = require('../lib/config');
const Codecept = require('../lib/codecept');
const { print, error } = require('../lib/output');

if (process.versions.node && process.versions.node.split('.') && process.versions.node.split('.')[0] < 8) {
  error('NodeJS >= 8 is required to run.');
  print();
  print('Please upgrade your NodeJS engine');
  print(`Current NodeJS version: ${process.version}`);
  process.exit(1);
}

program.usage('<command> [options]');
program.version(Codecept.version());

program.command('init [path]')
  .description('Creates dummy config in current dir or [path]')
  .action(require('../lib/command/init'));

program.command('migrate [path]')
  .description('Migrate json config to js config in current dir or [path]')
  .action(require('../lib/command/configMigrate'));

program.command('shell [path]')
  .alias('sh')
  .description('Interactive shell')
  .option('--verbose', 'output internal logging information')
  .option('--profile [value]', 'configuration profile to be used')
  .action(require('../lib/command/interactive'));

program.command('list [path]')
  .alias('l')
  .description('List all actions for I.')
  .action(require('../lib/command/list'));

program.command('def [path]')
  .description('Generates TypeScript definitions for all I actions.')
  .option('-c, --config [file]', 'configuration file to be used')
  .option('-o, --output [folder]', 'target folder to paste definitions')
  .action(require('../lib/command/definitions'));

program.command('gherkin:init [path]')
  .alias('bdd:init')
  .description('Prepare CodeceptJS to run feature files.')
  .option('-c, --config [file]', 'configuration file to be used')
  .action(require('../lib/command/gherkin/init'));

program.command('gherkin:steps [path]')
  .alias('bdd:steps')
  .description('Prints all defined gherkin steps.')
  .option('-c, --config [file]', 'configuration file to be used')
  .action(require('../lib/command/gherkin/steps'));

program.command('gherkin:snippets [path]')
  .alias('bdd:snippets')
  .description('Generate step definitions from steps.')
  .option('--dry-run', "don't save snippets to file")
  .option('-c, --config [file]', 'configuration file to be used')
  .option('--feature [file]', 'feature files(s) to scan')
  .option('--path [file]', 'file in which to place the new snippets')
  .action(require('../lib/command/gherkin/snippets'));

program.command('generate:test [path]')
  .alias('gt')
  .description('Generates an empty test')
  .action(require('../lib/command/generate').test);

program.command('generate:pageobject [path]')
  .alias('gpo')
  .description('Generates an empty page object')
  .action(require('../lib/command/generate').pageObject);

program.command('generate:object [path]')
  .alias('go')
  .option('--type, -t [kind]', 'type of object to be created')
  .description('Generates an empty support object (page/step/fragment)')
  .action(require('../lib/command/generate').pageObject);

program.command('generate:helper [path]')
  .alias('gh')
  .description('Generates a new helper')
  .action(require('../lib/command/generate').helper);

program.command('run [test]')
  .description('Executes tests')

  // codecept-only options
  .option('--steps', 'show step-by-step execution')
  .option('--debug', 'output additional information')
  .option('--verbose', 'output internal logging information')
  .option('-o, --override [value]', 'override current config options')
  .option('--profile [value]', 'configuration profile to be used')
  .option('-c, --config [file]', 'configuration file to be used')
  .option('--features', 'run only *.feature files and skip tests')
  .option('--tests', 'run only JS test files and skip features')
  .option('-p, --plugins <k=v,k2=v2,...>', 'enable plugins, comma-separated')

  // mocha options
  .option('--colors', 'force enabling of colors')
  .option('--no-colors', 'force disabling of colors')
  .option('-G, --growl', 'enable growl notification support')
  .option('-O, --reporter-options <k=v,k2=v2,...>', 'reporter-specific options')
  .option('-R, --reporter <name>', 'specify the reporter to use')
  .option('-S, --sort', 'sort test files')
  .option('-b, --bail', 'bail after first test failure')
  .option('-d, --debug', "enable node's debugger, synonym for node --debug")
  .option('-g, --grep <pattern>', 'only run tests matching <pattern>')
  .option('-f, --fgrep <string>', 'only run tests containing <string>')
  .option('-i, --invert', 'inverts --grep and --fgrep matches')
  .option('--full-trace', 'display the full stack trace')
  .option('--compilers <ext>:<module>,...', 'use the given module(s) to compile files')
  .option('--debug-brk', "enable node's debugger breaking on the first line")
  .option('--inline-diffs', 'display actual/expected differences inline within each string')
  .option('--no-exit', 'require a clean shutdown of the event loop: mocha will not call process.exit')
  .option('--recursive', 'include sub directories')
  .option('--trace', 'trace function calls')
  .option('--child <string>', 'option for child processes')

  .action(require('../lib/command/run'));

program.command('run-multiple [suites...]')
  .description('Executes tests multiple')
  .option('-c, --config [file]', 'configuration file to be used')
  .option('--profile [value]', 'configuration profile to be used')
  .option('--all', 'run all suites')
  .option('--features', 'run only *.feature files and skip tests')
  .option('--tests', 'run only JS test files and skip features')
  .option('-g, --grep <pattern>', 'only run tests matching <pattern>')
  .option('-f, --fgrep <string>', 'only run tests containing <string>')
  .option('-i, --invert', 'inverts --grep and --fgrep matches')
  .option('--steps', 'show step-by-step execution')
  .option('--verbose', 'output internal logging information')
  .option('--debug', 'output additional information')
  .option('-p, --plugins <k=v,k2=v2,...>', 'enable plugins, comma-separated')
  .option('-o, --override [value]', 'override current config options')
  .option('-O, --reporter-options <k=v,k2=v2,...>', 'reporter-specific options')
  .option('-R, --reporter <name>', 'specify the reporter to use')
  .option('--recursive', 'include sub directories')

  .action(require('../lib/command/run-multiple'));

if (process.argv.length <= 2) {
  program.outputHelp();
}
program.parse(process.argv);
<commit_msg>warn on unknown commands (#1836)<commit_after>#!/usr/bin/env node
const program = require('commander');
const path = require('path');
const Config = require('../lib/config');
const Codecept = require('../lib/codecept');
const { print, error } = require('../lib/output');

if (process.versions.node && process.versions.node.split('.') && process.versions.node.split('.')[0] < 8) {
  error('NodeJS >= 8 is required to run.');
  print();
  print('Please upgrade your NodeJS engine');
  print(`Current NodeJS version: ${process.version}`);
  process.exit(1);
}

program.usage('<command> [options]');
program.version(Codecept.version());

program.command('init [path]')
  .description('Creates dummy config in current dir or [path]')
  .action(require('../lib/command/init'));

program.command('migrate [path]')
  .description('Migrate json config to js config in current dir or [path]')
  .action(require('../lib/command/configMigrate'));

program.command('shell [path]')
  .alias('sh')
  .description('Interactive shell')
  .option('--verbose', 'output internal logging information')
  .option('--profile [value]', 'configuration profile to be used')
  .action(require('../lib/command/interactive'));

program.command('list [path]')
  .alias('l')
  .description('List all actions for I.')
  .action(require('../lib/command/list'));

program.command('def [path]')
  .description('Generates TypeScript definitions for all I actions.')
  .option('-c, --config [file]', 'configuration file to be used')
  .option('-o, --output [folder]', 'target folder to paste definitions')
  .action(require('../lib/command/definitions'));

program.command('gherkin:init [path]')
  .alias('bdd:init')
  .description('Prepare CodeceptJS to run feature files.')
  .option('-c, --config [file]', 'configuration file to be used')
  .action(require('../lib/command/gherkin/init'));

program.command('gherkin:steps [path]')
  .alias('bdd:steps')
  .description('Prints all defined gherkin steps.')
  .option('-c, --config [file]', 'configuration file to be used')
  .action(require('../lib/command/gherkin/steps'));

program.command('gherkin:snippets [path]')
  .alias('bdd:snippets')
  .description('Generate step definitions from steps.')
  .option('--dry-run', "don't save snippets to file")
  .option('-c, --config [file]', 'configuration file to be used')
  .option('--feature [file]', 'feature files(s) to scan')
  .option('--path [file]', 'file in which to place the new snippets')
  .action(require('../lib/command/gherkin/snippets'));

program.command('generate:test [path]')
  .alias('gt')
  .description('Generates an empty test')
  .action(require('../lib/command/generate').test);

program.command('generate:pageobject [path]')
  .alias('gpo')
  .description('Generates an empty page object')
  .action(require('../lib/command/generate').pageObject);

program.command('generate:object [path]')
  .alias('go')
  .option('--type, -t [kind]', 'type of object to be created')
  .description('Generates an empty support object (page/step/fragment)')
  .action(require('../lib/command/generate').pageObject);

program.command('generate:helper [path]')
  .alias('gh')
  .description('Generates a new helper')
  .action(require('../lib/command/generate').helper);

program.command('run [test]')
  .description('Executes tests')

  // codecept-only options
  .option('--steps', 'show step-by-step execution')
  .option('--debug', 'output additional information')
  .option('--verbose', 'output internal logging information')
  .option('-o, --override [value]', 'override current config options')
  .option('--profile [value]', 'configuration profile to be used')
  .option('-c, --config [file]', 'configuration file to be used')
  .option('--features', 'run only *.feature files and skip tests')
  .option('--tests', 'run only JS test files and skip features')
  .option('-p, --plugins <k=v,k2=v2,...>', 'enable plugins, comma-separated')

  // mocha options
  .option('--colors', 'force enabling of colors')
  .option('--no-colors', 'force disabling of colors')
  .option('-G, --growl', 'enable growl notification support')
  .option('-O, --reporter-options <k=v,k2=v2,...>', 'reporter-specific options')
  .option('-R, --reporter <name>', 'specify the reporter to use')
  .option('-S, --sort', 'sort test files')
  .option('-b, --bail', 'bail after first test failure')
  .option('-d, --debug', "enable node's debugger, synonym for node --debug")
  .option('-g, --grep <pattern>', 'only run tests matching <pattern>')
  .option('-f, --fgrep <string>', 'only run tests containing <string>')
  .option('-i, --invert', 'inverts --grep and --fgrep matches')
  .option('--full-trace', 'display the full stack trace')
  .option('--compilers <ext>:<module>,...', 'use the given module(s) to compile files')
  .option('--debug-brk', "enable node's debugger breaking on the first line")
  .option('--inline-diffs', 'display actual/expected differences inline within each string')
  .option('--no-exit', 'require a clean shutdown of the event loop: mocha will not call process.exit')
  .option('--recursive', 'include sub directories')
  .option('--trace', 'trace function calls')
  .option('--child <string>', 'option for child processes')

  .action(require('../lib/command/run'));

program.command('run-multiple [suites...]')
  .description('Executes tests multiple')
  .option('-c, --config [file]', 'configuration file to be used')
  .option('--profile [value]', 'configuration profile to be used')
  .option('--all', 'run all suites')
  .option('--features', 'run only *.feature files and skip tests')
  .option('--tests', 'run only JS test files and skip features')
  .option('-g, --grep <pattern>', 'only run tests matching <pattern>')
  .option('-f, --fgrep <string>', 'only run tests containing <string>')
  .option('-i, --invert', 'inverts --grep and --fgrep matches')
  .option('--steps', 'show step-by-step execution')
  .option('--verbose', 'output internal logging information')
  .option('--debug', 'output additional information')
  .option('-p, --plugins <k=v,k2=v2,...>', 'enable plugins, comma-separated')
  .option('-o, --override [value]', 'override current config options')
  .option('-O, --reporter-options <k=v,k2=v2,...>', 'reporter-specific options')
  .option('-R, --reporter <name>', 'specify the reporter to use')
  .option('--recursive', 'include sub directories')

  .action(require('../lib/command/run-multiple'));

program.on('command:*', (cmd) => {
  console.log(`\nUnknown command ${cmd}\n`);
  program.outputHelp();
});

if (process.argv.length <= 2) {
  program.outputHelp();
}
program.parse(process.argv);
<|endoftext|>


<commit_before>// @flow
import bodyParser from 'koa-bodyparser';
import Koa from 'koa';
import Static from 'koa-static';

function errorHandler(ctx: Koa$Context, next: Function) {
  return next().catch(e => {
    ctx.status = 500;
    ctx.body = e.message;
  });
}

const koa = new Koa();

koa.use(errorHandler);
koa.use(Static(`${__dirname}/../fnordcredit_frontend/dist`));
koa.use(bodyParser());

global.koa = koa;

require('./Routes');
<commit_msg>Fix frontend path<commit_after>// @flow
import bodyParser from 'koa-bodyparser';
import Koa from 'koa';
import Static from 'koa-static';

function errorHandler(ctx: Koa$Context, next: Function) {
  return next().catch(e => {
    ctx.status = 500;
    ctx.body = e.message;
  });
}

const koa = new Koa();

koa.use(errorHandler);
koa.use(Static(`${__dirname}/../fnordcredit-frontend/dist`));
koa.use(bodyParser());

global.koa = koa;

require('./Routes');
<|endoftext|>


<commit_before>/**
 * pathvaiable, querystring 파라미터를 추출하는 클래스
 * location.hash 정보를 '_hash'키 값으로 가지고 있다.
 *
 * @param router URL 패턴
 * @param location 테스트용 변수입니다. 사용하지 마세요.
 * @example
 * var params = Restful();
 * var params = Restful('/category/{code}/{deal}/edit');
 */
var Restful = function(router, location){

  var isArray = function(obj) {
    return Object.prototype.toString.call(obj) === '[object Array]';
  };

  var error = function(message){
    if (window.console && window.console.error) {
      console.error(message);
    } else {
      //alert(message);
    }
  };

  // default value setting
  router = router ||'';
  location = location || window.location;

  var params = {};
  (function() {
    if (!router) return;
    var routers = router.split('/');
    var urls = location.pathname.split('/');

    // TODO context path는 어쩌지?
    if (routers.length != urls.length) {
      error('router and url not match~!');
    }

    for (var i = 0; i < routers.length; i++) {
      var matches = routers[i].match(/\{(\w+)\}/);
      if (matches) {
        params[matches[1]] = urls[i];
      }
    }
  })();

  (function() {
    var queryString = location.search;
    if (!queryString) return params;

    var keyVals = queryString.substring(1).split('&');
    for (var i = 0; i < keyVals.length; i++) {
      var keyVal = keyVals[i].split('=');
      var key = keyVal[0];
      var val = keyVal[1];

      if (key in params) {
        var preVal = params[key];
        if (isArray(preVal)) {
          params[key] = preVal.push(val);
        } else {
          params[key] = [ preVal, val ];
        }
      } else {
        params[key] = val;
      }
    }
  })();

  params['_hash'] = (location.hash).replace('#', '') || '';

  return params;
};
<commit_msg>버그 픽스<commit_after>/**
 * pathvaiable, querystring 파라미터를 추출하는 클래스
 * location.hash 정보를 '_hash'키 값으로 가지고 있다.
 *
 * @param router URL 패턴
 * @param location 테스트용 변수입니다. 사용하지 마세요.
 * @example
 * var params = Restful();
 * var params = Restful('/category/{code}/{deal}/edit');
 */
var Restful = function(router, location){

  var isArray = function(obj) {
    return Object.prototype.toString.call(obj) === '[object Array]';
  };

  var error = function(message){
    if (window.console && window.console.error) {
      console.error(message);
    } else {
      //alert(message);
    }
  };

  // default value setting
  router = router ||'';
  location = location || window.location;

  var params = {};
  (function() {
    if (!router) return;
    var routers = router.split('/');
    var urls = location.pathname.split('/');

    // TODO context path는 어쩌지?
    if (routers.length != urls.length) {
      error('router and url not match~!');
    }

    for (var i = 0; i < routers.length; i++) {
      var matches = routers[i].match(/\{(\w+)\}/);
      if (matches) {
        params[matches[1]] = urls[i];
      }
    }
  })();

  (function() {
    var queryString = location.search;
    if (!queryString) return params;

    var keyVals = queryString.substring(1).split('&');
    for (var i = 0; i < keyVals.length; i++) {
      var keyVal = keyVals[i].split('=');
      var key = keyVal[0];
      var val = keyVal[1];

      if (key in params) {
        var preVal = decodeURIComponent(params[key]);
        if (isArray(preVal)) {
          preVal.push(val);
          params[key] = preVal;
        } else {
          params[key] = [ preVal, val ];
        }
      } else {
        params[key] = val;
      }
    }
  })();

  params['_hash'] = (location.hash).replace('#', '') || '';

  return params;
};
<|endoftext|>