<commit_before>/**
 * @flow
 */

import _ from 'lodash';
import ExtendableError from 'es6-error';
import QueryString from 'querystring';
import axios from 'axios';
import idx from 'idx';

import Config from './Config';

import logger from './Logger';

import type { User } from './User';

// These aren't constants because some commands switch between staging and prod
function _rootBaseUrl() {
  return `${Config.api.scheme}://${Config.api.host}`;
}

function _apiBaseUrl() {
  let rootBaseUrl = _rootBaseUrl();
  if (Config.api.port) {
    rootBaseUrl += ':' + Config.api.port;
  }
  return rootBaseUrl + '/--/api/v2';
}

export class ApiV2Error extends ExtendableError {
  code: string;
  details: Object;
  serverStack: ?string;

  constructor(message: string, code: string = 'UNKNOWN') {
    super(message);
    this.code = code;
    this._isApiError = true;
  }
}

type RequestOptions = {
  httpMethod: 'get' | 'post' | 'put',
  queryParameters?: ?QueryParameters,
  body?: ?Object,
  json?: boolean,
};

type QueryParameters = { [key: string]: ?(string | number | boolean) };

type ErrorWithResponseBody = Error & {
  responseBody?: any,
};

type APIV2ClientOptions = {
  sessionSecret?: string,
};

export default class ApiV2Client {
  sessionSecret: ?string = null;

  static clientForUser(user: ?User): ApiV2Client {
    if (user) {
      return new ApiV2Client({
        sessionSecret: user.sessionSecret,
      });
    }

    return new ApiV2Client();
  }

  constructor(options: APIV2ClientOptions = {}) {
    if (options.sessionSecret) {
      this.sessionSecret = options.sessionSecret;
    }
  }

  async getAsync(
    methodName: string,
    args: QueryParameters = {},
    extraOptions: Object = {},
    returnEntireResponse: boolean = false
  ): Promise<*> {
    return this._requestAsync(
      methodName,
      {
        httpMethod: 'get',
        queryParameters: args,
        json: true,
      },
      extraOptions,
      returnEntireResponse
    );
  }

  async postAsync(
    methodName: string,
    data: Object = {},
    extraOptions: Object = {},
    returnEntireResponse: boolean = false
  ): Promise<*> {
    return this._requestAsync(
      methodName,
      {
        httpMethod: 'post',
        body: data,
      },
      extraOptions,
      returnEntireResponse
    );
  }

  async putAsync(
    methodName: string,
    data: Object = {},
    extraOptions: Object = {},
    returnEntireResponse: boolean = false
  ): Promise<*> {
    return this._requestAsync(
      methodName,
      {
        httpMethod: 'put',
        body: data,
      },
      extraOptions,
      returnEntireResponse
    );
  }

  async deleteAsync(
    methodName: string,
    data: Object = {},
    extraOptions: Object = {},
    returnEntireResponse: boolean = false
  ): Promise<*> {
    return this._requestAsync(
      methodName,
      {
        httpMethod: 'delete',
        body: data,
      },
      extraOptions,
      returnEntireResponse
    );
  }

  async _requestAsync(
    methodName: string,
    options: RequestOptions,
    extraRequestOptions: Object,
    returnEntireResponse: boolean = false
  ): Promise<*> {
    const url = `${_apiBaseUrl()}/${methodName}`;
    let reqOptions: Object = {
      url,
      method: options.httpMethod,
      headers: {
        'Exponent-Client': 'xdl',
      },
      json: typeof options.json !== 'undefined' ? options.json : false,
    };

    if (this.sessionSecret) {
      reqOptions.headers['Expo-Session'] = this.sessionSecret;
    }

    // Handle qs
    if (options.queryParameters) {
      reqOptions.params = options.queryParameters;
      reqOptions.paramsSerializer = QueryString.stringify;
    }

    // Handle body
    if (options.body) {
      reqOptions.data = options.body;
    }

    reqOptions = _.merge({}, reqOptions, extraRequestOptions);
    let response;
    let result;
    try {
      response = await axios.request(reqOptions);
      result = response.data;
    } catch (e) {
      // axios errors on 400's, pass this case to better error handling downstream
      const maybeErrorData = idx(e, _ => _.response.data.errors.length);
      if (maybeErrorData) {
        result = e.response.data;
      } else if (e.code === 'ECONNREFUSED' || e.code === 'ENOTFOUND' || e.code === 'ETIMEDOUT') {
        // surface network failures
        throw e;
      } else {
        const error: ErrorWithResponseBody = new Error(
          `There was a problem understanding the server. Please try again.`
        );
        error.responseBody = result;
        logger.error(error);
        throw error;
      }
    }

    if (!result || typeof result !== 'object') {
      let error: ErrorWithResponseBody = new Error(`There was a problem understanding the server.`);
      error.responseBody = result;
      throw error;
    }

    if (result.errors && result.errors.length) {
      let responseError = result.errors[0];
      let error = new ApiV2Error(responseError.message, responseError.code);
      error.serverStack = responseError.stack;
      error.details = responseError.details;
      throw error;
    }

    return returnEntireResponse ? response : result.data;
  }
}
<commit_msg>bubble all socket error codes as otherwise some errors are hard to debug<commit_after>/**
 * @flow
 */

import _ from 'lodash';
import ExtendableError from 'es6-error';
import QueryString from 'querystring';
import axios from 'axios';
import idx from 'idx';

import Config from './Config';

import type { User } from './User';

// These aren't constants because some commands switch between staging and prod
function _rootBaseUrl() {
  return `${Config.api.scheme}://${Config.api.host}`;
}

function _apiBaseUrl() {
  let rootBaseUrl = _rootBaseUrl();
  if (Config.api.port) {
    rootBaseUrl += ':' + Config.api.port;
  }
  return rootBaseUrl + '/--/api/v2';
}

export class ApiV2Error extends ExtendableError {
  code: string;
  details: Object;
  serverStack: ?string;

  constructor(message: string, code: string = 'UNKNOWN') {
    super(message);
    this.code = code;
    this._isApiError = true;
  }
}

type RequestOptions = {
  httpMethod: 'get' | 'post' | 'put',
  queryParameters?: ?QueryParameters,
  body?: ?Object,
  json?: boolean,
};

type QueryParameters = { [key: string]: ?(string | number | boolean) };

type APIV2ClientOptions = {
  sessionSecret?: string,
};

export default class ApiV2Client {
  sessionSecret: ?string = null;

  static clientForUser(user: ?User): ApiV2Client {
    if (user) {
      return new ApiV2Client({
        sessionSecret: user.sessionSecret,
      });
    }

    return new ApiV2Client();
  }

  constructor(options: APIV2ClientOptions = {}) {
    if (options.sessionSecret) {
      this.sessionSecret = options.sessionSecret;
    }
  }

  async getAsync(
    methodName: string,
    args: QueryParameters = {},
    extraOptions: Object = {},
    returnEntireResponse: boolean = false
  ): Promise<*> {
    return this._requestAsync(
      methodName,
      {
        httpMethod: 'get',
        queryParameters: args,
        json: true,
      },
      extraOptions,
      returnEntireResponse
    );
  }

  async postAsync(
    methodName: string,
    data: Object = {},
    extraOptions: Object = {},
    returnEntireResponse: boolean = false
  ): Promise<*> {
    return this._requestAsync(
      methodName,
      {
        httpMethod: 'post',
        body: data,
      },
      extraOptions,
      returnEntireResponse
    );
  }

  async putAsync(
    methodName: string,
    data: Object = {},
    extraOptions: Object = {},
    returnEntireResponse: boolean = false
  ): Promise<*> {
    return this._requestAsync(
      methodName,
      {
        httpMethod: 'put',
        body: data,
      },
      extraOptions,
      returnEntireResponse
    );
  }

  async deleteAsync(
    methodName: string,
    data: Object = {},
    extraOptions: Object = {},
    returnEntireResponse: boolean = false
  ): Promise<*> {
    return this._requestAsync(
      methodName,
      {
        httpMethod: 'delete',
        body: data,
      },
      extraOptions,
      returnEntireResponse
    );
  }

  async _requestAsync(
    methodName: string,
    options: RequestOptions,
    extraRequestOptions: Object,
    returnEntireResponse: boolean = false
  ): Promise<*> {
    const url = `${_apiBaseUrl()}/${methodName}`;
    let reqOptions: Object = {
      url,
      method: options.httpMethod,
      headers: {
        'Exponent-Client': 'xdl',
      },
      json: typeof options.json !== 'undefined' ? options.json : false,
    };

    if (this.sessionSecret) {
      reqOptions.headers['Expo-Session'] = this.sessionSecret;
    }

    // Handle qs
    if (options.queryParameters) {
      reqOptions.params = options.queryParameters;
      reqOptions.paramsSerializer = QueryString.stringify;
    }

    // Handle body
    if (options.body) {
      reqOptions.data = options.body;
    }

    reqOptions = _.merge({}, reqOptions, extraRequestOptions);
    let response;
    let result;
    try {
      response = await axios.request(reqOptions);
      result = response.data;
    } catch (e) {
      // axios errors on 400's, pass this case to better error handling downstream
      const maybeErrorData = idx(e, _ => _.response.data.errors.length);
      if (maybeErrorData) {
        result = e.response.data;
        if (!result || typeof result !== 'object') {
          throw e;
        }
      } else {
        throw e;
      }
    }

    if (result.errors && result.errors.length) {
      let responseError = result.errors[0];
      let error = new ApiV2Error(responseError.message, responseError.code);
      error.serverStack = responseError.stack;
      error.details = responseError.details;
      throw error;
    }

    return returnEntireResponse ? response : result.data;
  }
}
<|endoftext|>


<commit_before>(function() {
  'use strict';

  angular
    .module('bowyer', ['ui.router', 'ngMaterial']);

})();
<commit_msg>Update app.module.js<commit_after>(function() {
  'use strict';

  angular
    .module('bowyer', ['ui.router', 'ngMaterial']);

})();
(function() {
  'use strict';
  angular
    .module('starterApp')
    .config(configBlock);
  function configBlock($mdThemingProvider) {
      $mdThemingProvider.definePalette('white', {
        '50': 'ffffff',
        '100': 'ffffff',
        '200': 'ffffff',
        '300': 'ffffff',
        '400': 'ffffff',
        '500': 'ffffff',
        '600': 'ffffff',
        '700': 'ffffff',
        '800': 'ffffff',
        '900': 'ffffff',
        'A100': 'ffffff',
        'A200': 'ffffff',
        'A400': 'ffffff',
        'A700': 'ffffff',
        'contrastDefaultColor': '1D628B',    // whether, by default, text (contrast)
                                            // on this palette should be dark or light
        'contrastDarkColors': ['50', '100', //hues which contrast should be 'dark' by default
        '200', '300', '400', 'A100'],
        'contrastLightColors': '1D628B'    // could also specify this if default was 'dark'
    });
    $mdThemingProvider.theme('bowyer')
        .primaryPalette('white')
        .accentPalette('amber');
    $mdThemingProvider.setDefaultTheme('bowyer');
  }
})();
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * FileGrid constructor.
 *
 * Represents grid for the Grid View in the File Manager.
 * @constructor
 * @extends {cr.ui.Grid}
 */

