<commit_before>/* globals requirejs, require */

import Ember from 'ember';
import { assert, deprecate, warn } from '@ember/debug';
import EmberObject, { get, computed } from '@ember/object';
import { dasherize, classify, underscore } from '@ember/string';
import { DEBUG } from '@glimmer/env';
import classFactory from '../../utils/class-factory';
import makeDictionary from '../../utils/make-dictionary';

if (typeof requirejs.entries === 'undefined') {
  requirejs.entries = requirejs._eak_seen;
}

export class ModuleRegistry {
  constructor(entries) {
    this._entries = entries || requirejs.entries;
  }
  moduleNames() {
    return Object.keys(this._entries);
  }
  has(moduleName) {
    return moduleName in this._entries;
  }
  get(moduleName) {
    return require(moduleName);
  }
}

/**
 * This module defines a subclass of Ember.DefaultResolver that adds two
 * important features:
 *
 *  1) The resolver makes the container aware of es6 modules via the AMD
 *     output. The loader's _moduleEntries is consulted so that classes can be
 *     resolved directly via the module loader, without needing a manual
 *     `import`.
 *  2) is able to provide injections to classes that implement `extend`
 *     (as is typical with Ember).
 */

function parseName(fullName) {
  if (fullName.parsedName === true) { return fullName; }

  let prefix, type, name;
  let fullNameParts = fullName.split('@');

  // HTMLBars uses helper:@content-helper which collides
  // with ember-cli namespace detection.
  // This will be removed in a future release of HTMLBars.
  if (fullName !== 'helper:@content-helper' &&
      fullNameParts.length === 2) {
    let prefixParts = fullNameParts[0].split(':');

    if (prefixParts.length === 2) {
      prefix = prefixParts[1];
      type = prefixParts[0];
      name = fullNameParts[1];
    } else {
      let nameParts = fullNameParts[1].split(':');

      prefix = fullNameParts[0];
      type = nameParts[0];
      name = nameParts[1];
    }

    if (type === 'template' && prefix.lastIndexOf('components/', 0) === 0) {
      name = `components/${name}`;
      prefix = prefix.slice(11);
    }
  } else {
    fullNameParts = fullName.split(':');
    type = fullNameParts[0];
    name = fullNameParts[1];
  }

  let fullNameWithoutType = name;
  let namespace = get(this, 'namespace');
  let root = namespace;

  return {
    parsedName: true,
    fullName: fullName,
    prefix: prefix || this.prefix({type: type}),
    type: type,
    fullNameWithoutType: fullNameWithoutType,
    name: name,
    root: root,
    resolveMethodName: "resolve" + classify(type)
  };
}

function resolveOther(parsedName) {
  assert('`modulePrefix` must be defined', this.namespace.modulePrefix);

  let normalizedModuleName = this.findModuleName(parsedName);

  if (normalizedModuleName) {
    let defaultExport = this._extractDefaultExport(normalizedModuleName, parsedName);

    if (defaultExport === undefined) {
      throw new Error(` Expected to find: '${parsedName.fullName}' within '${normalizedModuleName}' but got 'undefined'. Did you forget to 'export default' within '${normalizedModuleName}'?`);
    }

    if (this.shouldWrapInClassFactory(defaultExport, parsedName)) {
      defaultExport = classFactory(defaultExport);
    }

    return defaultExport;
  }
}