function FileGrid() {
  throw new Error('Use FileGrid.decorate');
}

/**
 * Inherits from cr.ui.Grid.
 */
FileGrid.prototype.__proto__ = cr.ui.Grid.prototype;

/**
 * Decorates an HTML element to be a FileGrid.
 * @param {!Element} self The grid to decorate.
 * @param {!MetadataModel} metadataModel File system metadata.
 * @param {VolumeManagerWrapper} volumeManager Volume manager instance.
 * @param {!importer.HistoryLoader} historyLoader
 */
FileGrid.decorate = function(
    self, metadataModel, volumeManager, historyLoader) {
  cr.ui.Grid.decorate(self);
  self.__proto__ = FileGrid.prototype;
  self.metadataModel_ = metadataModel;
  self.volumeManager_ = volumeManager;
  self.historyLoader_ = historyLoader;

  /** @private {ListThumbnailLoader} */
  self.listThumbnailLoader_ = null;

  /** @private {number} */
  self.beginIndex_ = 0;

  /** @private {number} */
  self.endIndex_ = 0;

  /**
   * Reflects the visibility of import status in the UI.  Assumption: import
   * status is only enabled in import-eligible locations.  See
   * ImportController#onDirectoryChanged.  For this reason, the code in this
   * class checks if import status is visible, and if so, assumes that all the
   * files are in an import-eligible location.
   * TODO(kenobi): Clean this up once import status is queryable from metadata.
   *
   * @private {boolean}
   */
  self.importStatusVisible_ = true;

  /** @private {function(!Event)} */
  self.onThumbnailLoadedBound_ = self.onThumbnailLoaded_.bind(self);

  self.scrollBar_ = new ScrollBar();
  self.scrollBar_.initialize(self.parentElement, self);

  self.itemConstructor = function(entry) {
    var item = self.ownerDocument.createElement('li');
    FileGrid.Item.decorate(
        item,
        entry,
        /** @type {FileGrid} */ (self));
    return item;
  };

  self.relayoutRateLimiter_ =
      new AsyncUtil.RateLimiter(self.relayoutImmediately_.bind(self));
};

/**
 * Sets list thumbnail loader.
 * @param {ListThumbnailLoader} listThumbnailLoader A list thumbnail loader.
 * @private
 */
FileGrid.prototype.setListThumbnailLoader = function(listThumbnailLoader) {
  if (this.listThumbnailLoader_) {
    this.listThumbnailLoader_.removeEventListener(
        'thumbnailLoaded', this.onThumbnailLoadedBound_);
  }

  this.listThumbnailLoader_ = listThumbnailLoader;

  if (this.listThumbnailLoader_) {
    this.listThumbnailLoader_.addEventListener(
        'thumbnailLoaded', this.onThumbnailLoadedBound_);
    this.listThumbnailLoader_.setHighPriorityRange(
        this.beginIndex_, this.endIndex_);
  }
};

/**
 * Handles thumbnail loaded event.
 * @param {!Event} event An event.
 * @private
 */
FileGrid.prototype.onThumbnailLoaded_ = function(event) {
  var listItem = this.getListItemByIndex(event.index);
  if (listItem) {
    var box = listItem.querySelector('.img-container');
    if (box) {
      FileGrid.setThumbnailImage_(
          assertInstanceof(box, HTMLDivElement),
          event.dataUrl,
          /* should animate */ true);
    }
  }
};

/**
 * @override
 */
FileGrid.prototype.mergeItems = function(beginIndex, endIndex) {
  cr.ui.Grid.prototype.mergeItems.call(this, beginIndex, endIndex);

  // Make sure that grid item's selected attribute is updated just after the
  // mergeItems operation is done. This prevents shadow of selected grid items
  // from being animated unintentionally by redraw.
  for (var i = beginIndex; i < endIndex; i++) {
    var item = this.getListItemByIndex(i);
    if (!item)
      continue;
    var isSelected = this.selectionModel.getIndexSelected(i);
    if (item.selected != isSelected)
      item.selected = isSelected;
  }

  // Keep these values to set range when a new list thumbnail loader is set.
  this.beginIndex_ = beginIndex;
  this.endIndex_ = endIndex;
  if (this.listThumbnailLoader_ !== null)
    this.listThumbnailLoader_.setHighPriorityRange(beginIndex, endIndex);
};

/**
 * @override
 */
FileGrid.prototype.createSelectionController = function(sm) {
  return new FileGridSelectionController(assert(sm), this);
};

/**
 * Updates items to reflect metadata changes.
 * @param {string} type Type of metadata changed.
 * @param {Array.<Entry>} entries Entries whose metadata changed.
 */
FileGrid.prototype.updateListItemsMetadata = function(type, entries) {
  var urls = util.entriesToURLs(entries);
  var boxes = this.querySelectorAll('.img-container');
  for (var i = 0; i < boxes.length; i++) {
    var box = boxes[i];
    var listItem = this.getListItemAncestor(box);
    var entry = listItem && this.dataModel.item(listItem.listIndex);
    if (!entry || urls.indexOf(entry.toURL()) === -1)
      continue;

    this.decorateThumbnailBox_(assertInstanceof(box, HTMLDivElement), entry);
  }
};

/**
 * Redraws the UI. Skips multiple consecutive calls.
 */
FileGrid.prototype.relayout = function() {
  this.relayoutRateLimiter_.run();
};

/**
 * Redraws the UI immediately.
 * @private
 */
FileGrid.prototype.relayoutImmediately_ = function() {
  this.startBatchUpdates();
  this.columns = 0;
  this.redraw();
  this.endBatchUpdates();
  cr.dispatchSimpleEvent(this, 'relayout');
};

/**
 * Decorates thumbnail.
 * @param {cr.ui.ListItem} li List item.
 * @param {!Entry} entry Entry to render a thumbnail for.
 * @private
 */
FileGrid.prototype.decorateThumbnail_ = function(li, entry) {
  li.className = 'thumbnail-item';
  if (entry)
    filelist.decorateListItem(li, entry, this.metadataModel_);

  var frame = li.ownerDocument.createElement('div');
  frame.className = 'thumbnail-frame';
  li.appendChild(frame);

  var box = li.ownerDocument.createElement('div');
  if (entry) {
    this.decorateThumbnailBox_(assertInstanceof(box, HTMLDivElement), entry);
  }
  frame.appendChild(box);

  var active_checkmark = li.ownerDocument.createElement('div');
  active_checkmark.className = 'checkmark active';
  frame.appendChild(active_checkmark);
  var inactive_checkmark = li.ownerDocument.createElement('div');
  inactive_checkmark.className = 'checkmark inactive';
  frame.appendChild(inactive_checkmark);

  var bottom = li.ownerDocument.createElement('div');
  bottom.className = 'thumbnail-bottom';
  var badge = li.ownerDocument.createElement('div');
  badge.className = 'badge';
  bottom.appendChild(badge);
  bottom.appendChild(filelist.renderFileTypeIcon(li.ownerDocument, entry));
  bottom.appendChild(filelist.renderFileNameLabel(li.ownerDocument, entry));
  frame.appendChild(bottom);
};

/**
 * Decorates the box containing a centered thumbnail image.
 *
 * @param {!HTMLDivElement} box Box to decorate.
 * @param {Entry} entry Entry which thumbnail is generating for.
 * @param {function(HTMLImageElement)=} opt_imageLoadCallback Callback called
 *     when the image has been loaded before inserting it into the DOM.
 * @private
 */
FileGrid.prototype.decorateThumbnailBox_ = function(
    box, entry, opt_imageLoadCallback) {
  box.className = 'img-container';

  if (this.importStatusVisible_ &&
      importer.isEligibleType(entry)) {
    this.historyLoader_.getHistory().then(
        FileGrid.applyHistoryBadges_.bind(
            null,
            /** @type {!FileEntry} */ (entry),
            box));
  }

  if (entry.isDirectory) {
    box.setAttribute('generic-thumbnail', 'folder');

    var shared = !!this.metadataModel_.getCache([entry], ['shared'])[0].shared;
    box.classList.toggle('shared', shared);

    if (opt_imageLoadCallback)
      setTimeout(opt_imageLoadCallback, 0, null /* callback parameter */);
    return;
  }

  // Set thumbnail if it's already in cache.
  if (this.listThumbnailLoader_ &&
      this.listThumbnailLoader_.getThumbnailFromCache(entry)) {
    FileGrid.setThumbnailImage_(
        box,
        this.listThumbnailLoader_.getThumbnailFromCache(entry).dataUrl,
        /* should not animate */ false);
  } else {
    var mediaType = FileType.getMediaType(entry);
    box.setAttribute('generic-thumbnail', mediaType);
  }
};

/**
 * Sets the visibility of the cloud import status column.
 * @param {boolean} visible
 */
FileGrid.prototype.setImportStatusVisible = function(visible) {
  this.importStatusVisible_ = visible;
};

/**
 * Sets thumbnail image to the box.
 * @param {!HTMLDivElement} box A div element to hold thumbnails.
 * @param {string} dataUrl Data url of thumbnail.
 * @param {boolean} shouldAnimate Whether the thumbanil is shown with animation
 *     or not.
 * @private
 */
FileGrid.setThumbnailImage_ = function(box, dataUrl, shouldAnimate) {
  var oldThumbnails = box.querySelectorAll('.thumbnail');

  var thumbnail = box.ownerDocument.createElement('div');
  thumbnail.classList.add('thumbnail');
  thumbnail.style.backgroundImage = 'url(' + dataUrl + ')';
  thumbnail.addEventListener('webkitAnimationEnd', function() {
    // Remove animation css once animation is completed in order not to animate
    // again when an item is attached to the dom again.
    thumbnail.classList.remove('animate');

    for (var i = 0; i < oldThumbnails.length; i++) {
      if (box.contains(oldThumbnails[i]))
        box.removeChild(oldThumbnails[i]);
    }
  });
  if (shouldAnimate)
    thumbnail.classList.add('animate');
  box.appendChild(thumbnail);
};

/**
 * Applies cloud import history badges as appropriate for the Entry.
 *
 * @param {!FileEntry} entry
 * @param {Element} box Box to decorate.
 * @param {!importer.ImportHistory} history
 *
 * @private
 */
FileGrid.applyHistoryBadges_ = function(entry, box, history) {
  history.wasImported(entry, importer.Destination.GOOGLE_DRIVE)
      .then(
          function(imported) {
            if (imported) {
              // TODO(smckay): update badges when history changes
              // "box" is currently the sibling of the elemement
              // we want to style. So rather than employing
              // a possibly-fragile sibling selector we just
              // plop the imported class on the parent of both.
              box.parentElement.classList.add('imported');
            } else {
              history.wasCopied(entry, importer.Destination.GOOGLE_DRIVE)
                  .then(
                      function(copied) {
                        if (copied) {
                          // TODO(smckay): update badges when history changes
                          // "box" is currently the sibling of the elemement
                          // we want to style. So rather than employing
                          // a possibly-fragile sibling selector we just
                          // plop the imported class on the parent of both.
                          box.parentElement.classList.add('copied');
                        }
                      });
            }
          });
};

/**
 * Item for the Grid View.
 * @constructor
 * @extends {cr.ui.ListItem}
 */
FileGrid.Item = function() {
  throw new Error();
};

/**
 * Inherits from cr.ui.ListItem.
 */
FileGrid.Item.prototype.__proto__ = cr.ui.ListItem.prototype;

Object.defineProperty(FileGrid.Item.prototype, 'label', {
  /**
   * @this {FileGrid.Item}
   * @return {string} Label of the item.
   */
  get: function() {
    return this.querySelector('filename-label').textContent;
  }
});

/**
 * @param {Element} li List item element.
 * @param {!Entry} entry File entry.
 * @param {FileGrid} grid Owner.
 */
FileGrid.Item.decorate = function(li, entry, grid) {
  li.__proto__ = FileGrid.Item.prototype;
  li = /** @type {!FileGrid.Item} */ (li);
  grid.decorateThumbnail_(li, entry);

  // Override the default role 'listitem' to 'option' to match the parent's
  // role (listbox).
  li.setAttribute('role', 'option');
};

/**
 * Obtains if the drag selection should be start or not by referring the mouse
 * event.
 * @param {MouseEvent} event Drag start event.
 * @return {boolean} True if the mouse is hit to the background of the list.
 */
FileGrid.prototype.shouldStartDragSelection = function(event) {
  var pos = DragSelector.getScrolledPosition(this, event);
  return this.getHitElements(pos.x, pos.y).length === 0;
};

/**
 * Obtains the column/row index that the coordinate points.
 * @param {number} coordinate Vertical/horizontal coordinate value that points
 *     column/row.
 * @param {number} step Length from a column/row to the next one.
 * @param {number} threshold Threshold that determines whether 1 offset is added
 *     to the return value or not. This is used in order to handle the margin of
 *     column/row.
 * @return {number} Index of hit column/row.
 * @private
 */
FileGrid.prototype.getHitIndex_ = function(coordinate, step, threshold) {
  var index = ~~(coordinate / step);
  return (coordinate % step >= threshold) ? index + 1 : index;
};

/**
 * Obtains the index list of elements that are hit by the point or the
 * rectangle.
 *
 * We should match its argument interface with FileList.getHitElements.
 *
 * @param {number} x X coordinate value.
 * @param {number} y Y coordinate value.
 * @param {number=} opt_width Width of the coordinate.
 * @param {number=} opt_height Height of the coordinate.
 * @return {Array.<number>} Index list of hit elements.
 */
FileGrid.prototype.getHitElements = function(x, y, opt_width, opt_height) {
  var currentSelection = [];
  var right = x + (opt_width || 0);
  var bottom = y + (opt_height || 0);
  var itemMetrics = this.measureItem();
  var horizontalStartIndex = this.getHitIndex_(
      x, itemMetrics.width, itemMetrics.width - itemMetrics.marginRight);
  var horizontalEndIndex = Math.min(this.columns, this.getHitIndex_(
      right, itemMetrics.width, itemMetrics.marginLeft));
  var verticalStartIndex = this.getHitIndex_(
      y, itemMetrics.height, itemMetrics.height - itemMetrics.marginBottom);
  var verticalEndIndex = this.getHitIndex_(
      bottom, itemMetrics.height, itemMetrics.marginTop);
  for (var verticalIndex = verticalStartIndex;
       verticalIndex < verticalEndIndex;
       verticalIndex++) {
    var indexBase = this.getFirstItemInRow(verticalIndex);
    for (var horizontalIndex = horizontalStartIndex;
         horizontalIndex < horizontalEndIndex;
         horizontalIndex++) {
      var index = indexBase + horizontalIndex;
      if (0 <= index && index < this.dataModel.length)
        currentSelection.push(index);
    }
  }
  return currentSelection;
};

/**
 * Selection controller for the file grid.
 * @param {!cr.ui.ListSelectionModel} selectionModel The selection model to
 *     interact with.
 * @param {!cr.ui.Grid} grid The grid to interact with.
 * @constructor
 * @extends {cr.ui.GridSelectionController}
 * @struct
 * @suppress {checkStructDictInheritance}
 */
function FileGridSelectionController(selectionModel, grid) {
  cr.ui.GridSelectionController.call(this, selectionModel, grid);
}

FileGridSelectionController.prototype = /** @struct */ {
  __proto__: cr.ui.GridSelectionController.prototype
};

/** @override */
FileGridSelectionController.prototype.handlePointerDownUp = function(e, index) {
  filelist.handlePointerDownUp.call(this, e, index);
};

/** @override */
FileGridSelectionController.prototype.handleKeyDown = function(e) {
  filelist.handleKeyDown.call(this, e);
};
<commit_msg>Files.app: Update shared status of icons on grid items.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * FileGrid constructor.
 *
 * Represents grid for the Grid View in the File Manager.
 * @constructor
 * @extends {cr.ui.Grid}
 */

function FileGrid() {
  throw new Error('Use FileGrid.decorate');
}

/**
 * Inherits from cr.ui.Grid.
 */
FileGrid.prototype.__proto__ = cr.ui.Grid.prototype;

/**
 * Decorates an HTML element to be a FileGrid.
 * @param {!Element} self The grid to decorate.
 * @param {!MetadataModel} metadataModel File system metadata.
 * @param {VolumeManagerWrapper} volumeManager Volume manager instance.
 * @param {!importer.HistoryLoader} historyLoader
 */
FileGrid.decorate = function(
    self, metadataModel, volumeManager, historyLoader) {
  cr.ui.Grid.decorate(self);
  self.__proto__ = FileGrid.prototype;
  self.metadataModel_ = metadataModel;
  self.volumeManager_ = volumeManager;
  self.historyLoader_ = historyLoader;

  /** @private {ListThumbnailLoader} */
  self.listThumbnailLoader_ = null;

  /** @private {number} */
  self.beginIndex_ = 0;

  /** @private {number} */
  self.endIndex_ = 0;

  /**
   * Reflects the visibility of import status in the UI.  Assumption: import
   * status is only enabled in import-eligible locations.  See
   * ImportController#onDirectoryChanged.  For this reason, the code in this
   * class checks if import status is visible, and if so, assumes that all the
   * files are in an import-eligible location.
   * TODO(kenobi): Clean this up once import status is queryable from metadata.
   *
   * @private {boolean}
   */
  self.importStatusVisible_ = true;

  /** @private {function(!Event)} */
  self.onThumbnailLoadedBound_ = self.onThumbnailLoaded_.bind(self);

  self.scrollBar_ = new ScrollBar();
  self.scrollBar_.initialize(self.parentElement, self);

  self.itemConstructor = function(entry) {
    var item = self.ownerDocument.createElement('li');
    FileGrid.Item.decorate(
        item,
        entry,
        /** @type {FileGrid} */ (self));
    return item;
  };

  self.relayoutRateLimiter_ =
      new AsyncUtil.RateLimiter(self.relayoutImmediately_.bind(self));
};

/**
 * Sets list thumbnail loader.
 * @param {ListThumbnailLoader} listThumbnailLoader A list thumbnail loader.
 * @private
 */
FileGrid.prototype.setListThumbnailLoader = function(listThumbnailLoader) {
  if (this.listThumbnailLoader_) {
    this.listThumbnailLoader_.removeEventListener(
        'thumbnailLoaded', this.onThumbnailLoadedBound_);
  }

  this.listThumbnailLoader_ = listThumbnailLoader;

  if (this.listThumbnailLoader_) {
    this.listThumbnailLoader_.addEventListener(
        'thumbnailLoaded', this.onThumbnailLoadedBound_);
    this.listThumbnailLoader_.setHighPriorityRange(
        this.beginIndex_, this.endIndex_);
  }
};

/**
 * Handles thumbnail loaded event.
 * @param {!Event} event An event.
 * @private
 */
FileGrid.prototype.onThumbnailLoaded_ = function(event) {
  var listItem = this.getListItemByIndex(event.index);
  if (listItem) {
    var box = listItem.querySelector('.img-container');
    if (box) {
      FileGrid.setThumbnailImage_(
          assertInstanceof(box, HTMLDivElement),
          event.dataUrl,
          /* should animate */ true);
    }
  }
};

/**
 * @override
 */
FileGrid.prototype.mergeItems = function(beginIndex, endIndex) {
  cr.ui.Grid.prototype.mergeItems.call(this, beginIndex, endIndex);

  // Make sure that grid item's selected attribute is updated just after the
  // mergeItems operation is done. This prevents shadow of selected grid items
  // from being animated unintentionally by redraw.
  for (var i = beginIndex; i < endIndex; i++) {
    var item = this.getListItemByIndex(i);
    if (!item)
      continue;
    var isSelected = this.selectionModel.getIndexSelected(i);
    if (item.selected != isSelected)
      item.selected = isSelected;
  }

  // Keep these values to set range when a new list thumbnail loader is set.
  this.beginIndex_ = beginIndex;
  this.endIndex_ = endIndex;
  if (this.listThumbnailLoader_ !== null)
    this.listThumbnailLoader_.setHighPriorityRange(beginIndex, endIndex);
};

/**
 * @override
 */