// Ember.DefaultResolver docs:
//   https://github.com/emberjs/ember.js/blob/master/packages/ember-application/lib/system/resolver.js
const Resolver = EmberObject.extend({
  resolveOther,
  parseName,
  pluralizedTypes: null,
  moduleRegistry: null,

  makeToString(factory, fullName) {
    return '' + this.namespace.modulePrefix + '@' + fullName + ':';
  },

  shouldWrapInClassFactory(/* module, parsedName */){
    return false;
  },

  init() {
    this._super();
    this.moduleBasedResolver = true;

    if (!this._moduleRegistry) {
      this._moduleRegistry = new ModuleRegistry();
    }

    this._normalizeCache = makeDictionary();

    this.pluralizedTypes = this.pluralizedTypes || makeDictionary();

    if (!this.pluralizedTypes.config) {
      this.pluralizedTypes.config = 'config';
    }
    this._deprecatedPodModulePrefix = false;
  },

  normalize(fullName) {
    return this._normalizeCache[fullName] || (this._normalizeCache[fullName] = this._normalize(fullName));
  },

  resolve(fullName) {
    let parsedName = this.parseName(fullName);
    let resolveMethodName = parsedName.resolveMethodName;
    let resolved;

    if (typeof this[resolveMethodName] === 'function') {
      resolved = this[resolveMethodName](parsedName);
    }

    if (resolved == null) {
      resolved = this.resolveOther(parsedName);
    }

    return resolved;
  },

  _normalize(fullName) {
    // A) Convert underscores to dashes
    // B) Convert camelCase to dash-case, except for helpers where we want to avoid shadowing camelCase expressions
    // C) replace `.` with `/` in order to make nested controllers work in the following cases
    //      1. `needs: ['posts/post']`
    //      2. `{{render "posts/post"}}`
    //      3. `this.render('posts/post')` from Route

    let split = fullName.split(':');
    if (split.length > 1) {
      if (split[0] === 'helper') {
        return split[0] + ':' + split[1].replace(/_/g, '-');
      } else {
        return split[0] + ':' + dasherize(split[1].replace(/\./g, '/'));
      }
    } else {
      return fullName;
    }
  },

  pluralize(type) {
    return this.pluralizedTypes[type] || (this.pluralizedTypes[type] = type + 's');
  },

  podBasedLookupWithPrefix(podPrefix, parsedName) {
    let fullNameWithoutType = parsedName.fullNameWithoutType;

    if (parsedName.type === 'template') {
      fullNameWithoutType = fullNameWithoutType.replace(/^components\//, '');
    }

    return podPrefix + '/' + fullNameWithoutType + '/' + parsedName.type;
  },

  podBasedModuleName(parsedName) {
    let podPrefix = this.namespace.podModulePrefix || this.namespace.modulePrefix;

    return this.podBasedLookupWithPrefix(podPrefix, parsedName);
  },

  podBasedComponentsInSubdir(parsedName) {
    let podPrefix = this.namespace.podModulePrefix || this.namespace.modulePrefix;
    podPrefix = podPrefix + '/components';

    if (parsedName.type === 'component' || /^components/.test(parsedName.fullNameWithoutType)) {
      return this.podBasedLookupWithPrefix(podPrefix, parsedName);
    }
  },

  resolveEngine(parsedName) {
    let engineName = parsedName.fullNameWithoutType;
    let engineModule = engineName + '/engine';

    if (this._moduleRegistry.has(engineModule)) {
      return this._extractDefaultExport(engineModule);
    }
  },

  resolveRouteMap(parsedName) {
    let engineName = parsedName.fullNameWithoutType;
    let engineRoutesModule = engineName + '/routes';

    if (this._moduleRegistry.has(engineRoutesModule)) {
      let routeMap = this._extractDefaultExport(engineRoutesModule);

      assert(`The route map for ${engineName} should be wrapped by 'buildRoutes' before exporting.` , routeMap.isRouteMap);

      return routeMap;
    }
  },

  resolveTemplate(parsedName) {
    let resolved = this.resolveOther(parsedName);
    if (resolved == null) {
      resolved = Ember.TEMPLATES[parsedName.fullNameWithoutType];
    }
    return resolved;
  },

  mainModuleName(parsedName) {
    if (parsedName.fullNameWithoutType === 'main') {
      // if router:main or adapter:main look for a module with just the type first
      return parsedName.prefix + '/' + parsedName.type;
    }
  },

  defaultModuleName(parsedName) {
    return parsedName.prefix + '/' +  this.pluralize(parsedName.type) + '/' + parsedName.fullNameWithoutType;
  },

  prefix(parsedName) {
    let tmpPrefix = this.namespace.modulePrefix;

    if (this.namespace[parsedName.type + 'Prefix']) {
      tmpPrefix = this.namespace[parsedName.type + 'Prefix'];
    }

    return tmpPrefix;
  },

  /**

   A listing of functions to test for moduleName's based on the provided
   `parsedName`. This allows easy customization of additional module based
   lookup patterns.

   @property moduleNameLookupPatterns
   @returns {Ember.Array}
   */
  moduleNameLookupPatterns: computed(function(){
    return [
      this.podBasedModuleName,
      this.podBasedComponentsInSubdir,
      this.mainModuleName,
      this.defaultModuleName
    ];
  }).readOnly(),

  findModuleName(parsedName, loggingDisabled){
    let moduleNameLookupPatterns = this.get('moduleNameLookupPatterns');
    let moduleName;

    for (let index = 0, length = moduleNameLookupPatterns.length; index < length; index++) {
      let item = moduleNameLookupPatterns[index];

      let tmpModuleName = item.call(this, parsedName);

      // allow treat all dashed and all underscored as the same thing
      // supports components with dashes and other stuff with underscores.
      if (tmpModuleName) {
        tmpModuleName = this.chooseModuleName(tmpModuleName, parsedName);
      }

      if (tmpModuleName && this._moduleRegistry.has(tmpModuleName)) {
        moduleName = tmpModuleName;
      }

      if (!loggingDisabled) {
        this._logLookup(moduleName, parsedName, tmpModuleName);
      }

      if (moduleName) {
        return moduleName;
      }
    }
  },

  chooseModuleName(moduleName, parsedName) {
    let underscoredModuleName = underscore(moduleName);

    if (moduleName !== underscoredModuleName && this._moduleRegistry.has(moduleName) && this._moduleRegistry.has(underscoredModuleName)) {
      throw new TypeError(`Ambiguous module names: '${ moduleName}' and '${underscoredModuleName }'`);
    }

    if (this._moduleRegistry.has(moduleName)) {
      return moduleName;
    } else if (this._moduleRegistry.has(underscoredModuleName)) {
      return underscoredModuleName;
    }
    // workaround for dasherized partials:
    // something/something/-something => something/something/_something
    let partializedModuleName = moduleName.replace(/\/-([^/]*)$/, '/_$1');

    if (this._moduleRegistry.has(partializedModuleName)) {
      deprecate('Modules should not contain underscores. ' +
      'Attempted to lookup "'+moduleName+'" which ' +
      'was not found. Please rename "'+partializedModuleName+'" '+
      'to "'+moduleName+'" instead.', false,
      { id: 'ember-resolver.underscored-modules', until: '3.0.0' });

      return partializedModuleName;
    }

    if (DEBUG) {
      let isCamelCaseHelper = parsedName.type === 'helper' && /[a-z]+[A-Z]+/.test(moduleName);
      if (isCamelCaseHelper) {
        this._camelCaseHelperWarnedNames = this._camelCaseHelperWarnedNames || [];
        let alreadyWarned = this._camelCaseHelperWarnedNames.indexOf(parsedName.fullName) > -1;
        if (!alreadyWarned && this._moduleRegistry.has(dasherize(moduleName))) {
          this._camelCaseHelperWarnedNames.push(parsedName.fullName);
          warn('Attempted to lookup "' + parsedName.fullName + '" which ' +
          'was not found. In previous versions of ember-resolver, a bug would have ' +
          'caused the module at "' + dasherize(moduleName) + '" to be ' +
          'returned for this camel case helper name. This has been fixed. ' +
          'Use the dasherized name to resolve the module that would have been ' +
          'returned in previous versions.',
          false,
          { id: 'ember-resolver.camelcase-helper-names', until: '3.0.0' });
        }
      }
    }
  },

  // used by Ember.DefaultResolver.prototype._logLookup
  lookupDescription(fullName) {
    let parsedName = this.parseName(fullName);

    let moduleName = this.findModuleName(parsedName, true);

    return moduleName;
  },

  // only needed until 1.6.0-beta.2 can be required
  _logLookup(found, parsedName, description) {
    if (!Ember.ENV.LOG_MODULE_RESOLVER && !parsedName.root.LOG_RESOLVER) {
      return;
    }

    let padding;
    let symbol = found ? '[✓]' : '[ ]';

    if (parsedName.fullName.length > 60) {
      padding = '.';
    } else {
      padding = new Array(60 - parsedName.fullName.length).join('.');
    }

    if (!description) {
      description = this.lookupDescription(parsedName);
    }

    /* eslint-disable no-console */
    if (console && console.info) {
      console.info(symbol, parsedName.fullName, padding, description);
    }
  },

  knownForType(type) {
    let moduleKeys = this._moduleRegistry.moduleNames();

    let items = makeDictionary();
    for (let index = 0, length = moduleKeys.length; index < length; index++) {
      let moduleName = moduleKeys[index];
      let fullname = this.translateToContainerFullname(type, moduleName);

      if (fullname) {
        items[fullname] = true;
      }
    }

    return items;
  },

  translateToContainerFullname(type, moduleName) {
    let prefix = this.prefix({ type });

    // Note: using string manipulation here rather than regexes for better performance.
    // pod modules
    // '^' + prefix + '/(.+)/' + type + '$'
    let podPrefix = prefix + '/';
    let podSuffix = '/' + type;
    let start = moduleName.indexOf(podPrefix);
    let end = moduleName.indexOf(podSuffix);

    if (start === 0 && end === (moduleName.length - podSuffix.length) &&
        moduleName.length > (podPrefix.length + podSuffix.length)) {
      return type + ':' + moduleName.slice(start + podPrefix.length, end);
    }

    // non-pod modules
    // '^' + prefix + '/' + pluralizedType + '/(.+)$'
    let pluralizedType = this.pluralize(type);
    let nonPodPrefix = prefix + '/' + pluralizedType + '/';

    if (moduleName.indexOf(nonPodPrefix) === 0 && moduleName.length > nonPodPrefix.length) {
      return type + ':' + moduleName.slice(nonPodPrefix.length);
    }
  },

  _extractDefaultExport(normalizedModuleName) {
    let module = require(normalizedModuleName, null, null, true /* force sync */);

    if (module && module['default']) {
      module = module['default'];
    }

    return module;
  }
});

Resolver.reopenClass({
  moduleBasedResolver: true
});

export default Resolver;
<commit_msg>Remove outaded comment<commit_after>/* globals requirejs, require */

import Ember from 'ember';
import { assert, deprecate, warn } from '@ember/debug';
import EmberObject, { get, computed } from '@ember/object';
import { dasherize, classify, underscore } from '@ember/string';
import { DEBUG } from '@glimmer/env';
import classFactory from '../../utils/class-factory';
import makeDictionary from '../../utils/make-dictionary';

if (typeof requirejs.entries === 'undefined') {
  requirejs.entries = requirejs._eak_seen;
}

export class ModuleRegistry {
  constructor(entries) {
    this._entries = entries || requirejs.entries;
  }
  moduleNames() {
    return Object.keys(this._entries);
  }
  has(moduleName) {
    return moduleName in this._entries;
  }
  get(moduleName) {
    return require(moduleName);
  }
}

/**
 * This module defines a subclass of Ember.DefaultResolver that adds two
 * important features:
 *
 *  1) The resolver makes the container aware of es6 modules via the AMD
 *     output. The loader's _moduleEntries is consulted so that classes can be
 *     resolved directly via the module loader, without needing a manual
 *     `import`.
 *  2) is able to provide injections to classes that implement `extend`
 *     (as is typical with Ember).
 */

function parseName(fullName) {
  if (fullName.parsedName === true) { return fullName; }

  let prefix, type, name;
  let fullNameParts = fullName.split('@');

  // HTMLBars uses helper:@content-helper which collides
  // with ember-cli namespace detection.
  // This will be removed in a future release of HTMLBars.
  if (fullName !== 'helper:@content-helper' &&
      fullNameParts.length === 2) {
    let prefixParts = fullNameParts[0].split(':');

    if (prefixParts.length === 2) {
      prefix = prefixParts[1];
      type = prefixParts[0];
      name = fullNameParts[1];
    } else {
      let nameParts = fullNameParts[1].split(':');

      prefix = fullNameParts[0];
      type = nameParts[0];
      name = nameParts[1];
    }

    if (type === 'template' && prefix.lastIndexOf('components/', 0) === 0) {
      name = `components/${name}`;
      prefix = prefix.slice(11);
    }
  } else {
    fullNameParts = fullName.split(':');
    type = fullNameParts[0];
    name = fullNameParts[1];
  }

  let fullNameWithoutType = name;
  let namespace = get(this, 'namespace');
  let root = namespace;

  return {
    parsedName: true,
    fullName: fullName,
    prefix: prefix || this.prefix({type: type}),
    type: type,
    fullNameWithoutType: fullNameWithoutType,
    name: name,
    root: root,
    resolveMethodName: "resolve" + classify(type)
  };
}

function resolveOther(parsedName) {
  assert('`modulePrefix` must be defined', this.namespace.modulePrefix);

  let normalizedModuleName = this.findModuleName(parsedName);

  if (normalizedModuleName) {
    let defaultExport = this._extractDefaultExport(normalizedModuleName, parsedName);

    if (defaultExport === undefined) {
      throw new Error(` Expected to find: '${parsedName.fullName}' within '${normalizedModuleName}' but got 'undefined'. Did you forget to 'export default' within '${normalizedModuleName}'?`);
    }

    if (this.shouldWrapInClassFactory(defaultExport, parsedName)) {
      defaultExport = classFactory(defaultExport);
    }

    return defaultExport;
  }
}

const Resolver = EmberObject.extend({
  resolveOther,
  parseName,
  pluralizedTypes: null,
  moduleRegistry: null,

  makeToString(factory, fullName) {
    return '' + this.namespace.modulePrefix + '@' + fullName + ':';
  },

  shouldWrapInClassFactory(/* module, parsedName */){
    return false;
  },

  init() {
    this._super();
    this.moduleBasedResolver = true;

    if (!this._moduleRegistry) {
      this._moduleRegistry = new ModuleRegistry();
    }

    this._normalizeCache = makeDictionary();

    this.pluralizedTypes = this.pluralizedTypes || makeDictionary();

    if (!this.pluralizedTypes.config) {
      this.pluralizedTypes.config = 'config';
    }
    this._deprecatedPodModulePrefix = false;
  },

  normalize(fullName) {
    return this._normalizeCache[fullName] || (this._normalizeCache[fullName] = this._normalize(fullName));
  },

  resolve(fullName) {
    let parsedName = this.parseName(fullName);
    let resolveMethodName = parsedName.resolveMethodName;
    let resolved;

    if (typeof this[resolveMethodName] === 'function') {
      resolved = this[resolveMethodName](parsedName);
    }

    if (resolved == null) {
      resolved = this.resolveOther(parsedName);
    }

    return resolved;
  },

  _normalize(fullName) {
    // A) Convert underscores to dashes
    // B) Convert camelCase to dash-case, except for helpers where we want to avoid shadowing camelCase expressions
    // C) replace `.` with `/` in order to make nested controllers work in the following cases
    //      1. `needs: ['posts/post']`
    //      2. `{{render "posts/post"}}`
    //      3. `this.render('posts/post')` from Route

    let split = fullName.split(':');
    if (split.length > 1) {
      if (split[0] === 'helper') {
        return split[0] + ':' + split[1].replace(/_/g, '-');
      } else {
        return split[0] + ':' + dasherize(split[1].replace(/\./g, '/'));
      }
    } else {
      return fullName;
    }
  },

  pluralize(type) {
    return this.pluralizedTypes[type] || (this.pluralizedTypes[type] = type + 's');
  },

  podBasedLookupWithPrefix(podPrefix, parsedName) {
    let fullNameWithoutType = parsedName.fullNameWithoutType;

    if (parsedName.type === 'template') {
      fullNameWithoutType = fullNameWithoutType.replace(/^components\//, '');
    }

    return podPrefix + '/' + fullNameWithoutType + '/' + parsedName.type;
  },

  podBasedModuleName(parsedName) {
    let podPrefix = this.namespace.podModulePrefix || this.namespace.modulePrefix;

    return this.podBasedLookupWithPrefix(podPrefix, parsedName);
  },

  podBasedComponentsInSubdir(parsedName) {
    let podPrefix = this.namespace.podModulePrefix || this.namespace.modulePrefix;
    podPrefix = podPrefix + '/components';

    if (parsedName.type === 'component' || /^components/.test(parsedName.fullNameWithoutType)) {
      return this.podBasedLookupWithPrefix(podPrefix, parsedName);
    }
  },

  resolveEngine(parsedName) {
    let engineName = parsedName.fullNameWithoutType;
    let engineModule = engineName + '/engine';

    if (this._moduleRegistry.has(engineModule)) {
      return this._extractDefaultExport(engineModule);
    }
  },

  resolveRouteMap(parsedName) {
    let engineName = parsedName.fullNameWithoutType;
    let engineRoutesModule = engineName + '/routes';

    if (this._moduleRegistry.has(engineRoutesModule)) {
      let routeMap = this._extractDefaultExport(engineRoutesModule);

      assert(`The route map for ${engineName} should be wrapped by 'buildRoutes' before exporting.` , routeMap.isRouteMap);

      return routeMap;
    }
  },

  resolveTemplate(parsedName) {
    let resolved = this.resolveOther(parsedName);
    if (resolved == null) {
      resolved = Ember.TEMPLATES[parsedName.fullNameWithoutType];
    }
    return resolved;
  },

  mainModuleName(parsedName) {
    if (parsedName.fullNameWithoutType === 'main') {
      // if router:main or adapter:main look for a module with just the type first
      return parsedName.prefix + '/' + parsedName.type;
    }
  },

  defaultModuleName(parsedName) {
    return parsedName.prefix + '/' +  this.pluralize(parsedName.type) + '/' + parsedName.fullNameWithoutType;
  },

  prefix(parsedName) {
    let tmpPrefix = this.namespace.modulePrefix;

    if (this.namespace[parsedName.type + 'Prefix']) {
      tmpPrefix = this.namespace[parsedName.type + 'Prefix'];
    }

    return tmpPrefix;
  },

  /**

   A listing of functions to test for moduleName's based on the provided
   `parsedName`. This allows easy customization of additional module based
   lookup patterns.

   @property moduleNameLookupPatterns
   @returns {Ember.Array}
   */
  moduleNameLookupPatterns: computed(function(){
    return [
      this.podBasedModuleName,
      this.podBasedComponentsInSubdir,
      this.mainModuleName,
      this.defaultModuleName
    ];
  }).readOnly(),

  findModuleName(parsedName, loggingDisabled){
    let moduleNameLookupPatterns = this.get('moduleNameLookupPatterns');
    let moduleName;

    for (let index = 0, length = moduleNameLookupPatterns.length; index < length; index++) {
      let item = moduleNameLookupPatterns[index];

      let tmpModuleName = item.call(this, parsedName);

      // allow treat all dashed and all underscored as the same thing
      // supports components with dashes and other stuff with underscores.
      if (tmpModuleName) {
        tmpModuleName = this.chooseModuleName(tmpModuleName, parsedName);
      }

      if (tmpModuleName && this._moduleRegistry.has(tmpModuleName)) {
        moduleName = tmpModuleName;
      }

      if (!loggingDisabled) {
        this._logLookup(moduleName, parsedName, tmpModuleName);
      }

      if (moduleName) {
        return moduleName;
      }
    }
  },

  chooseModuleName(moduleName, parsedName) {
    let underscoredModuleName = underscore(moduleName);

    if (moduleName !== underscoredModuleName && this._moduleRegistry.has(moduleName) && this._moduleRegistry.has(underscoredModuleName)) {
      throw new TypeError(`Ambiguous module names: '${ moduleName}' and '${underscoredModuleName }'`);
    }

    if (this._moduleRegistry.has(moduleName)) {
      return moduleName;
    } else if (this._moduleRegistry.has(underscoredModuleName)) {
      return underscoredModuleName;
    }
    // workaround for dasherized partials:
    // something/something/-something => something/something/_something
    let partializedModuleName = moduleName.replace(/\/-([^/]*)$/, '/_$1');

    if (this._moduleRegistry.has(partializedModuleName)) {
      deprecate('Modules should not contain underscores. ' +
      'Attempted to lookup "'+moduleName+'" which ' +
      'was not found. Please rename "'+partializedModuleName+'" '+
      'to "'+moduleName+'" instead.', false,
      { id: 'ember-resolver.underscored-modules', until: '3.0.0' });

      return partializedModuleName;
    }

    if (DEBUG) {
      let isCamelCaseHelper = parsedName.type === 'helper' && /[a-z]+[A-Z]+/.test(moduleName);
      if (isCamelCaseHelper) {
        this._camelCaseHelperWarnedNames = this._camelCaseHelperWarnedNames || [];
        let alreadyWarned = this._camelCaseHelperWarnedNames.indexOf(parsedName.fullName) > -1;
        if (!alreadyWarned && this._moduleRegistry.has(dasherize(moduleName))) {
          this._camelCaseHelperWarnedNames.push(parsedName.fullName);
          warn('Attempted to lookup "' + parsedName.fullName + '" which ' +
          'was not found. In previous versions of ember-resolver, a bug would have ' +
          'caused the module at "' + dasherize(moduleName) + '" to be ' +
          'returned for this camel case helper name. This has been fixed. ' +
          'Use the dasherized name to resolve the module that would have been ' +
          'returned in previous versions.',
          false,
          { id: 'ember-resolver.camelcase-helper-names', until: '3.0.0' });
        }
      }
    }
  },

  // used by Ember.DefaultResolver.prototype._logLookup
  lookupDescription(fullName) {
    let parsedName = this.parseName(fullName);

    let moduleName = this.findModuleName(parsedName, true);

    return moduleName;
  },

  // only needed until 1.6.0-beta.2 can be required
  _logLookup(found, parsedName, description) {
    if (!Ember.ENV.LOG_MODULE_RESOLVER && !parsedName.root.LOG_RESOLVER) {
      return;
    }

    let padding;
    let symbol = found ? '[✓]' : '[ ]';

    if (parsedName.fullName.length > 60) {
      padding = '.';
    } else {
      padding = new Array(60 - parsedName.fullName.length).join('.');
    }

    if (!description) {
      description = this.lookupDescription(parsedName);
    }

    /* eslint-disable no-console */
    if (console && console.info) {
      console.info(symbol, parsedName.fullName, padding, description);
    }
  },

  knownForType(type) {
    let moduleKeys = this._moduleRegistry.moduleNames();

    let items = makeDictionary();
    for (let index = 0, length = moduleKeys.length; index < length; index++) {
      let moduleName = moduleKeys[index];
      let fullname = this.translateToContainerFullname(type, moduleName);

      if (fullname) {
        items[fullname] = true;
      }
    }

    return items;
  },

  translateToContainerFullname(type, moduleName) {
    let prefix = this.prefix({ type });

    // Note: using string manipulation here rather than regexes for better performance.
    // pod modules
    // '^' + prefix + '/(.+)/' + type + '$'
    let podPrefix = prefix + '/';
    let podSuffix = '/' + type;
    let start = moduleName.indexOf(podPrefix);
    let end = moduleName.indexOf(podSuffix);

    if (start === 0 && end === (moduleName.length - podSuffix.length) &&
        moduleName.length > (podPrefix.length + podSuffix.length)) {
      return type + ':' + moduleName.slice(start + podPrefix.length, end);
    }

    // non-pod modules
    // '^' + prefix + '/' + pluralizedType + '/(.+)$'
    let pluralizedType = this.pluralize(type);
    let nonPodPrefix = prefix + '/' + pluralizedType + '/';

    if (moduleName.indexOf(nonPodPrefix) === 0 && moduleName.length > nonPodPrefix.length) {
      return type + ':' + moduleName.slice(nonPodPrefix.length);
    }
  },

  _extractDefaultExport(normalizedModuleName) {
    let module = require(normalizedModuleName, null, null, true /* force sync */);

    if (module && module['default']) {
      module = module['default'];
    }

    return module;
  }
});

Resolver.reopenClass({
  moduleBasedResolver: true
});

export default Resolver;
<|endoftext|>


<commit_before>var Config = (function(url, callback) {
	// var API_URL = "http://192.168.100.200:30003";
	var API_URL = window.location.origin + window.location.pathname.replace(/\/index\.html/, '');

	function getConfig(url, callback){
		$.ajax({
			url: API_URL + url,
			type: 'GET',
			success: function(res) {
				callback(true, res);
			},
			error: function(res) {
				callback(false);
			}
		})
	}

	function setConfig(url, data, callback) {
		$.ajax({
			contentType: 'application/json; charset=UTF-8',
			type: 'POST',
			url: API_URL + url,
			data: JSON.stringify(data),
			dataType: 'json',
			success: function(res) {
				callback(true, res);
			},
			error: function(res) {
				callback(false);
			}
		})
	}

	return {
		getConfig: getConfig,
		setConfig: setConfig
	}
})();
// 检查 url 是否 https
function checkHttps(url) {
	if (url.includes(url)) {
		return true;
	} else {
		return false;
	}
}
// 插件 https insecure
function pluginInsecure(url, callback) {
	$.ajax({
		url: url,
		success: function() {
			callback(true);
		},
		error: function(res) {
			if (res.status === 0) {
				callback(false);
			}
			else {
				callback(true);
			}
		}
	})
}
// 倒计时
function countDown(el, callback) {
	var count = 3;
	var timer = setInterval(function() {
		console.log(count)
		console.log(el);
		$(el).html('(' + count + ')')
		count --;
		if (count === -1) {
			clearInterval(timer);
			callback();
		}
	}, 1000);
}

// 跳转
function changeUrl(url) {
	if (checkHttps(url)) {
		pluginInsecure(url, function(res) {
			if (res) {
				window.location.href = url;
			} else {
				$("#myModal").modal('hide');
				$('#tips').html('如果该页面无法显示，有可能是使用了自定义SSL证书。\
可以打开此页面，接受SSL证书解决');
				countDown($("#count"), function(){
					window.location.href = url;
				});
			}
		})
	} else {
		if (checkHttps(window.location.origin)) {
			$('#tips').html('
无法打开该页面，因为违法了浏览器安全规则。你的浏览器现在正在使用HTTPS，该插件使用了HTTP。
\

请使用HTTP操作DCE，可以在“设置->SSL”将系统调整为不强制使用SSL。
');
		} else {
			window.location.href = url;
		}
	}
}

$().ready(function() {

	Config.getConfig('/plugin.config', function(success, res) {
		if (success && res.WebUrl) {
			changeUrl(res.WebUrl);
		} else {
			$('#myModal').modal('show');
		}
	});

	$('#submit').on('click', function() {
		var webUrl = $('#url').val();
		Config.setConfig('/plugin.config', {
			WebUrl: webUrl
		}, function(success, res) {
			if (success && res.WebUrl) {
				changeUrl(res.WebUrl);
			}
		})
	})
})
<commit_msg>修改了倒计时的界面呈现，修改了部分错误<commit_after>var Config = (function(url, callback) {
	// var API_URL = "http://192.168.100.200:30003";
	var API_URL = window.location.origin + window.location.pathname.replace(/\/index\.html/, '');

	function getConfig(url, callback){
		$.ajax({
			url: API_URL + url,
			type: 'GET',
			success: function(res) {
				callback(true, res);
			},
			error: function(res) {
				callback(false);
			}
		})
	}

	function setConfig(url, data, callback) {
		$.ajax({
			contentType: 'application/json; charset=UTF-8',
			type: 'POST',
			url: API_URL + url,
			data: JSON.stringify(data),
			dataType: 'json',
			success: function(res) {
				callback(true, res);
			},
			error: function(res) {
				callback(false);
			}
		})
	}

	return {
		getConfig: getConfig,
		setConfig: setConfig
	}
})();
// 检查 url 是否 https
function checkHttps(url) {
	if (url.includes('https://')) {
		return true;
	} else {
		return false;
	}
}
// 插件 https insecure
function pluginInsecure(url, callback) {
	$.ajax({
		url: url,
		success: function() {
			callback(true);
		},
		error: function(res) {
			if (res.status === 0) {
				callback(false);
			} else {
				callback(true);
			}
		}
	})
}
// 倒计时
function countDown(el, callback) {
	var count = 2;
	var timer = setInterval(function() {
		$(el).html('(' + count + ')')
		count --;
		if (count === -1) {
			clearInterval(timer);
			callback();
		}
	}, 1000);
}

// 跳转
function changeUrl(url) {
	if (!checkHttps(url)) {
		pluginInsecure(url, function(res) {
			if (res) {
				window.location.href = url;
			} else {
				$("#myModal").modal('hide');
				var tips = $('
3
\

如果无法显示。可以打开此页面，接受 SSL 证书解决。
');

				$('#tips').append(tips);
				countDown($("#count"), function(){
					window.location.href = url;
				});
			}
		})
	} else {
		if (checkHttps(window.location.origin)) {
			$('#tips').html('
无法打开该页面，因为违法了浏览器安全规则。你的浏览器现在正在使用HTTPS，该插件使用了HTTP。
\

请使用HTTP操作DCE，可以在“设置->SSL”将系统调整为不强制使用SSL。
');
		} else {
			window.location.href = url;
		}
	}
}

$().ready(function() {

	Config.getConfig('/plugin.config', function(success, res) {
		if (success && res.WebUrl) {
			changeUrl(res.WebUrl);
		} else {
			$('#myModal').modal('show');
		}
	});

	$('#submit').on('click', function() {
		var webUrl = $('#url').val();
		Config.setConfig('/plugin.config', {
			WebUrl: webUrl
		}, function(success, res) {
			if (success && res.WebUrl) {
				changeUrl(res.WebUrl);
			}
		})
	})
})
<|endoftext|>


<commit_before>// first find which runs have built data in them, sorted
// built :: [Int]
var built = function(){
  var seen = {};
  for (var i = 0; i < shake.length; i++)
    seen[shake[i].built] = true;
  var seen2 = [];
  for (var i in seen)
    seen2.push(i);
  return seen2.sort(function cmp(a,b){return a-b;});
}();

// what is the index of the last build run
// lastRun :: Int
var lastRun = built.length == 0 ? 0 : built[built.length-1];

function showTime(x){return x.toFixed(2) + "s";}
function showPerc(x){return (x*100).toFixed(2) + "%";}
function showShort(x){return x;}

function plural(n,not1,is1){
  return n == 1
    ? (is1 == undefined ? "" : is1)
    : (not1 == undefined ? "s" : not1);
}

function listEq(xs, ys)
{
  if (xs.length != ys.length) return false;
  for (var i = 0; i < xs.length; i++)
    if (xs[i] != ys[i]) return false;
  return true;
}

// Return the n top entries, grouping as necessary by words
// huffman :: Int -> [{sum :: Double, name :: String}] -> [{sum :: Double, count :: Int, name :: String}]
function huffman(resultSize, xs)
{
  var val = {sum: 0, count: 0, children: {}};

  for (var i = 0; i < xs.length; i++)
  {
    var val2 = val;
    var ys = xs[i].name.split(' ');
    for (var j = 0; j < ys.length; j++)
    {
      if (val2.children[ys[j]])
        val2 = val2.children[ys[j]];
      else
      {
        var t = {sum: 0, count: 0, children: {}};
        val2.children[ys[j]] = t;
        val2 = t;
      }
      val2.sum += xs[i].sum;
      val2.count++;
    }
  }

  function compress(val) // return the number of items
  {
    var n = 0;
    for (var j in val.children)
      n += compress(val.children[j]);
    if (n == 1)
      val.children = {};
    return Math.max(1,n);
  }
  compress(val);

  function flatten(path, val, res)
  {
    for (var i in val.children)
    {
      var ii = val.children[i];
      var pp = path.slice(0);
      pp.push(i);
      res.push({sum:ii.sum, count:ii.count, name:pp, free:path.length==0});
      flatten(pp,ii,res);
    }
  }
  var flat = [];
  flatten([], val, flat);

  while(true)
  {
    // order everything
    flat.sort(function(a,b){var i = b.sum - a.sum; return i != 0 ? i : b.count - a.count;});

    // now, if something in the first n is not free, mark it free and delete anyone who relies on it
    // then repeat, if nothing is not free, break
    var cont = false;
    for (var i = 0; i < Math.min(resultSize, flat.length); i++)
    {
      if (!flat[i].free)
      {
        cont = true;
        flat[i].free = true;
        for (var j = 0; j < flat.length; j++)
        {
          if (listEq(flat[i].name.slice(0,flat[i].name.length-1), flat[j].name))
          {
            flat[j].count -= flat[i].count;
            flat[j].sum -= flat[i].sum;
          }
        }
        break;
      }
    }
    if (!cont) break;
  }

  for (var i = 0; i < flat.length; i++)
    flat[i].name = flat[i].name.join(" ");
  return flat.slice(0, resultSize);
}

function load()
{
  /////////////////////////////////////////////////////////////////
  // SUMMARY INFORMATION

  var countLast = 0;
  var sumExecution = 0;
  var maxExecution = 0;
  var countTrace = 0, countTraceLast = 0;
  var sumTrace = 0;
  var maxTrace = 0;
  var maxTraceStopLast = 0;
  for (var i = 0; i < shake.length; i++)
  {
    var isLast = shake[i].built == lastRun;
    countLast += isLast ? 1 : 0;
    sumExecution += shake[i].execution;
    maxExecution = Math.max(maxExecution, shake[i].execution);
    var traces = shake[i].traces;
    if (!traces) continue;
    for (var j = 0; j < traces.length; j++)
    {
      countTrace += 1;
      countTraceLast += isLast ? 1 : 0;
      sumTrace += traces[j].stop - traces[j].start;
      maxTrace = Math.max(maxTrace, traces[j].stop - traces[j].start);
      maxTraceStopLast = Math.max(maxTraceStopLast, isLast ? traces[j].stop : 0);
    }
  }

  var summary =
    "
" +
    "
Runs: This database has tracked " + built.length + " run" + plural(built.length) + ".
" +
    "
Rules: There are " + shake.length + " rules (" + countLast + " rebuilt in the last run).
" +
    "
Commands: Building required " + countTrace + " traced commands (" + countTraceLast + " in the last run).
" +
    "
Build time: The total (unparallelised) build time is " + showTime(sumExecution) + " of which " + showTime(sumTrace) + " is traced commands.
" +
    "
Longest steps: The longest rule takes " + showTime(maxExecution) + ", and the longest traced command takes " + showTime(maxTrace) + ".
" +
    "
Parallelism: Last run gave an average parallelism of " + (sumTrace / maxTraceStopLast).toFixed(2) + " times over " + showTime(maxTraceStopLast) + ".
" +
    "
";
  $('#summary').append(summary);

  /////////////////////////////////////////////////////////////////
  // PARALLELISM GRAPH

  var buckets = [];
  var countBuckets = 100;
  for (var i = 0; i <= countBuckets; i++)
    buckets.push(0); // fill with 1 more element, but the last bucket will always be 0

  for (var i = 0; i < shake.length; i++)
  {
    var traces = shake[i].traces;
    if (!traces || shake[i].built != lastRun) continue;
    for (var j = 0; j < traces.length; j++)
    {
      var start = traces[j].start * countBuckets / maxTraceStopLast;
      var stop = traces[j].stop * countBuckets / maxTraceStopLast;

      if (Math.floor(start) == Math.floor(stop))
        buckets[Math.floor(start)] += stop - start;
      else
      {
        for (var k = Math.ceil(start); k < Math.floor(stop); k++)
          buckets[k]++;
        buckets[Math.floor(start)] += Math.ceil(start) - start;
        buckets[Math.floor(stop)] += stop - Math.floor(stop);
      }
    }
  }
  var maxBucket = 0;
  for (var i = 0; i < countBuckets; i++)
    maxBucket = Math.max(maxBucket, buckets[i]);
  maxBucket = Math.ceil(maxBucket - 0.00001);

  plotvals = [];
  for (var i = 0; i < countBuckets; i++)
    plotvals.push([i, (buckets[i] * 100 / maxBucket)]);
  $.plot($('#shakeplot'), [{color: '#5EB95E', data: plotvals}]);

  /////////////////////////////////////////////////////////////////
  // MOST EXPENSIVE RULES

  var top = shake.slice(0).sort(function(a,b){return b.execution-a.execution}).slice(0,15);
  var rules = "
";
  for (var i = 0; i < top.length; i++)
  {
    rules += "
" +
      "
" +
      "

	" +
      "" + showTime(top[i].execution) + "	" +
      "" + showPerc(top[i].execution / sumExecution) + "	" +
      "" + top[i].name + "	" +
      "
";
  }
  rules += "
";
  $('#rule-details').append(rules);

  /////////////////////////////////////////////////////////////////
  // MOST EXPENSIVE COMMANDS

  var tooList = [];
  for (var i = 0; i < shake.length; i++)
  {
    var traces = shake[i].traces;
    if (!traces) continue;
    for (var j = 0; j < traces.length; j++)
      tooList.push({name: traces[j].command, sum: traces[j].stop - traces[j].start});
  }

  toolList = huffman(15, tooList);
  var commands = "
";
  for (var i = 0; i < toolList.length; i++)
  {
    commands += "
" +
      "
" +
      "

	" +
      "" + showTime(toolList[i].sum) + "	" +
      "" + showPerc(toolList[i].sum / sumExecution) + "	" +
      "" + toolList[i].count + " ×	" +
      "" + toolList[i].name + "	" +
      "
";
  }
  commands += "
";
  $('#cmd-details').append(commands);

  /////////////////////////////////////////////////////////////////
  // REBUILD COSTS

  $('#rebuild-details').append(rebuildCost());
}

function rebuildCost()
{
    // first try and order the commands
    var done = {};
    var list = [];
    while (list.length < shake.length)
    {
        var start = list.length;
        for (var i = 0; i < shake.length; i++)
        {
            var deps = shake[i].depends;
            var good = !(i in done);
            for (var j = 0; j < deps.length; j++)
                good = good && (deps[j] in done);
            if (good)
            {
                list.push(i);
                done[i] = true;
            }
        }
        if (start === list.length)
            break; // failed due to cycle
    }

    // now find out how expensive each one is
    var costs = [];
    for (var i = 0; i < list.length; i++)
    {
        var seen = {};
        seen[list[i]] = true;
        var tot = shake[list[i]].execution;
        for (var j = i + 1; j < list.length; j++)
        {
            var deps = shake[list[j]].depends;
            var dep = false;
            for (var k = 0; k < deps.length; k++)
                dep = dep || (deps[k] in seen);
            if (dep)
            {
                seen[list[j]] = true;
                tot += shake[list[j]].execution;
            }
        }
        costs.push({name: shake[list[i]].name, cost: tot});
    }
    costs.sort(function(a,b){return b.cost-a.cost;});

    var res = "
";
    for (var i = 0; i < Math.min(15,costs.length); i++)
    {
      res += "
" +
        "
" +
        "

	" +
        "" + showTime(costs[i].cost) + "	" + costs[i].name + "
";
    }
    res += "
";
    return res;
}
<commit_msg>Redo the indentation in the Javascript<commit_after>// first find which runs have built data in them, sorted
// built :: [Int]
var built = function(){
    var seen = {};
    for (var i = 0; i < shake.length; i++)
        seen[shake[i].built] = true;
    var seen2 = [];
    for (var i in seen)
        seen2.push(i);
    return seen2.sort(function cmp(a,b){return a-b;});
}();

// what is the index of the last build run
// lastRun :: Int
var lastRun = built.length == 0 ? 0 : built[built.length-1];

function showTime(x){return x.toFixed(2) + "s";}
function showPerc(x){return (x*100).toFixed(2) + "%";}
function showShort(x){return x;}

function plural(n,not1,is1){
    return n == 1
        ? (is1 == undefined ? "" : is1)
        : (not1 == undefined ? "s" : not1);
}

function listEq(xs, ys)
{
    if (xs.length != ys.length) return false;
    for (var i = 0; i < xs.length; i++)
        if (xs[i] != ys[i]) return false;
    return true;
}

// Return the n top entries, grouping as necessary by words
// huffman :: Int -> [{sum :: Double, name :: String}] -> [{sum :: Double, count :: Int, name :: String}]
function huffman(resultSize, xs)
{
    var val = {sum: 0, count: 0, children: {}};

    for (var i = 0; i < xs.length; i++)
    {
        var val2 = val;
        var ys = xs[i].name.split(' ');
        for (var j = 0; j < ys.length; j++)
        {
            if (val2.children[ys[j]])
                val2 = val2.children[ys[j]];
            else
            {
                var t = {sum: 0, count: 0, children: {}};
                val2.children[ys[j]] = t;
                val2 = t;
            }
            val2.sum += xs[i].sum;
            val2.count++;
        }
    }

    function compress(val) // return the number of items
    {
        var n = 0;
        for (var j in val.children)
            n += compress(val.children[j]);
        if (n == 1)
            val.children = {};
        return Math.max(1,n);
    }
    compress(val);

    function flatten(path, val, res)
    {
        for (var i in val.children)
        {
            var ii = val.children[i];
            var pp = path.slice(0);
            pp.push(i);
            res.push({sum:ii.sum, count:ii.count, name:pp, free:path.length==0});
            flatten(pp,ii,res);
        }
    }
    var flat = [];
    flatten([], val, flat);

    while(true)
    {
        // order everything
        flat.sort(function(a,b){var i = b.sum - a.sum; return i != 0 ? i : b.count - a.count;});

        // now, if something in the first n is not free, mark it free and delete anyone who relies on it
        // then repeat, if nothing is not free, break
        var cont = false;
        for (var i = 0; i < Math.min(resultSize, flat.length); i++)
        {
            if (!flat[i].free)
            {
                cont = true;
                flat[i].free = true;
                for (var j = 0; j < flat.length; j++)
                {
                    if (listEq(flat[i].name.slice(0,flat[i].name.length-1), flat[j].name))
                    {
                        flat[j].count -= flat[i].count;
                        flat[j].sum -= flat[i].sum;
                    }
                }
                break;
            }
        }
        if (!cont) break;
    }

    for (var i = 0; i < flat.length; i++)
        flat[i].name = flat[i].name.join(" ");
    return flat.slice(0, resultSize);
}

function load()
{
  /////////////////////////////////////////////////////////////////
  // SUMMARY INFORMATION

    var countLast = 0;
    var sumExecution = 0;
    var maxExecution = 0;
    var countTrace = 0, countTraceLast = 0;
    var sumTrace = 0;
    var maxTrace = 0;
    var maxTraceStopLast = 0;
    for (var i = 0; i < shake.length; i++)
    {
        var isLast = shake[i].built == lastRun;
        countLast += isLast ? 1 : 0;
        sumExecution += shake[i].execution;
        maxExecution = Math.max(maxExecution, shake[i].execution);
        var traces = shake[i].traces;
        if (!traces) continue;
        for (var j = 0; j < traces.length; j++)
        {
            countTrace += 1;
            countTraceLast += isLast ? 1 : 0;
            sumTrace += traces[j].stop - traces[j].start;
            maxTrace = Math.max(maxTrace, traces[j].stop - traces[j].start);
            maxTraceStopLast = Math.max(maxTraceStopLast, isLast ? traces[j].stop : 0);
        }
    }

    var summary =
        "
" +
        "
Runs: This database has tracked " + built.length + " run" + plural(built.length) + ".
" +
        "
Rules: There are " + shake.length + " rules (" + countLast + " rebuilt in the last run).
" +
        "
Commands: Building required " + countTrace + " traced commands (" + countTraceLast + " in the last run).
" +
        "
Build time: The total (unparallelised) build time is " + showTime(sumExecution) + " of which " + showTime(sumTrace) + " is traced commands.
" +
        "
Longest steps: The longest rule takes " + showTime(maxExecution) + ", and the longest traced command takes " + showTime(maxTrace) + ".
" +
        "
Parallelism: Last run gave an average parallelism of " + (sumTrace / maxTraceStopLast).toFixed(2) + " times over " + showTime(maxTraceStopLast) + ".
" +
        "
";
    $('#summary').append(summary);

    /////////////////////////////////////////////////////////////////
    // PARALLELISM GRAPH

    var buckets = [];
    var countBuckets = 100;
    for (var i = 0; i <= countBuckets; i++)
        buckets.push(0); // fill with 1 more element, but the last bucket will always be 0

    for (var i = 0; i < shake.length; i++)
    {
        var traces = shake[i].traces;
        if (!traces || shake[i].built != lastRun) continue;
        for (var j = 0; j < traces.length; j++)
        {
            var start = traces[j].start * countBuckets / maxTraceStopLast;
            var stop = traces[j].stop * countBuckets / maxTraceStopLast;

            if (Math.floor(start) == Math.floor(stop))
                buckets[Math.floor(start)] += stop - start;
            else
            {
                for (var k = Math.ceil(start); k < Math.floor(stop); k++)
                    buckets[k]++;
                buckets[Math.floor(start)] += Math.ceil(start) - start;
                buckets[Math.floor(stop)] += stop - Math.floor(stop);
            }
        }
    }
    var maxBucket = 0;
    for (var i = 0; i < countBuckets; i++)
        maxBucket = Math.max(maxBucket, buckets[i]);
    maxBucket = Math.ceil(maxBucket - 0.00001);

    plotvals = [];
    for (var i = 0; i < countBuckets; i++)
        plotvals.push([i, (buckets[i] * 100 / maxBucket)]);
    $.plot($('#shakeplot'), [{color: '#5EB95E', data: plotvals}]);

    /////////////////////////////////////////////////////////////////
    // MOST EXPENSIVE RULES

    var top = shake.slice(0).sort(function(a,b){return b.execution-a.execution}).slice(0,15);
    var rules = "
";
    for (var i = 0; i < top.length; i++)
    {
        rules += "
" +
            "
" +
            "

	" +
            "" + showTime(top[i].execution) + "	" +
            "" + showPerc(top[i].execution / sumExecution) + "	" +
            "" + top[i].name + "	" +
            "
";
    }
    rules += "
";
    $('#rule-details').append(rules);

    /////////////////////////////////////////////////////////////////
    // MOST EXPENSIVE COMMANDS

    var tooList = [];
    for (var i = 0; i < shake.length; i++)
    {
        var traces = shake[i].traces;
        if (!traces) continue;
        for (var j = 0; j < traces.length; j++)
            tooList.push({name: traces[j].command, sum: traces[j].stop - traces[j].start});
    }

    toolList = huffman(15, tooList);
    var commands = "
";
    for (var i = 0; i < toolList.length; i++)
    {
        commands += "
" +
            "
" +
            "

	" +
            "" + showTime(toolList[i].sum) + "	" +
            "" + showPerc(toolList[i].sum / sumExecution) + "	" +
            "" + toolList[i].count + " ×	" +
            "" + toolList[i].name + "	" +
            "
";
    }
    commands += "
";
    $('#cmd-details').append(commands);

    /////////////////////////////////////////////////////////////////
    // REBUILD COSTS

    $('#rebuild-details').append(rebuildCost());
}

function rebuildCost()
{
    // first try and order the commands
    var done = {};
    var list = [];
    while (list.length < shake.length)
    {
        var start = list.length;
        for (var i = 0; i < shake.length; i++)
        {
            var deps = shake[i].depends;
            var good = !(i in done);
            for (var j = 0; j < deps.length; j++)
                good = good && (deps[j] in done);
            if (good)
            {
                list.push(i);
                done[i] = true;
            }
        }
        if (start === list.length)
            break; // failed due to cycle
    }

    // now find out how expensive each one is
    var costs = [];
    for (var i = 0; i < list.length; i++)
    {
        var seen = {};
        seen[list[i]] = true;
        var tot = shake[list[i]].execution;
        for (var j = i + 1; j < list.length; j++)
        {
            var deps = shake[list[j]].depends;
            var dep = false;
            for (var k = 0; k < deps.length; k++)
                dep = dep || (deps[k] in seen);
            if (dep)
            {
                seen[list[j]] = true;
                tot += shake[list[j]].execution;
            }
        }
        costs.push({name: shake[list[i]].name, cost: tot});
    }
    costs.sort(function(a,b){return b.cost-a.cost;});

    var res = "
";
    for (var i = 0; i < Math.min(15,costs.length); i++)
    {
      res += "
" +
        "
" +
        "

	" +
        "" + showTime(costs[i].cost) + "	" + costs[i].name + "
";
    }
    res += "
";
    return res;
}
<|endoftext|>


<commit_before>(function(){

	const $ = (_q) => document.querySelectorAll(_q);
	const $v = (_q) => {
		const _$ = $(_q);
		const len = _$.length;
		console.log(len);
		if(!len)
		{
			return null;
		}
		const i = len - 1;
		return _$[i].text || _$[i].src || _$[i].href || _$[i].content
	};

	const LINK = "//erikccoder.github.io/markdown-web-note/index.html"
	const selection = window.getSelection().toString();
	const author = $v('meta[name="author"], meta[name="twitter:creator"], meta[property="article:author"]');
	const description = selection
						? selection
						: $v('meta[name="description"], meta[name="twitter:description"], meta[property="og:description"]');
	const image0 = $v('meta[name="twitter:image"], meta[property="og:image"]');
	const image = image0 ? image0 : $v('img');
	const keywords = $v('meta[name="keywords"]');
	const link = $v('link[rel="canonical"], meta[property="og:url"]') || window.location.href;
	const time = $v('meta[property="article:published_time"]');
	const title0 = $v('title, meta[name="twitter:title"], meta[property="og:title"]');
	const title = title0 ? title0.trim() : title0;
	const video = $v('meta[property="og:video"], meta[property="og:video:url"]');
	const tags = keywords
				 ?  '\n -' + keywords.replace(/,\ /g, ',').split(',').join('\n- ')
				 : null;

	const data = {
		link,
		author,
		image,
		time,
		title,
		video,
		tags
	};
	let str = `------\n`;
	Object.keys(data).forEach( k =>
	{
		if(data[k]) str += `${k}: ${data[k]}\n`
	});
	str += `------\n\n`;

	if(title){
		str += `# ${title}\n`;
	}
	if(description){
		str += `${description}\n\n`;
	}
	if(image){
		str += `![image](${image})\n\n`;
	}

	str += `${link}\n`;

	const markdown = encodeURIComponent(btoa(unescape(encodeURIComponent(str))));
	const fileName = location.pathname.replace(/\/$/g, '').split('/').pop();

	console.log({image});

	// return;
	setTimeout(()=>{
		location = `${LINK}?file=${fileName}&content=${markdown}`
	},0)

})()
<commit_msg>Update bookmarklet.js<commit_after>(function(){

	const $ = (_q) => document.querySelectorAll(_q);
	const $v = (_q) => {
		const _$ = $(_q);
		const len = _$.length;
		console.log(len);
		if(!len)
		{
			return null;
		}
		const i = len - 1;
		return _$[i].text || _$[i].src || _$[i].href || _$[i].content
	};

	const DEBUG = window.markdownWebNoteDebug;

	const LINK = "//erikccoder.github.io/markdown-web-note/index.html"
	const selection = window.getSelection().toString();
	const author = $v('meta[name="author"], meta[name="twitter:creator"], meta[property="article:author"]');
	const description = selection
						? selection
						: $v('meta[name="description"], meta[name="twitter:description"], meta[property="og:description"]');
	const image0 = $v('meta[name="twitter:image"], meta[property="og:image"]');
	const image = image0 ? image0 : $v('img');
	const keywords = $v('meta[name="keywords"]');
	const link = $v('link[rel="canonical"], meta[property="og:url"]') || window.location.href;
	const time = $v('meta[property="article:published_time"]');
	const title0 = $v('title, meta[name="twitter:title"], meta[property="og:title"]');
	const title = title0 ? title0.trim() : title0;
	const video = $v('meta[property="og:video"], meta[property="og:video:url"]');
	const tags = keywords
				 ?  '\n -' + keywords.replace(/,\ /g, ',').split(',').join('\n- ')
				 : null;

	const data = {
		link,
		author,
		image,
		time,
		title,
		video,
		tags
	};
	let str = `------\n`;
	Object.keys(data).forEach( k =>
	{
		if(data[k]) str += `${k}: ${data[k]}\n`
	});
	str += `------\n\n`;

	if(title){
		str += `# ${title}\n`;
	}
	if(description){
		str += `${description}\n\n`;
	}
	if(image){
		str += `![image](${image})\n\n`;
	}

	str += `${link}\n`;

	const markdown = encodeURIComponent(btoa(unescape(encodeURIComponent(str))));
	const fileName = location.pathname.replace(/\/$/g, '').split('/').pop();

	// return;
	setTimeout(()=>{
		location = DEBUG
					? `${LINK}?file=${fileName}&content=${markdown}`
					: `${LINK}?DEBUG=1&file=${fileName}&content=${markdown}`
	},0)

})()
<|endoftext|>


<commit_before>var http = require('http');
var __request = http.request;
exports.request = __request;

var proxy = {
    host: '',
    port: 0
};

var _debug = false;

http.request = function (options, callback) {
    var __options = options;
    __options.path = 'http://' + options.host + options.path;
    __options.host = proxy.host;
    __options.port = proxy.port;
    if (_debug) {
        console.log('=== http-proxy.js begin debug ===');
        console.log(JSON.stringify(__options, null, 2));
        console.log('=== http-proxy.js end debug ===');
    }
    var req = __request(__options, function (res) {
        callback(res);
    });
    return req;
};

module.exports = function (host, port, debug) {
    proxy.host = host;
    proxy.port = port;
    _debug = debug || false;
};<commit_msg>Fixed proxy problems<commit_after><|endoftext|>


<commit_before>'use strict';
var url = require('url');
var React = require('react/addons');
var ValidationMixin = require('react-validation-mixin');
var Joi = require('joi');
var nets = require('nets');
var Scene = require('../components/scene');
var Dropdown = require('../components/dropdown');
var apiUrl = require('../config.js').OAMUploaderApi;
var AppActions = require('../actions/app-actions');
var $ = require('jquery');

// Sanity note:
// There are some places where the component state is being altered directly.
// This happens because of javascript objects work. Ex:
//   onSceneValueChange: function (sceneIndex, fieldName, fieldValue) {
//     var scenes = this.state.scenes;
//     scenes[sceneIndex][fieldName] = fieldValue;
//     this.setState({scenes: scenes});
//   },
// The solution would be to clone the state every time, but since we're
// ALWAYS calling setState after one of these changes, it's not a problem.
// It's still an antipattern, but I know what I'm doing! :)

module.exports = React.createClass({
  displayName: 'Home',

  mixins: [ValidationMixin],

  validatorTypes: {
    'uploader-name': Joi.string().label('Name').required(),
    'uploader-token': Joi.string().required().hex().length(64).label('Token'),
    'uploader-email': Joi.string().email().label('Email'),

    'scenes': Joi.array().items(
      Joi.object().keys({
        'title': Joi.string().min(1).required().label('Title'),
        'platform-type': Joi.string().required().valid('satellite', 'aircraft', 'uav', 'ballon', 'kite'),
        'sensor': Joi.string().allow('').label('Sensor'),
        'date-start': Joi.date().required().label('Date start'),
        'date-end': Joi.date().min(Joi.ref('date-start')).max('now').required().label('Date End'),

        'img-loc': Joi.array().min(1).items(
          Joi.object().keys({
            url: Joi.string().required().label('Imagery url'),
            origin: Joi.string().required().label('Imagery file origin')
          })
        ).label('Imagery location'),

        'tile-url': Joi.string().allow('').label('Tile service'),
        'provider': Joi.string().required().label('Provider'),
        'contact-type': Joi.string().required().valid('uploader', 'other'),
        'contact-name': Joi.label('Name').when('contact-type', { is: 'other', then: Joi.string().required() }),
        'contact-email': Joi.label('Email').when('contact-type', { is: 'other', then: Joi.string().email().required() })
      })
    )
  },

  getInitialState: function () {
    if (process.env.DS_DEBUG) {
      return {
        loading: false,

        // Form properties.
        'uploader-token': '',
        'uploader-name': 'Dummy Dum Dum',
        'uploader-email': 'zimmy@fake.com',
        scenes: [
          this.getSceneDataTemplate()
        ]
      };
    }

    return {
      loading: false,

      // Form properties.
      'uploader-token': '',
      'uploader-name': '',
      'uploader-email': '',
      scenes: [
        this.getSceneDataTemplate()
      ]
    };
  },

  getSceneDataTemplate: function () {
    var midnight = new Date();
    midnight.setMilliseconds(0);
    midnight.setSeconds(0);
    midnight.setMinutes(0);
    midnight.setHours(0);
    var now = new Date();

    if (process.env.DS_DEBUG) {
      return {
        'title': 'An imaginary scene',
        'platform-type': 'satellite',
        'sensor': 'x',
        'date-start': midnight.toISOString(),
        'date-end': now.toISOString(),
        'img-loc': [this.getSceneImgLocTemplate()],
        'tile-url': '',
        'provider': 'Mocks R Us',
        'contact-type': 'uploader',
        'contact-name': '',
        'contact-email': ''
      };
    }

    return {
      'platform-type': 'satellite',
      'sensor': '',
      'date-start': midnight.toISOString(),
      'date-end': now.toISOString(),
      'img-loc': [],
      'tile-url': '',
      'provider': '',
      'contact-type': 'uploader',
      'contact-name': '',
      'contact-email': ''
    };
  },

  getSceneImgLocTemplate: function () {
    if (process.env.DS_DEBUG) {
      return {
        url: 'http://fake-imagery.net/fake.tif',
        origin: 'manual'
      };
    }

    return {
      url: '',
      origin: ''
    };
  },

  addScene: function () {
    var scenes = this.state.scenes;
    scenes.push(this.getSceneDataTemplate());
    this.setState({scenes: scenes});
  },

  removeScene: function (sceneIndex) {
    var scenes = this.state.scenes;
    scenes.splice(sceneIndex, 1);
    this.setState({scenes: scenes});
  },

  addImageryLocationToScene: function (sceneIndex, origin) {
    let scenes = this.state.scenes;
    let tmp = this.getSceneImgLocTemplate();
    tmp.origin = origin;
    scenes[sceneIndex]['img-loc'].push(tmp);
    this.setState({scenes: scenes});
  },

  removeImageryLocatioFromScene: function (sceneIndex, imgLocIndex) {
    var scenes = this.state.scenes;
    scenes[sceneIndex]['img-loc'].splice(imgLocIndex, 1);
    this.setState({scenes: scenes});
  },

  onSceneValueChange: function (sceneIndex, fieldName, fieldValue) {
    var scenes = this.state.scenes;
    scenes[sceneIndex][fieldName] = fieldValue;
    this.setState({scenes: scenes});
  },

  onValueChange: function (event) {
    var data = {};
    data[event.target.name] = event.target.value;
    this.setState(data);
  },

  resetForm: function () {
    this.setState({
      'uploader-token': null,
      'uploader-name': null,
      'uploader-email': null,
      scenes: [
        this.getSceneDataTemplate()
      ]
    });
  },

  onSubmit: function (event) {
    event.preventDefault();

    // Warning... Controlled HACK.
    // The state should never be changed in this way as it doesn't trigger
    // a render, however it will be updated by the validate function later on.
    // This is needed to clear previous errors as the plugin doesn't handle
    // arrays of objects specially well.
    this.state.errors = {}; // eslint-disable-line

    this.validate(function (error, validationErrors) {
      if (error) {
        console.log(validationErrors);
        AppActions.showNotification('alert', 'Form contains errors!');
        this.scrollToError();
      } else {
        if (this.state.loading) {
          // Submit already in process.
          return;
        }
        this.setState({loading: true});

        AppActions.clearNotification();

        // All is well.
        // SUBMIT DATA.
        //
        // 1 - Prepare data in state.
        // 2 - Submit.
        // 3 - Set form feedback with -- this.setFormFeedback(type, message);
        //   - TYPE can be: alert success warning info
        // 4 - Hide loading. -- this.setState({loading: false});
        // 5 - Reset form when success. -- this.resetForm();

        var token = this.state['uploader-token'];

        var uploader = {
          name: this.state['uploader-name'],
          email: this.state['uploader-email']
        };
        var data = {
          uploader: uploader,
          scenes: this.state.scenes.map(function (scene) {
            var other = scene['contact-type'] === 'other';
            var contact = {
              name: other ? scene['contact-name'] : uploader.name,
              email: other ? scene['contact-email'] : uploader.email
            };

            var tms = scene['tile-url'].trim();
            tms = tms.length === 0 ? undefined : tms;

            return {
              contact: contact,
              title: scene.title,
              provider: scene.provider,
              platform: scene['platform-type'],
              sensor: scene.sensor,
              acquisition_start: scene['date-start'],
              acquisition_end: scene['date-end'],
              tms: tms,
              urls: scene['img-loc'].map(o => o.url)
            };
          })
        };
        console.log('valid', data);

        nets({
          url: url.resolve(apiUrl, '/uploads?access_token=' + token),
          method: 'POST',
          body: JSON.stringify(data),
          headers: {
            'Content-Type': 'application/json'
          }
        }, function (err, resp, body) {
          if (err) {
            console.error('error', err);
          }
          this.setState({loading: false});

          if (resp.statusCode >= 200 && resp.statusCode < 400) {
            var id = JSON.parse(body.toString()).upload;

            AppActions.showNotification('success', (

                Your upload request was successfully submitted and is being processed. Check upload status.

            ));

            this.resetForm();
          } else {
            var message = null;
            if (resp.statusCode === 401) {
              message = (
                The provided token is not valid.
              );
            } else {
              message = (

                  There was a problem with the request.

              );
              console.log(body);
            }

            AppActions.showNotification('alert', message);
          }
        }.bind(this));
      }
    }.bind(this));
  },

  scrollToError: function () {
    var topPos = $('.message-alert').first().offset().top;
    $('html').animate({ scrollTop: topPos - 50 });
  },

  renderErrorMessage: function (message) {
    message = message || '';
    if (message.trim().length === 0) { return null; }

    return (

{message}

    );
  },

  renderScene: function (data, index) {
    return (
      <Scene
        key={index}
        total={this.state.scenes.length}
        index={index} data={data}
        onValueChange={this.onSceneValueChange}
        removeScene={this.removeScene}

        addImageryLocationToScene={this.addImageryLocationToScene}
        removeImageryLocatioFromScene={this.removeImageryLocatioFromScene}

        handleValidation={this.handleValidation}
        getValidationMessages={this.getValidationMessages}
        renderErrorMessage={this.renderErrorMessage} />
    );
  },

  render: function () {
    return (

Welcome to the OpenAerialMap Imagery Uploader.
 Use the form below to submit your imagery - a valid upload token is needed. Read the documentation to learn how to contribute.

          <Dropdown element='div' className='drop dropdown center' triggerTitle='Request a token' triggerClassName='bttn-request-token' triggerText='Request a token'>

Open GitHub issue

Send email

          </Dropdown>

Upload

            <form id='upload-form' className='form-horizontal'>

              <fieldset className='form-fieldset general'>
                <legend className='form-legend'>General</legend>

                  Token

                    <input type='password' className='form-control' placeholder='Key' name='uploader-token' id='uploader-token' onBlur={this.handleValidation('uploader-token')} onChange={this.onValueChange} value={this.state['uploader-token']} />
                    {this.renderErrorMessage(this.getValidationMessages('uploader-token')[0])}

                  Uploader name

                    <input type='text' className='form-control' placeholder='Name' name='uploader-name' id='uploader-name' onBlur={this.handleValidation('uploader-name')} onChange={this.onValueChange} value={this.state['uploader-name']} />
                    {this.renderErrorMessage(this.getValidationMessages('uploader-name')[0])}

                Uploader email

                    <input type='email' className='form-control' placeholder='Email' name='uploader-email' id='uploader-email' onBlur={this.handleValidation('uploader-email')} onChange={this.onValueChange} value={this.state['uploader-email']} />
                    {this.renderErrorMessage(this.getValidationMessages('uploader-email')[0])}

              </fieldset>

              {this.state.scenes.map(this.renderScene)}

                <button type='button' className='bttn-add-scene' onClick={this.addScene} title='Add new dataset'>New dataset</button>

By submitting imagery to OpenAerialMap, you agree to place your imagery into the Open Imagery Network (OIN). All imagery contained in OIN is licensed CC-BY 4.0, with attribution as contributors of Open Imagery Network. All imagery is available to be traced in OpenStreetMap.

                <button type='submit' className='bttn-submit' onClick={this.onSubmit}>Submit</button>

            </form>

        {this.state.loading ?
Loading
 : null}

    );
  }
});
<commit_msg>switch to info@oam email<commit_after>'use strict';
var url = require('url');
var React = require('react/addons');
var ValidationMixin = require('react-validation-mixin');
var Joi = require('joi');
var nets = require('nets');
var Scene = require('../components/scene');
var Dropdown = require('../components/dropdown');
var apiUrl = require('../config.js').OAMUploaderApi;
var AppActions = require('../actions/app-actions');
var $ = require('jquery');

// Sanity note:
// There are some places where the component state is being altered directly.
// This happens because of javascript objects work. Ex:
//   onSceneValueChange: function (sceneIndex, fieldName, fieldValue) {
//     var scenes = this.state.scenes;
//     scenes[sceneIndex][fieldName] = fieldValue;
//     this.setState({scenes: scenes});
//   },
// The solution would be to clone the state every time, but since we're
// ALWAYS calling setState after one of these changes, it's not a problem.
// It's still an antipattern, but I know what I'm doing! :)

module.exports = React.createClass({
  displayName: 'Home',

  mixins: [ValidationMixin],

  validatorTypes: {
    'uploader-name': Joi.string().label('Name').required(),
    'uploader-token': Joi.string().required().hex().length(64).label('Token'),
    'uploader-email': Joi.string().email().label('Email'),

    'scenes': Joi.array().items(
      Joi.object().keys({
        'title': Joi.string().min(1).required().label('Title'),
        'platform-type': Joi.string().required().valid('satellite', 'aircraft', 'uav', 'ballon', 'kite'),
        'sensor': Joi.string().allow('').label('Sensor'),
        'date-start': Joi.date().required().label('Date start'),
        'date-end': Joi.date().min(Joi.ref('date-start')).max('now').required().label('Date End'),

        'img-loc': Joi.array().min(1).items(
          Joi.object().keys({
            url: Joi.string().required().label('Imagery url'),
            origin: Joi.string().required().label('Imagery file origin')
          })
        ).label('Imagery location'),

        'tile-url': Joi.string().allow('').label('Tile service'),
        'provider': Joi.string().required().label('Provider'),
        'contact-type': Joi.string().required().valid('uploader', 'other'),
        'contact-name': Joi.label('Name').when('contact-type', { is: 'other', then: Joi.string().required() }),
        'contact-email': Joi.label('Email').when('contact-type', { is: 'other', then: Joi.string().email().required() })
      })
    )
  },

  getInitialState: function () {
    if (process.env.DS_DEBUG) {
      return {
        loading: false,

        // Form properties.
        'uploader-token': '',
        'uploader-name': 'Dummy Dum Dum',
        'uploader-email': 'zimmy@fake.com',
        scenes: [
          this.getSceneDataTemplate()
        ]
      };
    }

    return {
      loading: false,

      // Form properties.
      'uploader-token': '',
      'uploader-name': '',
      'uploader-email': '',
      scenes: [
        this.getSceneDataTemplate()
      ]
    };
  },

  getSceneDataTemplate: function () {
    var midnight = new Date();
    midnight.setMilliseconds(0);
    midnight.setSeconds(0);
    midnight.setMinutes(0);
    midnight.setHours(0);
    var now = new Date();

    if (process.env.DS_DEBUG) {
      return {
        'title': 'An imaginary scene',
        'platform-type': 'satellite',
        'sensor': 'x',
        'date-start': midnight.toISOString(),
        'date-end': now.toISOString(),
        'img-loc': [this.getSceneImgLocTemplate()],
        'tile-url': '',
        'provider': 'Mocks R Us',
        'contact-type': 'uploader',
        'contact-name': '',
        'contact-email': ''
      };
    }

    return {
      'platform-type': 'satellite',
      'sensor': '',
      'date-start': midnight.toISOString(),
      'date-end': now.toISOString(),
      'img-loc': [],
      'tile-url': '',
      'provider': '',
      'contact-type': 'uploader',
      'contact-name': '',
      'contact-email': ''
    };
  },

  getSceneImgLocTemplate: function () {
    if (process.env.DS_DEBUG) {
      return {
        url: 'http://fake-imagery.net/fake.tif',
        origin: 'manual'
      };
    }

    return {
      url: '',
      origin: ''
    };
  },

  addScene: function () {
    var scenes = this.state.scenes;
    scenes.push(this.getSceneDataTemplate());
    this.setState({scenes: scenes});
  },

  removeScene: function (sceneIndex) {
    var scenes = this.state.scenes;
    scenes.splice(sceneIndex, 1);
    this.setState({scenes: scenes});
  },

  addImageryLocationToScene: function (sceneIndex, origin) {
    let scenes = this.state.scenes;
    let tmp = this.getSceneImgLocTemplate();
    tmp.origin = origin;
    scenes[sceneIndex]['img-loc'].push(tmp);
    this.setState({scenes: scenes});
  },

  removeImageryLocatioFromScene: function (sceneIndex, imgLocIndex) {
    var scenes = this.state.scenes;
    scenes[sceneIndex]['img-loc'].splice(imgLocIndex, 1);
    this.setState({scenes: scenes});
  },

  onSceneValueChange: function (sceneIndex, fieldName, fieldValue) {
    var scenes = this.state.scenes;
    scenes[sceneIndex][fieldName] = fieldValue;
    this.setState({scenes: scenes});
  },

  onValueChange: function (event) {
    var data = {};
    data[event.target.name] = event.target.value;
    this.setState(data);
  },

  resetForm: function () {
    this.setState({
      'uploader-token': null,
      'uploader-name': null,
      'uploader-email': null,
      scenes: [
        this.getSceneDataTemplate()
      ]
    });
  },

  onSubmit: function (event) {
    event.preventDefault();

    // Warning... Controlled HACK.
    // The state should never be changed in this way as it doesn't trigger
    // a render, however it will be updated by the validate function later on.
    // This is needed to clear previous errors as the plugin doesn't handle
    // arrays of objects specially well.
    this.state.errors = {}; // eslint-disable-line

    this.validate(function (error, validationErrors) {
      if (error) {
        console.log(validationErrors);
        AppActions.showNotification('alert', 'Form contains errors!');
        this.scrollToError();
      } else {
        if (this.state.loading) {
          // Submit already in process.
          return;
        }
        this.setState({loading: true});

        AppActions.clearNotification();

        // All is well.
        // SUBMIT DATA.
        //
        // 1 - Prepare data in state.
        // 2 - Submit.
        // 3 - Set form feedback with -- this.setFormFeedback(type, message);
        //   - TYPE can be: alert success warning info
        // 4 - Hide loading. -- this.setState({loading: false});
        // 5 - Reset form when success. -- this.resetForm();

        var token = this.state['uploader-token'];

        var uploader = {
          name: this.state['uploader-name'],
          email: this.state['uploader-email']
        };
        var data = {
          uploader: uploader,
          scenes: this.state.scenes.map(function (scene) {
            var other = scene['contact-type'] === 'other';
            var contact = {
              name: other ? scene['contact-name'] : uploader.name,
              email: other ? scene['contact-email'] : uploader.email
            };

            var tms = scene['tile-url'].trim();
            tms = tms.length === 0 ? undefined : tms;

            return {
              contact: contact,
              title: scene.title,
              provider: scene.provider,
              platform: scene['platform-type'],
              sensor: scene.sensor,
              acquisition_start: scene['date-start'],
              acquisition_end: scene['date-end'],
              tms: tms,
              urls: scene['img-loc'].map(o => o.url)
            };
          })
        };
        console.log('valid', data);

        nets({
          url: url.resolve(apiUrl, '/uploads?access_token=' + token),
          method: 'POST',
          body: JSON.stringify(data),
          headers: {
            'Content-Type': 'application/json'
          }
        }, function (err, resp, body) {
          if (err) {
            console.error('error', err);
          }
          this.setState({loading: false});

          if (resp.statusCode >= 200 && resp.statusCode < 400) {
            var id = JSON.parse(body.toString()).upload;

            AppActions.showNotification('success', (

                Your upload request was successfully submitted and is being processed. Check upload status.

            ));

            this.resetForm();
          } else {
            var message = null;
            if (resp.statusCode === 401) {
              message = (
                The provided token is not valid.
              );
            } else {
              message = (

                  There was a problem with the request.

              );
              console.log(body);
            }

            AppActions.showNotification('alert', message);
          }
        }.bind(this));
      }
    }.bind(this));
  },

  scrollToError: function () {
    var topPos = $('.message-alert').first().offset().top;
    $('html').animate({ scrollTop: topPos - 50 });
  },

  renderErrorMessage: function (message) {
    message = message || '';
    if (message.trim().length === 0) { return null; }

    return (

{message}

    );
  },

  renderScene: function (data, index) {
    return (
      <Scene
        key={index}
        total={this.state.scenes.length}
        index={index} data={data}
        onValueChange={this.onSceneValueChange}
        removeScene={this.removeScene}

        addImageryLocationToScene={this.addImageryLocationToScene}
        removeImageryLocatioFromScene={this.removeImageryLocatioFromScene}

        handleValidation={this.handleValidation}
        getValidationMessages={this.getValidationMessages}
        renderErrorMessage={this.renderErrorMessage} />
    );
  },

  render: function () {
    return (

Welcome to the OpenAerialMap Imagery Uploader.
 Use the form below to submit your imagery - a valid upload token is needed. Read the documentation to learn how to contribute.

          <Dropdown element='div' className='drop dropdown center' triggerTitle='Request a token' triggerClassName='bttn-request-token' triggerText='Request a token'>

Open GitHub issue

Send email

          </Dropdown>

Upload

            <form id='upload-form' className='form-horizontal'>

              <fieldset className='form-fieldset general'>
                <legend className='form-legend'>General</legend>

                  Token

                    <input type='password' className='form-control' placeholder='Key' name='uploader-token' id='uploader-token' onBlur={this.handleValidation('uploader-token')} onChange={this.onValueChange} value={this.state['uploader-token']} />
                    {this.renderErrorMessage(this.getValidationMessages('uploader-token')[0])}

                  Uploader name

                    <input type='text' className='form-control' placeholder='Name' name='uploader-name' id='uploader-name' onBlur={this.handleValidation('uploader-name')} onChange={this.onValueChange} value={this.state['uploader-name']} />
                    {this.renderErrorMessage(this.getValidationMessages('uploader-name')[0])}

                Uploader email

                    <input type='email' className='form-control' placeholder='Email' name='uploader-email' id='uploader-email' onBlur={this.handleValidation('uploader-email')} onChange={this.onValueChange} value={this.state['uploader-email']} />
                    {this.renderErrorMessage(this.getValidationMessages('uploader-email')[0])}

              </fieldset>

              {this.state.scenes.map(this.renderScene)}

                <button type='button' className='bttn-add-scene' onClick={this.addScene} title='Add new dataset'>New dataset</button>

By submitting imagery to OpenAerialMap, you agree to place your imagery into the Open Imagery Network (OIN). All imagery contained in OIN is licensed CC-BY 4.0, with attribution as contributors of Open Imagery Network. All imagery is available to be traced in OpenStreetMap.

                <button type='submit' className='bttn-submit' onClick={this.onSubmit}>Submit</button>

            </form>

        {this.state.loading ?
Loading
 : null}

    );
  }
});
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import style from './PresetSelector.css';

export default class PresetSelector extends Component {
    static propTypes = {
        options: PropTypes.array.isRequired,
        preset: PropTypes.string,
        disabled: PropTypes.bool,
        setPreset: PropTypes.func.isRequired,
    };

    handleChange = (evt) => {
        const { index, setPreset } = this.props;

        setPreset(evt.target.value);
    };

    render() {
        const { options, preset, disabled } = this.props;

        return (
            <select className={style.select} onChange={this.handleChange} value={preset} disabled={disabled}>
                <option value="">Manual</option>
                {options.map((option) =>
                    <option key={option.name} value={option.name}>{option.name}</option>
                )}
            </select>
        );
    }
}
<commit_msg>Add select separator<commit_after>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import style from './PresetSelector.css';

export default class PresetSelector extends Component {
    static propTypes = {
        options: PropTypes.array.isRequired,
        preset: PropTypes.string,
        disabled: PropTypes.bool,
        setPreset: PropTypes.func.isRequired,
    };

    handleChange = (evt) => {
        const { index, setPreset } = this.props;

        setPreset(evt.target.value);
    };

    render() {
        const { options, preset, disabled } = this.props;

        return (
            <select className={style.select} onChange={this.handleChange} value={preset} disabled={disabled}>
                <option value="">Manual</option>
                <option disabled="disabled">──────────</option>
                {options.map((option) =>
                    <option key={option.name} value={option.name}>{option.name}</option>
                )}
            </select>
        );
    }
}
<|endoftext|>


<commit_before>/**
 * Created by stefas on 09/03/15.
 */
angular.module('myApp.controllers')
    .controller('CommonCtrl', ['$scope', '$http','defaults', 'Session', '$rootScope', 'camomileService', '$resource', '$cookieStore',
        function ($scope, $http, defaults, Session, $rootScope, camomileService, $resource, $cookieStore) {

            'use strict';

            delete $http.defaults.headers.common['X-Requested-With'];

            $scope.model = {};
            $scope.model.absUrl = $rootScope.absUrl;

            var useDefaultVideoPath = $cookieStore.get("use.default.video.path") || true;
            var videoPath = $cookieStore.get("video.path")||"";

            $scope.model.useDefaultVideoPath = useDefaultVideoPath;
            $scope.model.videoPath = videoPath;

            var config = $resource($rootScope.absUrl + '/config');

            // Use callbacks to store in $rootScope
            config.get().$promise.then(function (data) {
                $rootScope.dataroot = data.camomile_api;
                $rootScope.toolroot = data.pyannote_api;
                $rootScope.queues = data.queues;

                camomileService.setURL($rootScope.dataroot);

                camomileService.me(function(err, data)
                {
                    $scope.$apply(function(){
                        if(data.error)
                        {
                            Session.isLogged = false;
                            Session.username = undefined;
                            $scope.model.message = undefined;
                        }
                        else
                        {
                            Session.isLogged = true;
                            Session.username = data.username;
                            $scope.model.message = "Connected as " + Session.username;
                        }
                    });
                });
            });

            // test if user is logged or not
            $scope.isLogged = function () {
                return Session.isLogged;
            };

            // URL for video
            $scope.model.video = "";

            function f_filterResults(n_win, n_docel, n_body) {
                var n_result = n_win ? n_win : 0;
                if (n_docel && (!n_result || (n_result > n_docel)))
                    n_result = n_docel;
                return n_body && (!n_result || (n_result > n_body)) ? n_body : n_result;
            }

            // get the client height
            $scope.f_clientHeight = function () {
                return f_filterResults(
                    window.innerHeight ? window.innerHeight : 0,
                    document.documentElement ? document.documentElement.clientHeight : 0,
                    document.body ? document.body.clientHeight : 0
                );
            };

            // get the client width
            $scope.f_clientWidth = function () {
                return f_filterResults(
                    window.innerWidth ? window.innerWidth : 0,
                    document.documentElement ? document.documentElement.clientWidth : 0,
                    document.body ? document.body.clientWidth : 0
                );
            };

            $scope.model.edit_click = function () {
                $scope.model.edit_flag = true;
            };

            $scope.model.debugProbe = function () {
                console.log("probe called");
            };

            // hide contextmenu if clicked anywhere but on relevant targets
            $("body").on("click", function () {
                $("#contextMenu").hide().find("li").removeClass("disabled").children().css({
                    "pointer-events": "auto"
                });
            });

        }]);<commit_msg>fix: useDefaultVideoPath was always set to True<commit_after>/**
 * Created by stefas on 09/03/15.
 */
angular.module('myApp.controllers')
    .controller('CommonCtrl', ['$scope', '$http','defaults', 'Session', '$rootScope', 'camomileService', '$resource', '$cookieStore',
        function ($scope, $http, defaults, Session, $rootScope, camomileService, $resource, $cookieStore) {

            'use strict';

            delete $http.defaults.headers.common['X-Requested-With'];

            $scope.model = {};
            $scope.model.absUrl = $rootScope.absUrl;

            var useDefaultVideoPath = $cookieStore.get("use.default.video.path");
            if (useDefaultVideoPath === undefined) useDefaultVideoPath = true;
            var videoPath = $cookieStore.get("video.path") || "";

            $scope.model.useDefaultVideoPath = useDefaultVideoPath;
            $scope.model.videoPath = videoPath;

            var config = $resource($rootScope.absUrl + '/config');

            // Use callbacks to store in $rootScope
            config.get().$promise.then(function (data) {
                $rootScope.dataroot = data.camomile_api;
                $rootScope.toolroot = data.pyannote_api;
                $rootScope.queues = data.queues;

                camomileService.setURL($rootScope.dataroot);

                camomileService.me(function(err, data)
                {
                    $scope.$apply(function(){
                        if(data.error)
                        {
                            Session.isLogged = false;
                            Session.username = undefined;
                            $scope.model.message = undefined;
                        }
                        else
                        {
                            Session.isLogged = true;
                            Session.username = data.username;
                            $scope.model.message = "Connected as " + Session.username;
                        }
                    });
                });
            });

            // test if user is logged or not
            $scope.isLogged = function () {
                return Session.isLogged;
            };

            // URL for video
            $scope.model.video = "";

            function f_filterResults(n_win, n_docel, n_body) {
                var n_result = n_win ? n_win : 0;
                if (n_docel && (!n_result || (n_result > n_docel)))
                    n_result = n_docel;
                return n_body && (!n_result || (n_result > n_body)) ? n_body : n_result;
            }

            // get the client height
            $scope.f_clientHeight = function () {
                return f_filterResults(
                    window.innerHeight ? window.innerHeight : 0,
                    document.documentElement ? document.documentElement.clientHeight : 0,
                    document.body ? document.body.clientHeight : 0
                );
            };

            // get the client width
            $scope.f_clientWidth = function () {
                return f_filterResults(
                    window.innerWidth ? window.innerWidth : 0,
                    document.documentElement ? document.documentElement.clientWidth : 0,
                    document.body ? document.body.clientWidth : 0
                );
            };

            $scope.model.edit_click = function () {
                $scope.model.edit_flag = true;
            };

            $scope.model.debugProbe = function () {
                console.log("probe called");
            };

            // hide contextmenu if clicked anywhere but on relevant targets
            $("body").on("click", function () {
                $("#contextMenu").hide().find("li").removeClass("disabled").children().css({
                    "pointer-events": "auto"
                });
            });

        }]);<|endoftext|>