FileGrid.prototype.createSelectionController = function(sm) {
  return new FileGridSelectionController(assert(sm), this);
};

/**
 * Updates items to reflect metadata changes.
 * @param {string} type Type of metadata changed.
 * @param {Array.<Entry>} entries Entries whose metadata changed.
 */
FileGrid.prototype.updateListItemsMetadata = function(type, entries) {
  var urls = util.entriesToURLs(entries);
  var boxes = this.querySelectorAll('.img-container');
  for (var i = 0; i < boxes.length; i++) {
    var box = boxes[i];
    var listItem = this.getListItemAncestor(box);
    var entry = listItem && this.dataModel.item(listItem.listIndex);
    if (!entry || urls.indexOf(entry.toURL()) === -1)
      continue;

    this.decorateThumbnailBox_(assertInstanceof(box, HTMLDivElement), entry);
    this.updateSharedStatus_(assert(listItem), entry);
  }
};

/**
 * Redraws the UI. Skips multiple consecutive calls.
 */
FileGrid.prototype.relayout = function() {
  this.relayoutRateLimiter_.run();
};

/**
 * Redraws the UI immediately.
 * @private
 */
FileGrid.prototype.relayoutImmediately_ = function() {
  this.startBatchUpdates();
  this.columns = 0;
  this.redraw();
  this.endBatchUpdates();
  cr.dispatchSimpleEvent(this, 'relayout');
};

/**
 * Decorates thumbnail.
 * @param {cr.ui.ListItem} li List item.
 * @param {!Entry} entry Entry to render a thumbnail for.
 * @private
 */
FileGrid.prototype.decorateThumbnail_ = function(li, entry) {
  li.className = 'thumbnail-item';
  if (entry)
    filelist.decorateListItem(li, entry, this.metadataModel_);

  var frame = li.ownerDocument.createElement('div');
  frame.className = 'thumbnail-frame';
  li.appendChild(frame);

  var box = li.ownerDocument.createElement('div');
  if (entry) {
    this.decorateThumbnailBox_(assertInstanceof(box, HTMLDivElement), entry);
  }
  frame.appendChild(box);

  var active_checkmark = li.ownerDocument.createElement('div');
  active_checkmark.className = 'checkmark active';
  frame.appendChild(active_checkmark);
  var inactive_checkmark = li.ownerDocument.createElement('div');
  inactive_checkmark.className = 'checkmark inactive';
  frame.appendChild(inactive_checkmark);

  var bottom = li.ownerDocument.createElement('div');
  bottom.className = 'thumbnail-bottom';
  var badge = li.ownerDocument.createElement('div');
  badge.className = 'badge';
  bottom.appendChild(badge);
  bottom.appendChild(filelist.renderFileTypeIcon(li.ownerDocument, entry));
  bottom.appendChild(filelist.renderFileNameLabel(li.ownerDocument, entry));
  frame.appendChild(bottom);

  this.updateSharedStatus_(li, entry);
};

/**
 * Decorates the box containing a centered thumbnail image.
 *
 * @param {!HTMLDivElement} box Box to decorate.
 * @param {Entry} entry Entry which thumbnail is generating for.
 * @private
 */
FileGrid.prototype.decorateThumbnailBox_ = function(box, entry) {
  box.className = 'img-container';

  if (this.importStatusVisible_ &&
      importer.isEligibleType(entry)) {
    this.historyLoader_.getHistory().then(
        FileGrid.applyHistoryBadges_.bind(
            null,
            /** @type {!FileEntry} */ (entry),
            box));
  }

  if (entry.isDirectory) {
    box.setAttribute('generic-thumbnail', 'folder');
    return;
  }

  // Set thumbnail if it's already in cache.
  if (this.listThumbnailLoader_ &&
      this.listThumbnailLoader_.getThumbnailFromCache(entry)) {
    FileGrid.setThumbnailImage_(
        box,
        this.listThumbnailLoader_.getThumbnailFromCache(entry).dataUrl,
        /* should not animate */ false);
  } else {
    var mediaType = FileType.getMediaType(entry);
    box.setAttribute('generic-thumbnail', mediaType);
  }
};

/**
 * Added 'shared' class to icon and placeholder of a folder item.
 * @param {!HTMLLIElement} li The grid item.
 * @param {!Entry} entry File entry for the grid item.
 * @private
 */
FileGrid.prototype.updateSharedStatus_ = function(li, entry) {
  if (!entry.isDirectory)
    return;

  var shared = !!this.metadataModel_.getCache([entry], ['shared'])[0].shared;
  var box = li.querySelector('.img-container');
  if (box)
    box.classList.toggle('shared', shared);
  var icon = li.querySelector('.detail-icon');
  if (icon)
    icon.classList.toggle('shared', shared);
};

/**
 * Sets the visibility of the cloud import status column.
 * @param {boolean} visible
 */
FileGrid.prototype.setImportStatusVisible = function(visible) {
  this.importStatusVisible_ = visible;
};

/**
 * Sets thumbnail image to the box.
 * @param {!HTMLDivElement} box A div element to hold thumbnails.
 * @param {string} dataUrl Data url of thumbnail.
 * @param {boolean} shouldAnimate Whether the thumbanil is shown with animation
 *     or not.
 * @private
 */
FileGrid.setThumbnailImage_ = function(box, dataUrl, shouldAnimate) {
  var oldThumbnails = box.querySelectorAll('.thumbnail');

  var thumbnail = box.ownerDocument.createElement('div');
  thumbnail.classList.add('thumbnail');
  thumbnail.style.backgroundImage = 'url(' + dataUrl + ')';
  thumbnail.addEventListener('webkitAnimationEnd', function() {
    // Remove animation css once animation is completed in order not to animate
    // again when an item is attached to the dom again.
    thumbnail.classList.remove('animate');

    for (var i = 0; i < oldThumbnails.length; i++) {
      if (box.contains(oldThumbnails[i]))
        box.removeChild(oldThumbnails[i]);
    }
  });
  if (shouldAnimate)
    thumbnail.classList.add('animate');
  box.appendChild(thumbnail);
};

/**
 * Applies cloud import history badges as appropriate for the Entry.
 *
 * @param {!FileEntry} entry
 * @param {Element} box Box to decorate.
 * @param {!importer.ImportHistory} history
 *
 * @private
 */
FileGrid.applyHistoryBadges_ = function(entry, box, history) {
  history.wasImported(entry, importer.Destination.GOOGLE_DRIVE)
      .then(
          function(imported) {
            if (imported) {
              // TODO(smckay): update badges when history changes
              // "box" is currently the sibling of the elemement
              // we want to style. So rather than employing
              // a possibly-fragile sibling selector we just
              // plop the imported class on the parent of both.
              box.parentElement.classList.add('imported');
            } else {
              history.wasCopied(entry, importer.Destination.GOOGLE_DRIVE)
                  .then(
                      function(copied) {
                        if (copied) {
                          // TODO(smckay): update badges when history changes
                          // "box" is currently the sibling of the elemement
                          // we want to style. So rather than employing
                          // a possibly-fragile sibling selector we just
                          // plop the imported class on the parent of both.
                          box.parentElement.classList.add('copied');
                        }
                      });
            }
          });
};

/**
 * Item for the Grid View.
 * @constructor
 * @extends {cr.ui.ListItem}
 */
FileGrid.Item = function() {
  throw new Error();
};

/**
 * Inherits from cr.ui.ListItem.
 */
FileGrid.Item.prototype.__proto__ = cr.ui.ListItem.prototype;

Object.defineProperty(FileGrid.Item.prototype, 'label', {
  /**
   * @this {FileGrid.Item}
   * @return {string} Label of the item.
   */
  get: function() {
    return this.querySelector('filename-label').textContent;
  }
});

/**
 * @param {Element} li List item element.
 * @param {!Entry} entry File entry.
 * @param {FileGrid} grid Owner.
 */
FileGrid.Item.decorate = function(li, entry, grid) {
  li.__proto__ = FileGrid.Item.prototype;
  li = /** @type {!FileGrid.Item} */ (li);
  grid.decorateThumbnail_(li, entry);

  // Override the default role 'listitem' to 'option' to match the parent's
  // role (listbox).
  li.setAttribute('role', 'option');
};

/**
 * Obtains if the drag selection should be start or not by referring the mouse
 * event.
 * @param {MouseEvent} event Drag start event.
 * @return {boolean} True if the mouse is hit to the background of the list.
 */
FileGrid.prototype.shouldStartDragSelection = function(event) {
  var pos = DragSelector.getScrolledPosition(this, event);
  return this.getHitElements(pos.x, pos.y).length === 0;
};

/**
 * Obtains the column/row index that the coordinate points.
 * @param {number} coordinate Vertical/horizontal coordinate value that points
 *     column/row.
 * @param {number} step Length from a column/row to the next one.
 * @param {number} threshold Threshold that determines whether 1 offset is added
 *     to the return value or not. This is used in order to handle the margin of
 *     column/row.
 * @return {number} Index of hit column/row.
 * @private
 */
FileGrid.prototype.getHitIndex_ = function(coordinate, step, threshold) {
  var index = ~~(coordinate / step);
  return (coordinate % step >= threshold) ? index + 1 : index;
};

/**
 * Obtains the index list of elements that are hit by the point or the
 * rectangle.
 *
 * We should match its argument interface with FileList.getHitElements.
 *
 * @param {number} x X coordinate value.
 * @param {number} y Y coordinate value.
 * @param {number=} opt_width Width of the coordinate.
 * @param {number=} opt_height Height of the coordinate.
 * @return {Array.<number>} Index list of hit elements.
 */
FileGrid.prototype.getHitElements = function(x, y, opt_width, opt_height) {
  var currentSelection = [];
  var right = x + (opt_width || 0);
  var bottom = y + (opt_height || 0);
  var itemMetrics = this.measureItem();
  var horizontalStartIndex = this.getHitIndex_(
      x, itemMetrics.width, itemMetrics.width - itemMetrics.marginRight);
  var horizontalEndIndex = Math.min(this.columns, this.getHitIndex_(
      right, itemMetrics.width, itemMetrics.marginLeft));
  var verticalStartIndex = this.getHitIndex_(
      y, itemMetrics.height, itemMetrics.height - itemMetrics.marginBottom);
  var verticalEndIndex = this.getHitIndex_(
      bottom, itemMetrics.height, itemMetrics.marginTop);
  for (var verticalIndex = verticalStartIndex;
       verticalIndex < verticalEndIndex;
       verticalIndex++) {
    var indexBase = this.getFirstItemInRow(verticalIndex);
    for (var horizontalIndex = horizontalStartIndex;
         horizontalIndex < horizontalEndIndex;
         horizontalIndex++) {
      var index = indexBase + horizontalIndex;
      if (0 <= index && index < this.dataModel.length)
        currentSelection.push(index);
    }
  }
  return currentSelection;
};

/**
 * Selection controller for the file grid.
 * @param {!cr.ui.ListSelectionModel} selectionModel The selection model to
 *     interact with.
 * @param {!cr.ui.Grid} grid The grid to interact with.
 * @constructor
 * @extends {cr.ui.GridSelectionController}
 * @struct
 * @suppress {checkStructDictInheritance}
 */
function FileGridSelectionController(selectionModel, grid) {
  cr.ui.GridSelectionController.call(this, selectionModel, grid);
}

FileGridSelectionController.prototype = /** @struct */ {
  __proto__: cr.ui.GridSelectionController.prototype
};

/** @override */
FileGridSelectionController.prototype.handlePointerDownUp = function(e, index) {
  filelist.handlePointerDownUp.call(this, e, index);
};

/** @override */
FileGridSelectionController.prototype.handleKeyDown = function(e) {
  filelist.handleKeyDown.call(this, e);
};
<|endoftext|>


<commit_before>var express = require( "express" );
var async = require( "async" );
var models = require( "./models" );

module.exports = function ( messageBroker ) {

    var app = express();

    messageBroker.create( "sensor.get" );
    messageBroker.create( "system.get" );

    // log sensor data job
    var getSensorData = function ( done ) {
        messageBroker.publish( "sensor.get", { serialMessage: "A" }, function ( err, data ) {
            if ( err ) {
                return done( err );
            }
            return done( null, data );
        } );
    };

    var saveSensorData = function ( sensorData, done ) {
        models.SensorReading.create( sensorData, function ( err, data ) {
            if ( err ) {
                return done( err );
            }
            return done( null, data );
        } );
    };

    app.get( "/job/log-sensor-reading", function ( req, res ) {
        async.waterfall( [ getSensorData, saveSensorData ], function ( err, data ) {
            if ( err ) {
                // add logging here
                return res.json( 500 );
            }
            return res.json( 200 );
        } );
    } );

    // log system data job
    var getSystemData = function ( done ) {
        messageBroker.publish( "system.get", {}, function ( err, data ) {
            if ( err ) {
                return done( err );
            }
            return done( null, data );
        } );
    };

    var saveSystemData = function ( systemData, done ) {
        models.SystemReading.create( systemData, function ( err, data ) {
            if ( err ) {
                return done( err );
            }
            return done( null, data );
        } );
    };

    app.get( "/job/log-system-reading", function ( req, res ) {
        async.waterfall( [ getSystemData, saveSystemData ], function ( err, data ) {
            if ( err ) {
                // add logging here
                return res.json( 500 );
            }
            return res.json(    200 );
        } );
    } );

    return app;

};
<commit_msg>Debugging<commit_after>var express = require( "express" );
var async = require( "async" );
var models = require( "./models" );

module.exports = function ( messageBroker ) {

    var app = express();

    messageBroker.create( "sensor.get" );
    messageBroker.create( "system.get" );

    // log sensor data job
    var getSensorData = function ( done ) {
        console.log( "Request sent: sensor.get" );
        messageBroker.publish( "sensor.get", { serialMessage: "A" }, function ( err, data ) {
            if ( err ) {
                return done( err );
            }
            console.log( "Response received: sensor.get" );
            return done( null, data );
        } );
    };

    var saveSensorData = function ( sensorData, done ) {
        console.log( "Request sent: SensorReading.create" );
        models.SensorReading.create( sensorData, function ( err, data ) {
            if ( err ) {
                return done( err );
            }
            console.log( "Response received: SensorReading.create" );
            return done( null, data );
        } );
    };

    app.get( "/job/log-sensor-reading", function ( req, res ) {
        async.waterfall( [ getSensorData, saveSensorData ], function ( err, data ) {
            if ( err ) {
                // add logging here
                return res.status( 500 ).json();
            }
            console.log( "Sensor Reading" );
            console.log( data );
            return res.status( 200 ).json();
        } );
    } );

    // log system data job
    var getSystemData = function ( done ) {
        messageBroker.publish( "system.get", {}, function ( err, data ) {
            if ( err ) {
                return done( err );
            }
            return done( null, data );
        } );
    };

    var saveSystemData = function ( systemData, done ) {
        models.SystemReading.create( systemData, function ( err, data ) {
            if ( err ) {
                return done( err );
            }
            return done( null, data );
        } );
    };

    app.get( "/job/log-system-reading", function ( req, res ) {
        async.waterfall( [ getSystemData, saveSystemData ], function ( err, data ) {
            if ( err ) {
                // add logging here
                return res.status( 500 ).json();
            }
            console.log( "System Reading" );
            console.log( data );
            return res.status( 200 ).json();
        } );
    } );

    return app;

};
<|endoftext|>


<commit_before>import { objectType } from "./core/utilities";

// Test for equality any JavaScript type.
// Authors: Philippe Rathé <prathe@gmail.com>, David Chan <david@troi.org>
export default ( function() {

	// Value pairs queued for comparison. Used for breadth-first processing order, recursion
	// detection and avoiding repeated comparison (see below for details).
	// Elements are { a: val, b: val }.
	let pairs = [];

	const getProto = Object.getPrototypeOf || function( obj ) {
		return obj.__proto__;
	};

	function useStrictEquality( a, b ) {

		// This only gets called if a and b are not strict equal, and is used to compare on
		// the primitive values inside object wrappers. For example:
		// `var i = 1;`
		// `var j = new Number(1);`
		// Neither a nor b can be null, as a !== b and they have the same type.
		if ( typeof a === "object" ) {
			a = a.valueOf();
		}
		if ( typeof b === "object" ) {
			b = b.valueOf();
		}

		return a === b;
	}

	function compareConstructors( a, b ) {
		let protoA = getProto( a );
		let protoB = getProto( b );

		// Comparing constructors is more strict than using `instanceof`
		if ( a.constructor === b.constructor ) {
			return true;
		}

		// Ref #851
		// If the obj prototype descends from a null constructor, treat it
		// as a null prototype.
		if ( protoA && protoA.constructor === null ) {
			protoA = null;
		}
		if ( protoB && protoB.constructor === null ) {
			protoB = null;
		}

		// Allow objects with no prototype to be equivalent to
		// objects with Object as their constructor.
		if ( ( protoA === null && protoB === Object.prototype ) ||
				( protoB === null && protoA === Object.prototype ) ) {
			return true;
		}

		return false;
	}

	function getRegExpFlags( regexp ) {
		return "flags" in regexp ? regexp.flags : regexp.toString().match( /[gimuy]*$/ )[ 0 ];
	}

	function isContainer( val ) {
		return [ "object", "array", "map", "set" ].indexOf( objectType( val ) ) !== -1;
	}

	function breadthFirstCompareChild( a, b ) {

		// If a is a container not reference-equal to b, postpone the comparison to the
		// end of the pairs queue -- unless (a, b) has been seen before, in which case skip
		// over the pair.
		if ( a === b ) {
			return true;
		}
		if ( !isContainer( a ) ) {
			return typeEquiv( a, b );
		}
		if ( pairs.every( function( pair ) {
			return pair.a !== a || pair.b !== b;
		} ) ) {

			// Not yet started comparing this pair
			pairs.push( { a: a, b: b } );
		}
		return true;
	}

	const callbacks = {
		"string": useStrictEquality,
		"boolean": useStrictEquality,
		"number": useStrictEquality,
		"null": useStrictEquality,
		"undefined": useStrictEquality,
		"symbol": useStrictEquality,
		"date": useStrictEquality,

		"nan": function() {
			return true;
		},

		"regexp": function( a, b ) {
			return a.source === b.source &&

				// Include flags in the comparison
				getRegExpFlags( a ) === getRegExpFlags( b );
		},

		// abort (identical references / instance methods were skipped earlier)
		"function": function() {
			return false;
		},

		"array": function( a, b ) {

			const len = a.length;
			if ( len !== b.length ) {

				// Safe and faster
				return false;
			}

			for ( let i = 0; i < len; i++ ) {

				// Compare non-containers; queue non-reference-equal containers
				if ( !breadthFirstCompareChild( a[ i ], b[ i ] ) ) {
					return false;
				}
			}
			return true;
		},

		// Define sets a and b to be equivalent if for each element aVal in a, there
		// is some element bVal in b such that aVal and bVal are equivalent. Element
		// repetitions are not counted, so these are equivalent:
		// a = new Set( [ {}, [], [] ] );
		// b = new Set( [ {}, {}, [] ] );
		"set": function( a, b ) {

			if ( a.size !== b.size ) {

				// This optimization has certain quirks because of the lack of
				// repetition counting. For instance, adding the same
				// (reference-identical) element to two equivalent sets can
				// make them non-equivalent.
				return false;
			}

			let outerEq = true;

			a.forEach( function( aVal ) {

				// Short-circuit if the result is already known. (Using for...of
				// with a break clause would be cleaner here, but it would cause
				// a syntax error on older Javascript implementations even if
				// Set is unused)
				if ( !outerEq ) {
					return;
				}

				let innerEq = false;

				b.forEach( function( bVal ) {

					// Likewise, short-circuit if the result is already known
					if ( innerEq ) {
						return;
					}

					// Swap out the global pairs list, as the nested call to
					// innerEquiv will clobber its contents
					const parentPairs = pairs;
					if ( innerEquiv( bVal, aVal ) ) {
						innerEq = true;
					}

					// Replace the global pairs list
					pairs = parentPairs;
				} );

				if ( !innerEq ) {
					outerEq = false;
				}
			} );

			return outerEq;
		},

		// Define maps a and b to be equivalent if for each key-value pair (aKey, aVal)
		// in a, there is some key-value pair (bKey, bVal) in b such that
		// [ aKey, aVal ] and [ bKey, bVal ] are equivalent. Key repetitions are not
		// counted, so these are equivalent:
		// a = new Map( [ [ {}, 1 ], [ {}, 1 ], [ [], 1 ] ] );
		// b = new Map( [ [ {}, 1 ], [ [], 1 ], [ [], 1 ] ] );
		"map": function( a, b ) {

			if ( a.size !== b.size ) {

				// This optimization has certain quirks because of the lack of
				// repetition counting. For instance, adding the same
				// (reference-identical) key-value pair to two equivalent maps
				// can make them non-equivalent.
				return false;
			}

			let outerEq = true;

			a.forEach( function( aVal, aKey ) {

				// Short-circuit if the result is already known. (Using for...of
				// with a break clause would be cleaner here, but it would cause
				// a syntax error on older Javascript implementations even if
				// Map is unused)
				if ( !outerEq ) {
					return;
				}

				let innerEq = false;

				b.forEach( function( bVal, bKey ) {

					// Likewise, short-circuit if the result is already known
					if ( innerEq ) {
						return;
					}

					// Swap out the global pairs list, as the nested call to
					// innerEquiv will clobber its contents
					const parentPairs = pairs;
					if ( innerEquiv( [ bVal, bKey ], [ aVal, aKey ] ) ) {
						innerEq = true;
					}

					// Replace the global pairs list
					pairs = parentPairs;
				} );

				if ( !innerEq ) {
					outerEq = false;
				}
			} );

			return outerEq;
		},

		"object": function( a, b ) {

			if ( compareConstructors( a, b ) === false ) {
				return false;
			}

			const aProperties = [];
			const bProperties = [];

			// Be strict: don't ensure hasOwnProperty and go deep
			for ( const i in a ) {

				// Collect a's properties
				aProperties.push( i );

				// Skip OOP methods that look the same
				if (
					a.constructor !== Object &&
					typeof a.constructor !== "undefined" &&
					typeof a[ i ] === "function" &&
					typeof b[ i ] === "function" &&
					a[ i ].toString() === b[ i ].toString()
				) {
					continue;
				}

				// Compare non-containers; queue non-reference-equal containers
				if ( !breadthFirstCompareChild( a[ i ], b[ i ] ) ) {
					return false;
				}
			}

			for ( const i in b ) {

				// Collect b's properties
				bProperties.push( i );
			}

			// Ensures identical properties name
			return typeEquiv( aProperties.sort(), bProperties.sort() );
		}
	};

	function typeEquiv( a, b ) {
		const type = objectType( a );

		// Callbacks for containers will append to the pairs queue to achieve breadth-first
		// search order. The pairs queue is also used to avoid reprocessing any pair of
		// containers that are reference-equal to a previously visited pair (a special case
		// this being recursion detection).
		//
		// Because of this approach, once typeEquiv returns a false value, it should not be
		// called again without clearing the pair queue else it may wrongly report a visited
		// pair as being equivalent.
		return objectType( b ) === type && callbacks[ type ]( a, b );
	}

	function innerEquiv( a, b ) {

		// We're done when there's nothing more to compare
		if ( arguments.length < 2 ) {
			return true;
		}

		// Clear the global pair queue and add the top-level values being compared
		pairs = [ { a: a, b: b } ];

		for ( let i = 0; i < pairs.length; i++ ) {
			const pair = pairs[ i ];

			// Perform type-specific comparison on any pairs that are not strictly
			// equal. For container types, that comparison will postpone comparison
			// of any sub-container pair to the end of the pair queue. This gives
			// breadth-first search order. It also avoids the reprocessing of
			// reference-equal siblings, cousins etc, which can have a significant speed
			// impact when comparing a container of small objects each of which has a
			// reference to the same (singleton) large object.
			if ( pair.a !== pair.b && !typeEquiv( pair.a, pair.b ) ) {
				return false;
			}
		}

		// ...across all consecutive argument pairs
		return arguments.length === 2 || innerEquiv.apply( this, [].slice.call( arguments, 1 ) );
	}

	return ( ...args ) => {
		const result = innerEquiv( ...args );

		// Release any retained objects
		pairs.length = 0;
		return result;
	};
}() );
<commit_msg>Docs: Fix casing of "JavaScript"<commit_after>import { objectType } from "./core/utilities";

// Test for equality any JavaScript type.
// Authors: Philippe Rathé <prathe@gmail.com>, David Chan <david@troi.org>
export default ( function() {

	// Value pairs queued for comparison. Used for breadth-first processing order, recursion
	// detection and avoiding repeated comparison (see below for details).
	// Elements are { a: val, b: val }.
	let pairs = [];

	const getProto = Object.getPrototypeOf || function( obj ) {
		return obj.__proto__;
	};

	function useStrictEquality( a, b ) {

		// This only gets called if a and b are not strict equal, and is used to compare on
		// the primitive values inside object wrappers. For example:
		// `var i = 1;`
		// `var j = new Number(1);`
		// Neither a nor b can be null, as a !== b and they have the same type.
		if ( typeof a === "object" ) {
			a = a.valueOf();
		}
		if ( typeof b === "object" ) {
			b = b.valueOf();
		}

		return a === b;
	}

	function compareConstructors( a, b ) {
		let protoA = getProto( a );
		let protoB = getProto( b );

		// Comparing constructors is more strict than using `instanceof`
		if ( a.constructor === b.constructor ) {
			return true;
		}

		// Ref #851
		// If the obj prototype descends from a null constructor, treat it
		// as a null prototype.
		if ( protoA && protoA.constructor === null ) {
			protoA = null;
		}
		if ( protoB && protoB.constructor === null ) {
			protoB = null;
		}

		// Allow objects with no prototype to be equivalent to
		// objects with Object as their constructor.
		if ( ( protoA === null && protoB === Object.prototype ) ||
				( protoB === null && protoA === Object.prototype ) ) {
			return true;
		}

		return false;
	}

	function getRegExpFlags( regexp ) {
		return "flags" in regexp ? regexp.flags : regexp.toString().match( /[gimuy]*$/ )[ 0 ];
	}

	function isContainer( val ) {
		return [ "object", "array", "map", "set" ].indexOf( objectType( val ) ) !== -1;
	}

	function breadthFirstCompareChild( a, b ) {

		// If a is a container not reference-equal to b, postpone the comparison to the
		// end of the pairs queue -- unless (a, b) has been seen before, in which case skip
		// over the pair.
		if ( a === b ) {
			return true;
		}
		if ( !isContainer( a ) ) {
			return typeEquiv( a, b );
		}
		if ( pairs.every( function( pair ) {
			return pair.a !== a || pair.b !== b;
		} ) ) {

			// Not yet started comparing this pair
			pairs.push( { a: a, b: b } );
		}
		return true;
	}

	const callbacks = {
		"string": useStrictEquality,
		"boolean": useStrictEquality,
		"number": useStrictEquality,
		"null": useStrictEquality,
		"undefined": useStrictEquality,
		"symbol": useStrictEquality,
		"date": useStrictEquality,

		"nan": function() {
			return true;
		},

		"regexp": function( a, b ) {
			return a.source === b.source &&

				// Include flags in the comparison
				getRegExpFlags( a ) === getRegExpFlags( b );
		},

		// abort (identical references / instance methods were skipped earlier)
		"function": function() {
			return false;
		},

		"array": function( a, b ) {

			const len = a.length;
			if ( len !== b.length ) {

				// Safe and faster
				return false;
			}

			for ( let i = 0; i < len; i++ ) {

				// Compare non-containers; queue non-reference-equal containers
				if ( !breadthFirstCompareChild( a[ i ], b[ i ] ) ) {
					return false;
				}
			}
			return true;
		},

		// Define sets a and b to be equivalent if for each element aVal in a, there
		// is some element bVal in b such that aVal and bVal are equivalent. Element
		// repetitions are not counted, so these are equivalent:
		// a = new Set( [ {}, [], [] ] );
		// b = new Set( [ {}, {}, [] ] );
		"set": function( a, b ) {

			if ( a.size !== b.size ) {

				// This optimization has certain quirks because of the lack of
				// repetition counting. For instance, adding the same
				// (reference-identical) element to two equivalent sets can
				// make them non-equivalent.
				return false;
			}

			let outerEq = true;

			a.forEach( function( aVal ) {

				// Short-circuit if the result is already known. (Using for...of
				// with a break clause would be cleaner here, but it would cause
				// a syntax error on older JavaScript implementations even if
				// Set is unused)
				if ( !outerEq ) {
					return;
				}

				let innerEq = false;

				b.forEach( function( bVal ) {

					// Likewise, short-circuit if the result is already known
					if ( innerEq ) {
						return;
					}

					// Swap out the global pairs list, as the nested call to
					// innerEquiv will clobber its contents
					const parentPairs = pairs;
					if ( innerEquiv( bVal, aVal ) ) {
						innerEq = true;
					}

					// Replace the global pairs list
					pairs = parentPairs;
				} );

				if ( !innerEq ) {
					outerEq = false;
				}
			} );

			return outerEq;
		},

		// Define maps a and b to be equivalent if for each key-value pair (aKey, aVal)
		// in a, there is some key-value pair (bKey, bVal) in b such that
		// [ aKey, aVal ] and [ bKey, bVal ] are equivalent. Key repetitions are not
		// counted, so these are equivalent:
		// a = new Map( [ [ {}, 1 ], [ {}, 1 ], [ [], 1 ] ] );
		// b = new Map( [ [ {}, 1 ], [ [], 1 ], [ [], 1 ] ] );
		"map": function( a, b ) {

			if ( a.size !== b.size ) {

				// This optimization has certain quirks because of the lack of
				// repetition counting. For instance, adding the same
				// (reference-identical) key-value pair to two equivalent maps
				// can make them non-equivalent.
				return false;
			}

			let outerEq = true;

			a.forEach( function( aVal, aKey ) {

				// Short-circuit if the result is already known. (Using for...of
				// with a break clause would be cleaner here, but it would cause
				// a syntax error on older JavaScript implementations even if
				// Map is unused)
				if ( !outerEq ) {
					return;
				}

				let innerEq = false;

				b.forEach( function( bVal, bKey ) {

					// Likewise, short-circuit if the result is already known
					if ( innerEq ) {
						return;
					}

					// Swap out the global pairs list, as the nested call to
					// innerEquiv will clobber its contents
					const parentPairs = pairs;
					if ( innerEquiv( [ bVal, bKey ], [ aVal, aKey ] ) ) {
						innerEq = true;
					}

					// Replace the global pairs list
					pairs = parentPairs;
				} );

				if ( !innerEq ) {
					outerEq = false;
				}
			} );

			return outerEq;
		},

		"object": function( a, b ) {

			if ( compareConstructors( a, b ) === false ) {
				return false;
			}

			const aProperties = [];
			const bProperties = [];

			// Be strict: don't ensure hasOwnProperty and go deep
			for ( const i in a ) {

				// Collect a's properties
				aProperties.push( i );

				// Skip OOP methods that look the same
				if (
					a.constructor !== Object &&
					typeof a.constructor !== "undefined" &&
					typeof a[ i ] === "function" &&
					typeof b[ i ] === "function" &&
					a[ i ].toString() === b[ i ].toString()
				) {
					continue;
				}

				// Compare non-containers; queue non-reference-equal containers
				if ( !breadthFirstCompareChild( a[ i ], b[ i ] ) ) {
					return false;
				}
			}

			for ( const i in b ) {

				// Collect b's properties
				bProperties.push( i );
			}

			// Ensures identical properties name
			return typeEquiv( aProperties.sort(), bProperties.sort() );
		}
	};

	function typeEquiv( a, b ) {
		const type = objectType( a );

		// Callbacks for containers will append to the pairs queue to achieve breadth-first
		// search order. The pairs queue is also used to avoid reprocessing any pair of
		// containers that are reference-equal to a previously visited pair (a special case
		// this being recursion detection).
		//
		// Because of this approach, once typeEquiv returns a false value, it should not be
		// called again without clearing the pair queue else it may wrongly report a visited
		// pair as being equivalent.
		return objectType( b ) === type && callbacks[ type ]( a, b );
	}

	function innerEquiv( a, b ) {

		// We're done when there's nothing more to compare
		if ( arguments.length < 2 ) {
			return true;
		}

		// Clear the global pair queue and add the top-level values being compared
		pairs = [ { a: a, b: b } ];

		for ( let i = 0; i < pairs.length; i++ ) {
			const pair = pairs[ i ];

			// Perform type-specific comparison on any pairs that are not strictly
			// equal. For container types, that comparison will postpone comparison
			// of any sub-container pair to the end of the pair queue. This gives
			// breadth-first search order. It also avoids the reprocessing of
			// reference-equal siblings, cousins etc, which can have a significant speed
			// impact when comparing a container of small objects each of which has a
			// reference to the same (singleton) large object.
			if ( pair.a !== pair.b && !typeEquiv( pair.a, pair.b ) ) {
				return false;
			}
		}

		// ...across all consecutive argument pairs
		return arguments.length === 2 || innerEquiv.apply( this, [].slice.call( arguments, 1 ) );
	}

	return ( ...args ) => {
		const result = innerEquiv( ...args );

		// Release any retained objects
		pairs.length = 0;
		return result;
	};
}() );
<|endoftext|>


<commit_before>(function() {
    'use strict';

    angular
        .module('openeApp', [
            'ngSanitize',
            'ngMaterial',
            'ui.router',
            'ngResource',
            'ngPDFViewer',
            'swfobject',
            'isteven-multi-select',
            'openeApp.translations',
            'openeApp.cases',
            'openeApp.cases.members',
            'openeApp.cases.parties',
            'openeApp.classification',
            'openeApp.dashboard',
            'openeApp.files',
            'openeApp.tasks',
            'openeApp.documents',
            'openeApp.notes',
            'openeApp.contacts',
            'openeApp.administration',
            'openeApp.office',
            'openeApp.groups'
        ])
        .constant('USER_ROLES', {
            admin: 'admin',
            user: 'user',
            guest: 'guest'
        })
        .config(config)
        .run(function($rootScope, $state, $stateParams, authService) {
            $rootScope.$on('$stateChangeStart', function(event, next, params) {
                $rootScope.toState = next;
                $rootScope.toStateParams = params;
                if (next.data.authorizedRoles.length == 0) {
                    return;
                }
                if (authService.isAuthenticated()) {

                } else {
                    event.preventDefault();
                    $rootScope.returnToState = $rootScope.toState;
                    $rootScope.returnToStateParams = $rootScope.toStateParams;
                    $state.go('login');
                }
//                console.log('authenticated? ', authService.isAuthenticated());
//                if (!authService.isAuthenticated()) {
//                    event.preventDefault();
//                    $state.go('login');
//                }
            });
        });

    config.$inject = ['$mdThemingProvider', '$stateProvider', '$urlRouterProvider', 'USER_ROLES', '$mdIconProvider'];

    function config($mdThemingProvider, $stateProvider, $urlRouterProvider, USER_ROLES, $mdIconProvider) {
        $mdThemingProvider.theme('default')
            .primaryPalette('blue', {
              'default': '600',
              'hue-1': '400',
              'hue-2': '800',
              'hue-3': '900'
            })
            .accentPalette('amber')
            .warnPalette('deep-orange');

        $mdIconProvider.icon('md-calendar', '/app/assets/img/icons/today.svg');

        $urlRouterProvider.otherwise('/');

        $stateProvider.state('site', {
            abstract: true,
            resolve: {
                authorize: ['authService', function(authService) {
                }]
            }
        }).state('dashboard', {
            parent: 'site',
            url: '/',
            views: {
                'content@': {
                    templateUrl: '/app/src/dashboard/view/dashboard.html',
                    controller: 'DashboardController'
                }
            },
            data: {
                authorizedRoles: [USER_ROLES.user]
            }
        }).state('cases', {
            parent: 'site',
            url: '/cases',
            views: {
                'content@': {
                    templateUrl: '/app/src/cases/view/cases.html',
                    controller: 'CaseController',
                    controllerAs: 'vm'
                }
            },
            data: {
                authorizedRoles: [USER_ROLES.user]
            }
        }).state('caseinfo', {
            parent: 'site',
            url: '/cases/case/:caseId',
            views: {
                'content@': {
                    templateUrl: '/app/src/cases/view/case.html',
                    controller: 'CaseInfoController',
                    controllerAs: 'vm'
                }
            },
            data: {
                authorizedRoles: [USER_ROLES.user]
            }
        }).state('docDetails', {
            parent: 'site',
            url: '/cases/case/:caseId/doc/:storeType/:storeId/:id',
            views: {
                'content@': {
                    controller : 'DocumentDetailsController',
                    templateUrl : 'app/src/documents/view/document.html',
                    controllerAs: 'docCtrl'
                }
            },
            data: {
                authorizedRoles: [USER_ROLES.user]
            }
        }).state('login', {
            parent: 'site',
            url: '/login',
            views: {
                'content@': {
                    templateUrl: '/app/src/authentication/view/login.html',
                    controller: 'AuthController',
                    controllerAs: 'vm'
                }
            },
            data: {
                authorizedRoles: []
            }
        }).state('tasks', {
            parent: 'site',
            url: '/tasks',
            views: {
                'content@': {
                    templateUrl : '/app/src/tasks/view/tasks.html',
                    controller : 'tasksOverviewController',
                    controllerAs: 'tasksCtrl'
                }
            },
            data: {
                authorizedRoles: [USER_ROLES.user]
            }
        }).state('administration', {
            parent: 'site',
            url: '/admin',
            views: {
                'content@': {
                    templateUrl : '/app/src/admin/view/admin.html',
                    controller : 'AdminController',
                    controllerAs: 'vm',
                }
            },
            data: {
                authorizedRoles: [USER_ROLES.user]
            }
        }).state('administration.organizations', {
            parent: 'site',
            url: '/admin/organizations',
            views: {
                'content@': {
                    templateUrl: '/app/src/admin/view/admin.html',
                    controller: 'AdminController',
                    controllerAs: 'vm'
                }
            },
            data: {
                authorizedRoles: [USER_ROLES.user],
                selectedTab: 2
            }
        }).state('administration.contacts', {
            parent: 'site',
            url: '/admin/contacts',
            views: {
                'content@': {
                    templateUrl: '/app/src/admin/view/admin.html',
                    controller: 'AdminController',
                    controllerAs: 'vm'
                }
            },
            data: {
                authorizedRoles: [USER_ROLES.user],
                selectedTab: 3
            }
        }).state('administration.organizations.organization', {
            parent: 'site',
            url: '/admin/organizations/:storeProtocol/:storeIdentifier/:uuid',
            views: {
                'content@': {
                    templateUrl: '/app/src/contacts/view/organization.html',
                    controller: 'OrganizationController',
                    controllerAs: 'vm'
                }
            },
            data: {
                authorizedRoles: [USER_ROLES.user]
            }
        }).state('administration.groups', {
            parent: 'administration',
            url: '/groups',
            views: {
                'content@': {
                    templateUrl: '/app/src/groups/view/groups.html',
                    controller: 'GroupController',
                    controllerAs: 'vm'
                }
            },
            data: {
                authorizedRoles: [USER_ROLES.user],
                selectedTab: 1
            }
        }).state('administration.groups.group', {
            parent: 'administration',
            url: '/groups/group',
            views: {
                'content@': {
                    templateUrl: '/app/src/groups/view/group.html',
                    controller: 'GroupController',
                    controllerAs: 'vm'
                }
            },
            data: {
                authorizedRoles: [USER_ROLES.user],
                selectedTab: 1
            }
        });
    }

})();
<commit_msg>no message<commit_after>(function() {
    'use strict';

    angular
        .module('openeApp', [
            'ngSanitize',
            'ngMaterial',
            'ui.router',
            'ngResource',
            'ngPDFViewer',
            'swfobject',
            'isteven-multi-select',
            'openeApp.translations',
            'openeApp.cases',
            'openeApp.cases.members',
            'openeApp.cases.parties',
            'openeApp.classification',
            'openeApp.dashboard',
            'openeApp.files',
            'openeApp.tasks',
            'openeApp.documents',
            'openeApp.notes',
            'openeApp.contacts',
            'openeApp.administration',
            'openeApp.office',
            'openeApp.groups'
        ])
        .constant('USER_ROLES', {
            admin: 'admin',
            user: 'user',
            guest: 'guest'
        })
        .constant('ALFRESCO_URI', {
            apiProxy: '/alfresco/api/',
            serviceApiProxy: '/alfresco/service/api/',
            serviceSlingshotProxy: '/alfresco/service/slingshot/'
        })
        .config(config)
        .run(function($rootScope, $state, $stateParams, authService) {
            $rootScope.$on('$stateChangeStart', function(event, next, params) {
                $rootScope.toState = next;
                $rootScope.toStateParams = params;
                if (next.data.authorizedRoles.length == 0) {
                    return;
                }
                if (authService.isAuthenticated()) {

                } else {
                    event.preventDefault();
                    $rootScope.returnToState = $rootScope.toState;
                    $rootScope.returnToStateParams = $rootScope.toStateParams;
                    $state.go('login');
                }
//                console.log('authenticated? ', authService.isAuthenticated());
//                if (!authService.isAuthenticated()) {
//                    event.preventDefault();
//                    $state.go('login');
//                }
            });
        });

    config.$inject = ['$mdThemingProvider', '$stateProvider', '$urlRouterProvider', 'USER_ROLES', '$mdIconProvider'];

    function config($mdThemingProvider, $stateProvider, $urlRouterProvider, USER_ROLES, $mdIconProvider) {
        $mdThemingProvider.theme('default')
            .primaryPalette('blue', {
              'default': '600',
              'hue-1': '400',
              'hue-2': '800',
              'hue-3': '900'
            })
            .accentPalette('amber')
            .warnPalette('deep-orange');

        $mdIconProvider.icon('md-calendar', '/app/assets/img/icons/today.svg');

        $urlRouterProvider.otherwise('/');

        $stateProvider.state('site', {
            abstract: true,
            resolve: {
                authorize: ['authService', function(authService) {
                }]
            }
        }).state('dashboard', {
            parent: 'site',
            url: '/',
            views: {
                'content@': {
                    templateUrl: '/app/src/dashboard/view/dashboard.html',
                    controller: 'DashboardController'
                }
            },
            data: {
                authorizedRoles: [USER_ROLES.user]
            }
        }).state('cases', {
            parent: 'site',
            url: '/cases',
            views: {
                'content@': {
                    templateUrl: '/app/src/cases/view/cases.html',
                    controller: 'CaseController',
                    controllerAs: 'vm'
                }
            },
            data: {
                authorizedRoles: [USER_ROLES.user]
            }
        }).state('caseinfo', {
            parent: 'site',
            url: '/cases/case/:caseId',
            views: {
                'content@': {
                    templateUrl: '/app/src/cases/view/case.html',
                    controller: 'CaseInfoController',
                    controllerAs: 'vm'
                }
            },
            data: {
                authorizedRoles: [USER_ROLES.user]
            }
        }).state('docDetails', {
            parent: 'site',
            url: '/cases/case/:caseId/doc/:storeType/:storeId/:id',
            views: {
                'content@': {
                    controller : 'DocumentDetailsController',
                    templateUrl : 'app/src/documents/view/document.html',
                    controllerAs: 'docCtrl'
                }
            },
            data: {
                authorizedRoles: [USER_ROLES.user]
            }
        }).state('login', {
            parent: 'site',
            url: '/login',
            views: {
                'content@': {
                    templateUrl: '/app/src/authentication/view/login.html',
                    controller: 'AuthController',
                    controllerAs: 'vm'
                }
            },
            data: {
                authorizedRoles: []
            }
        }).state('tasks', {
            parent: 'site',
            url: '/tasks',
            views: {
                'content@': {
                    templateUrl : '/app/src/tasks/view/tasks.html',
                    controller : 'tasksOverviewController',
                    controllerAs: 'tasksCtrl'
                }
            },
            data: {
                authorizedRoles: [USER_ROLES.user]
            }
        }).state('administration', {
            parent: 'site',
            url: '/admin',
            views: {
                'content@': {
                    templateUrl : '/app/src/admin/view/admin.html',
                    controller : 'AdminController',
                    controllerAs: 'vm',
                }
            },
            data: {
                authorizedRoles: [USER_ROLES.user]
            }
        }).state('administration.organizations', {
            parent: 'site',
            url: '/admin/organizations',
            views: {
                'content@': {
                    templateUrl: '/app/src/admin/view/admin.html',
                    controller: 'AdminController',
                    controllerAs: 'vm'
                }
            },
            data: {
                authorizedRoles: [USER_ROLES.user],
                selectedTab: 2
            }
        }).state('administration.contacts', {
            parent: 'site',
            url: '/admin/contacts',
            views: {
                'content@': {
                    templateUrl: '/app/src/admin/view/admin.html',
                    controller: 'AdminController',
                    controllerAs: 'vm'
                }
            },
            data: {
                authorizedRoles: [USER_ROLES.user],
                selectedTab: 3
            }
        }).state('administration.organizations.organization', {
            parent: 'site',
            url: '/admin/organizations/:storeProtocol/:storeIdentifier/:uuid',
            views: {
                'content@': {
                    templateUrl: '/app/src/contacts/view/organization.html',
                    controller: 'OrganizationController',
                    controllerAs: 'vm'
                }
            },
            data: {
                authorizedRoles: [USER_ROLES.user]
            }
        }).state('administration.groups', {
            parent: 'administration',
            url: '/groups',
            views: {
                'content@': {
                    templateUrl: '/app/src/groups/view/groups.html',
                    controller: 'GroupController',
                    controllerAs: 'vm'
                }
            },
            data: {
                authorizedRoles: [USER_ROLES.user],
                selectedTab: 1
            }
        }).state('administration.groups.group', {
            parent: 'administration',
            url: '/groups/group',
            views: {
                'content@': {
                    templateUrl: '/app/src/groups/view/group.html',
                    controller: 'GroupController',
                    controllerAs: 'vm'
                }
            },
            data: {
                authorizedRoles: [USER_ROLES.user],
                selectedTab: 1
            }
        });
    }

})();
<|endoftext|>


<commit_before>/*#ifndef(UMD)*/
"use strict";
/*global _gpfIgnore*/ // Helper to remove unused parameter warning
/*global _gpfStringReplaceEx*/ // String replacement using dictionary map
/*exported _gpfErrorDeclare*/
/*#endif*/

var
    /**
     * GPF Error class
     *
     * @constructor
     * @class _GpfError
     * @alias gpf.Error
     */
    _GpfError = gpf.Error = function () {
    },

    /**
     * Generates an error function
     *
     * @param {Number} code
     * @param {String} name
     * @return {Function}
     * @closure
     * @private
     */
    _gpfGenErrorName = function (code, name, message) {
        var result = function (context) {
            var
                error = new gpf.Error(),
                finalMessage,
                replacements,
                key;
            gpf.setReadOnlyProperty(error, "code", code);
            gpf.setReadOnlyProperty(error, "name", name);
            if (context) {
                replacements = {};
                for (key in context) {
                    if (context.hasOwnProperty(key)) {
                        replacements["{" + key + "}"] =
                            context[key].toString();
                    }
                }
                finalMessage = _gpfStringReplaceEx(message,
                    replacements);
            } else {
                finalMessage = message;
            }
            gpf.setReadOnlyProperty(error, "message", finalMessage);
            return error;
        };
        gpf.setReadOnlyProperty(result, "CODE", code);
        gpf.setReadOnlyProperty(result, "NAME", name);
        gpf.setReadOnlyProperty(result, "MESSAGE", message);
        return result;
    },

    /**
     * Last allocated error code
     *
     * @type {number}
     * @private
     */
    _gpfLastErrorCode = 0,

    /**
     * Declare error messages.
     * Each module declares its own errors.
     *
     * @param {String} module
     * @param {Object} list Dictionary of name to message
     * @private
     */
    _gpfErrorDeclare = function (module, list) {
        var
            name,
            code;
        _gpfIgnore(module);
        for (name in list) {
            if (list.hasOwnProperty(name)) {
                code = ++_gpfLastErrorCode;
                gpf.Error["CODE_" + name.toUpperCase()] = code;
                gpf.Error[name] = _gpfGenErrorName(code, name, list[name]);
            }
        }
    };

_GpfError.prototype = {

    constructor: _GpfError,

    /**
     * Error code
     *
     * @type {Number}
     * @read-only
     */
    code: 0,

    /**
     * Error name
     *
     * @type {String}
     * @read-only
     */
    name: "Error",

    /**
     * Error message
     *
     * @type {String}
     * @read-only
     */
    message: ""

};

_gpfErrorDeclare("boot", {
    NotImplemented:
        "Not implemented",
    Abstract:
        "Abstract",
    AssertionFailed:
        "Assertion failed: {message}"
});<commit_msg>InvalidParameter error<commit_after>/*#ifndef(UMD)*/
"use strict";
/*global _gpfIgnore*/ // Helper to remove unused parameter warning
/*global _gpfStringReplaceEx*/ // String replacement using dictionary map
/*exported _gpfErrorDeclare*/
/*#endif*/

var
    /**
     * GPF Error class
     *
     * @constructor
     * @class _GpfError
     * @alias gpf.Error
     */
    _GpfError = gpf.Error = function () {
    },

    /**
     * Generates an error function
     *
     * @param {Number} code
     * @param {String} name
     * @return {Function}
     * @closure
     * @private
     */
    _gpfGenErrorName = function (code, name, message) {
        var result = function (context) {
            var
                error = new gpf.Error(),
                finalMessage,
                replacements,
                key;
            gpf.setReadOnlyProperty(error, "code", code);
            gpf.setReadOnlyProperty(error, "name", name);
            if (context) {
                replacements = {};
                for (key in context) {
                    if (context.hasOwnProperty(key)) {
                        replacements["{" + key + "}"] =
                            context[key].toString();
                    }
                }
                finalMessage = _gpfStringReplaceEx(message,
                    replacements);
            } else {
                finalMessage = message;
            }
            gpf.setReadOnlyProperty(error, "message", finalMessage);
            return error;
        };
        gpf.setReadOnlyProperty(result, "CODE", code);
        gpf.setReadOnlyProperty(result, "NAME", name);
        gpf.setReadOnlyProperty(result, "MESSAGE", message);
        return result;
    },

    /**
     * Last allocated error code
     *
     * @type {number}
     * @private
     */
    _gpfLastErrorCode = 0,

    /**
     * Declare error messages.
     * Each module declares its own errors.
     *
     * @param {String} module
     * @param {Object} list Dictionary of name to message
     * @private
     */
    _gpfErrorDeclare = function (module, list) {
        var
            name,
            code;
        _gpfIgnore(module);
        for (name in list) {
            if (list.hasOwnProperty(name)) {
                code = ++_gpfLastErrorCode;
                gpf.Error["CODE_" + name.toUpperCase()] = code;
                gpf.Error[name] = _gpfGenErrorName(code, name, list[name]);
            }
        }
    };

_GpfError.prototype = {

    constructor: _GpfError,

    /**
     * Error code
     *
     * @type {Number}
     * @read-only
     */
    code: 0,

    /**
     * Error name
     *
     * @type {String}
     * @read-only
     */
    name: "Error",

    /**
     * Error message
     *
     * @type {String}
     * @read-only
     */
    message: ""

};

_gpfErrorDeclare("boot", {
    NotImplemented:
        "Not implemented",
    Abstract:
        "Abstract",
    AssertionFailed:
        "Assertion failed: {message}",
    InvalidParameter:
        "Invalid parameter"
});<|endoftext|>