<commit_before>// @flow
/* eslint-disable jsx-a11y/href-no-hash */

import * as React from "react";
import Toast from "libs/toast";
import messages from "messages";
import { Link, withRouter } from "react-router-dom";
import { Dropdown, Menu, Icon } from "antd";
import type { APIMaybeUnimportedDatasetType } from "admin/api_flow_types";
import type { RouterHistory } from "react-router-dom";
import { createExplorational, triggerDatasetClearCache } from "admin/admin_rest_api";
import features from "features";

type Props = {
  dataset: APIMaybeUnimportedDatasetType,
  isUserAdmin: boolean,
  history: RouterHistory,
};

type State = {};

class DatasetActionView extends React.PureComponent<Props, State> {
  createTracing = async (
    dataset: APIMaybeUnimportedDatasetType,
    typ: "skeleton" | "volume" | "hybrid",
    withFallback: boolean,
  ) => {
    const annotation = await createExplorational(dataset.name, typ, withFallback);
    this.props.history.push(`/annotations/${annotation.typ}/${annotation.id}`);
  };

  clearCache = async (dataset: APIMaybeUnimportedDatasetType) => {
    await triggerDatasetClearCache(dataset.dataStore.url, dataset.name);
    Toast.success(messages["dataset.clear_cache_success"]);
  };

  render() {
    const dataset = this.props.dataset;
    const centerBackgroundImageStyle = {
      verticalAlign: "middle",
    };

    const menu = (
      <Menu>
        <Menu.Item key="existing">
           this.createTracing(dataset, "volume", true)}
            title="Create volume tracing"
          >
            Use Existing Segmentation Layer

        </Menu.Item>
        <Menu.Item key="new">
           this.createTracing(dataset, "volume", false)}
            title="Create volume tracing"
          >
            Use a New Segmentation Layer

        </Menu.Item>
      </Menu>
    );

    const volumeTracingMenu = (
      <Dropdown overlay={menu} trigger={["click"]}>

          {" "}
          Start Volume Tracing

      </Dropdown>
    );

    return (

        {this.props.isUserAdmin && dataset.dataSource.dataLayers == null ? (

            <Link to={`/datasets/${dataset.name}/import`} className="import-dataset">
              <Icon type="plus-circle-o" />Import
            </Link>

{dataset.dataSource.status}

        ) : null}
        {dataset.isActive ? (

            {this.props.isUserAdmin && dataset.isEditable ? (
              <React.Fragment>
                <Link to={`/datasets/${dataset.name}/edit`} title="Edit Dataset">
                  <Icon type="edit" />Edit
                </Link>
                 this.clearCache(dataset)} title="Reload Dataset">
                  <Icon type="retweet" />Reload

              </React.Fragment>
            ) : null}
            <a href={`/datasets/${dataset.name}/view`} title="View Dataset">
              <Icon type="eye-o" />View

             this.createTracing(dataset, "skeleton", false)}
              title="Create Skeleton Tracing"
            >
              {" "}
              Start Skeleton Tracing

            {volumeTracingMenu}
            {features().hybridTracings ? (
               this.createTracing(dataset, "hybrid", true)}
                title="Create Hybrid Tracing"
              >
                <Icon type="swap" />
                Start Hybrid Tracing

            ) : null}

        ) : null}

    );
  }
}

export default withRouter(DatasetActionView);
<commit_msg>add warning tooltip to hybrid tracing button (#3090)<commit_after>// @flow
/* eslint-disable jsx-a11y/href-no-hash */

import * as React from "react";
import Toast from "libs/toast";
import messages from "messages";
import { Link, withRouter } from "react-router-dom";
import { Dropdown, Menu, Icon, Tooltip } from "antd";
import type { APIMaybeUnimportedDatasetType } from "admin/api_flow_types";
import type { RouterHistory } from "react-router-dom";
import { createExplorational, triggerDatasetClearCache } from "admin/admin_rest_api";
import features from "features";

type Props = {
  dataset: APIMaybeUnimportedDatasetType,
  isUserAdmin: boolean,
  history: RouterHistory,
};

type State = {};

class DatasetActionView extends React.PureComponent<Props, State> {
  createTracing = async (
    dataset: APIMaybeUnimportedDatasetType,
    typ: "skeleton" | "volume" | "hybrid",
    withFallback: boolean,
  ) => {
    const annotation = await createExplorational(dataset.name, typ, withFallback);
    this.props.history.push(`/annotations/${annotation.typ}/${annotation.id}`);
  };

  clearCache = async (dataset: APIMaybeUnimportedDatasetType) => {
    await triggerDatasetClearCache(dataset.dataStore.url, dataset.name);
    Toast.success(messages["dataset.clear_cache_success"]);
  };

  render() {
    const dataset = this.props.dataset;
    const centerBackgroundImageStyle = {
      verticalAlign: "middle",
    };

    const menu = (
      <Menu>
        <Menu.Item key="existing">
           this.createTracing(dataset, "volume", true)}
            title="Create volume tracing"
          >
            Use Existing Segmentation Layer

        </Menu.Item>
        <Menu.Item key="new">
           this.createTracing(dataset, "volume", false)}
            title="Create volume tracing"
          >
            Use a New Segmentation Layer

        </Menu.Item>
      </Menu>
    );

    const volumeTracingMenu = (
      <Dropdown overlay={menu} trigger={["click"]}>

          {" "}
          Start Volume Tracing

      </Dropdown>
    );

    return (

        {this.props.isUserAdmin && dataset.dataSource.dataLayers == null ? (

            <Link to={`/datasets/${dataset.name}/import`} className="import-dataset">
              <Icon type="plus-circle-o" />Import
            </Link>

{dataset.dataSource.status}

        ) : null}
        {dataset.isActive ? (

            {this.props.isUserAdmin && dataset.isEditable ? (
              <React.Fragment>
                <Link to={`/datasets/${dataset.name}/edit`} title="Edit Dataset">
                  <Icon type="edit" />Edit
                </Link>
                 this.clearCache(dataset)} title="Reload Dataset">
                  <Icon type="retweet" />Reload

              </React.Fragment>
            ) : null}
            <a href={`/datasets/${dataset.name}/view`} title="View Dataset">
              <Icon type="eye-o" />View

             this.createTracing(dataset, "skeleton", false)}
              title="Create Skeleton Tracing"
            >
              {" "}
              Start Skeleton Tracing

            {volumeTracingMenu}
            {features().hybridTracings ? (
               this.createTracing(dataset, "hybrid", true)}
                title="Create Hybrid Tracing"
              >
                <Icon type="swap" />
                {"Start Hybrid Tracing "}
                <Tooltip title="Experimental" placement="topLeft">
                  <Icon type="exclamation-circle-o" style={{ color: "orange" }} />
                </Tooltip>

            ) : null}

        ) : null}

    );
  }
}

export default withRouter(DatasetActionView);
<|endoftext|>


<commit_before>import logger from 'loglevel'
import _ from 'lodash'
import sift from 'sift'
import feathers from '@feathersjs/client'
import io from 'socket.io-client'
import reactive from 'feathers-reactive'
import config from 'config'
import { permissions } from '../common'
import { Store } from './store'
import Vue from 'vue'
import { Platform } from 'quasar'
import { Events } from './events'

// Register some global filters for case conversions
Vue.filter('kebabCase', (value) => _.kebabCase(value))
Vue.filter('camelCase', (value) => _.camelCase(value))
Vue.filter('lowerCase', (value) => _.lowerCase(value))
Vue.filter('snakeCase', (value) => _.snakeCase(value))
Vue.filter('startCase', (value) => _.startCase(value))
Vue.filter('upperCase', (value) => _.upperCase(value))

function getBaseUrlStorageKey () {
  return config.appName + '-baseUrl'
}

function siftMatcher (originalQuery) {
  // Filter out Feathers specific operators like $limit, $skip, etc.
  // (copied from https://github.com/feathersjs-ecosystem/feathers-reactive)
  const keysToOmit = Object.keys(originalQuery).filter(key => key.charCodeAt(0) === 36)
  const query = _.omit(originalQuery, ...keysToOmit)
  // Compatibility with fuzzy search that use $search query syntax
  _.forOwn(query, (value, key) => {
    if ((typeof value === 'object') && _.has(value, '$search')) {
      query[key] = { $regex: new RegExp(_.get(value, '$search'), 'i') }
    }
  })
  return sift(query)
}

export function kalisio () {
  let api = feathers()

  // Setup our interface
  // -------------------

  // This avoid managing the API path before each service name
  // If a context is not given it will be retrieved from the store if any and used for contextual services
  api.getServicePath = function (name, context, withApiPrefix = true) {
    const options = _.get(api.serviceOptions, name, {})
    let path
    // For non-contextual services path is always the name
    if (!options.context) {
      path = name
    } else {
      // Context is given as string ID or object ?
      if (typeof context === 'string') {
        if (context) path = context + '/' + name
        // Force global context on empty string
        else path = name
      } else if (typeof context === 'object') {
        if (context && context._id) path = context._id + '/' + name
        // Force global context on empty object
        else path = name
      } else {
        // Otherwise test for current context as service is registered as contextual
        const context = Store.get('context')
        if (context) {
          path = api.getServicePath(name, context, false)
        } else {
          // Because it could also be registered as global with the same name fallback
          path = name
        }
      }
    }

    if (withApiPrefix) {
      path = config.apiPath + '/' + path
    }
    return path
  }
  api.getService = function (name, context) {
    const path = api.getServicePath(name, context)
    let service = api.service(path)
    if (!service) {
      throw new Error('Cannot retrieve service ' + name + ' for context ' + (typeof context === 'object' ? context._id : context))
    }
    // Store the path on first call
    if (!service.path) service.path = path
    return service
  }
  // Used to register an existing backend service with its options
  api.declareService = function (name, options = {}) {
    _.set(api.serviceOptions, name, options)
  }
  // Used to create a frontend only service with its options
  api.createService = function (name, options = {}) {
    let servicePath = options.path || name
    let contextId
    if (options.context) {
      contextId = (typeof options.context === 'object' ? options.context._id : options.context)
      servicePath = contextId + '/' + servicePath
    }
    servicePath = config.apiPath + '/' + servicePath
    api.declareService(name, options)
    let service = options.service
    // If we get a function try to call it assuming it will return the service object
    if (typeof options.service === 'function') {
      service = service(name, api, options)
    }
    service = api.use(servicePath, service)
    if (options.hooks) service.hooks(options.hooks)
    return api.service(servicePath)
  }
  // Change the base URL/domain to be used (useful for mobile apps)
  api.setBaseUrl = function (baseUrl) {
    window.localStorage.setItem(getBaseUrlStorageKey(), baseUrl)
    // Updating this setting live does not seem to work well in Feathers
    // For now the caller should simply "reload" the app
    /*
    if (config.transport === 'http') {
      Object.keys(this.services).forEach(path => {
        const service = this.service(path)
        if (service.base) {
          service.base = `${baseUrl}/${path}`
        }
      })
    } else {
      let socket = io(baseUrl, {
        transports: ['websocket'],
        path: config.apiPath + 'ws'
      })
      this.configure(feathers.socketio(socket))
    }
    */
  }

  api.getBaseUrl = function () {
    // FIXME: for test
    let isMobile = Platform.is.cordova || Platform.is.ios
    let origin = isMobile ? config.domain : window.location.origin
    // Check for registered custom base Url if any
    if (window.localStorage.getItem(getBaseUrlStorageKey())) {
      origin = window.localStorage.getItem(getBaseUrlStorageKey())
    }
    return origin
  }

  api.can = function (operation, service, context, resource) {
    let abilities = Store.get('user.abilities')
    logger.debug('Check for abilities ', operation, service, context, resource, abilities)
    if (!abilities) {
      logger.debug('Access denied without abilities')
      return false
    }
    // Check for access to service fisrt
    const path = api.getServicePath(service, context, false)
    let result = permissions.hasServiceAbilities(abilities, path)
    if (!result) {
      logger.debug('Access to service path ' + path + ' denied')
      return false
    } else if (operation === 'service') {
      // When we only check for service-level access return
      return true
    }
    // Then for access to resource
    result = permissions.hasResourceAbilities(abilities, operation, service, context, resource)
    if (!result) {
      logger.debug('Access to resource denied')
    } else {
      logger.debug('Access to resource granted')
    }
    return result
  }

  // Setup log level
  if (config.logs && config.logs.level) {
    logger.setLevel(config.logs.level, false)
  } else {
    logger.setLevel('info')
  }
  let origin = api.getBaseUrl()
  if (config.transport === 'http') {
    api.configure(feathers.rest(origin).fetch(window.fetch.bind(window)))
  } else {
    api.socket = io(origin, {
      transports: ['websocket'],
      path: config.apiPath + 'ws'
    })
    api.configure(feathers.socketio(api.socket, { timeout: config.apiTimeout || 10000 }))
    // Retrieve our specific errors on rate-limiting
    api.socket.on('rate-limit', (error) => Events.$emit('error', error))
  }
  api.configure(feathers.authentication({
    storage: window.localStorage,
    // FIXME: customize cookie/key name
    cookie: config.apiJwt || 'feathers-jwt',
    storageKey: config.apiJwt || 'feathers-jwt',
    path: config.apiPath + '/authentication'
  }))
  api.configure(reactive({
    idField: '_id',
    matcher: siftMatcher // Our custom matcher to handle fuzzy search
  }))
  // Object used to store configuration options for services
  api.serviceOptions = {}

  return api
}
<commit_msg>wip: https://github.com/kalisio/kdk/issues/31 (try to fix platform detection)<commit_after>import logger from 'loglevel'
import _ from 'lodash'
import sift from 'sift'
import feathers from '@feathersjs/client'
import io from 'socket.io-client'
import reactive from 'feathers-reactive'
import config from 'config'
import { permissions } from '../common'
import { Store } from './store'
import Vue from 'vue'
import { Platform } from 'quasar'
import { Events } from './events'

// Register some global filters for case conversions
Vue.filter('kebabCase', (value) => _.kebabCase(value))
Vue.filter('camelCase', (value) => _.camelCase(value))
Vue.filter('lowerCase', (value) => _.lowerCase(value))
Vue.filter('snakeCase', (value) => _.snakeCase(value))
Vue.filter('startCase', (value) => _.startCase(value))
Vue.filter('upperCase', (value) => _.upperCase(value))

function getBaseUrlStorageKey () {
  return config.appName + '-baseUrl'
}

function siftMatcher (originalQuery) {
  // Filter out Feathers specific operators like $limit, $skip, etc.
  // (copied from https://github.com/feathersjs-ecosystem/feathers-reactive)
  const keysToOmit = Object.keys(originalQuery).filter(key => key.charCodeAt(0) === 36)
  const query = _.omit(originalQuery, ...keysToOmit)
  // Compatibility with fuzzy search that use $search query syntax
  _.forOwn(query, (value, key) => {
    if ((typeof value === 'object') && _.has(value, '$search')) {
      query[key] = { $regex: new RegExp(_.get(value, '$search'), 'i') }
    }
  })
  return sift(query)
}

export function kalisio () {
  let api = feathers()

  // Setup our interface
  // -------------------

  // This avoid managing the API path before each service name
  // If a context is not given it will be retrieved from the store if any and used for contextual services
  api.getServicePath = function (name, context, withApiPrefix = true) {
    const options = _.get(api.serviceOptions, name, {})
    let path
    // For non-contextual services path is always the name
    if (!options.context) {
      path = name
    } else {
      // Context is given as string ID or object ?
      if (typeof context === 'string') {
        if (context) path = context + '/' + name
        // Force global context on empty string
        else path = name
      } else if (typeof context === 'object') {
        if (context && context._id) path = context._id + '/' + name
        // Force global context on empty object
        else path = name
      } else {
        // Otherwise test for current context as service is registered as contextual
        const context = Store.get('context')
        if (context) {
          path = api.getServicePath(name, context, false)
        } else {
          // Because it could also be registered as global with the same name fallback
          path = name
        }
      }
    }

    if (withApiPrefix) {
      path = config.apiPath + '/' + path
    }
    return path
  }
  api.getService = function (name, context) {
    const path = api.getServicePath(name, context)
    let service = api.service(path)
    if (!service) {
      throw new Error('Cannot retrieve service ' + name + ' for context ' + (typeof context === 'object' ? context._id : context))
    }
    // Store the path on first call
    if (!service.path) service.path = path
    return service
  }
  // Used to register an existing backend service with its options
  api.declareService = function (name, options = {}) {
    _.set(api.serviceOptions, name, options)
  }
  // Used to create a frontend only service with its options
  api.createService = function (name, options = {}) {
    let servicePath = options.path || name
    let contextId
    if (options.context) {
      contextId = (typeof options.context === 'object' ? options.context._id : options.context)
      servicePath = contextId + '/' + servicePath
    }
    servicePath = config.apiPath + '/' + servicePath
    api.declareService(name, options)
    let service = options.service
    // If we get a function try to call it assuming it will return the service object
    if (typeof options.service === 'function') {
      service = service(name, api, options)
    }
    service = api.use(servicePath, service)
    if (options.hooks) service.hooks(options.hooks)
    return api.service(servicePath)
  }
  // Change the base URL/domain to be used (useful for mobile apps)
  api.setBaseUrl = function (baseUrl) {
    window.localStorage.setItem(getBaseUrlStorageKey(), baseUrl)
    // Updating this setting live does not seem to work well in Feathers
    // For now the caller should simply "reload" the app
    /*
    if (config.transport === 'http') {
      Object.keys(this.services).forEach(path => {
        const service = this.service(path)
        if (service.base) {
          service.base = `${baseUrl}/${path}`
        }
      })
    } else {
      let socket = io(baseUrl, {
        transports: ['websocket'],
        path: config.apiPath + 'ws'
      })
      this.configure(feathers.socketio(socket))
    }
    */
  }

  api.getBaseUrl = function () {

    // let isMobile = Platform.is.cordova || Platform.is.ios
    let origin = Platform.is.cordova ? config.domain : window.location.origin
    // Check for registered custom base Url if any
    if (window.localStorage.getItem(getBaseUrlStorageKey())) {
      origin = window.localStorage.getItem(getBaseUrlStorageKey())
    }
    return origin
  }

  api.can = function (operation, service, context, resource) {
    let abilities = Store.get('user.abilities')
    logger.debug('Check for abilities ', operation, service, context, resource, abilities)
    if (!abilities) {
      logger.debug('Access denied without abilities')
      return false
    }
    // Check for access to service fisrt
    const path = api.getServicePath(service, context, false)
    let result = permissions.hasServiceAbilities(abilities, path)
    if (!result) {
      logger.debug('Access to service path ' + path + ' denied')
      return false
    } else if (operation === 'service') {
      // When we only check for service-level access return
      return true
    }
    // Then for access to resource
    result = permissions.hasResourceAbilities(abilities, operation, service, context, resource)
    if (!result) {
      logger.debug('Access to resource denied')
    } else {
      logger.debug('Access to resource granted')
    }
    return result
  }

  // Setup log level
  if (config.logs && config.logs.level) {
    logger.setLevel(config.logs.level, false)
  } else {
    logger.setLevel('info')
  }
  let origin = api.getBaseUrl()
  if (config.transport === 'http') {
    api.configure(feathers.rest(origin).fetch(window.fetch.bind(window)))
  } else {
    api.socket = io(origin, {
      transports: ['websocket'],
      path: config.apiPath + 'ws'
    })
    api.configure(feathers.socketio(api.socket, { timeout: config.apiTimeout || 10000 }))
    // Retrieve our specific errors on rate-limiting
    api.socket.on('rate-limit', (error) => Events.$emit('error', error))
  }
  api.configure(feathers.authentication({
    storage: window.localStorage,
    // FIXME: customize cookie/key name
    cookie: config.apiJwt || 'feathers-jwt',
    storageKey: config.apiJwt || 'feathers-jwt',
    path: config.apiPath + '/authentication'
  }))
  api.configure(reactive({
    idField: '_id',
    matcher: siftMatcher // Our custom matcher to handle fuzzy search
  }))
  // Object used to store configuration options for services
  api.serviceOptions = {}

  return api
}
<|endoftext|>


<commit_before>/**
 * Created with JetBrains RubyMine.
 * User: teamco
 * Date: 11/5/12
 * Time: 9:17 PM
 * To change this template use File | Settings | File Templates.
 */
define(
    [
        'config/anthill',
        'modules/Controller',
        'config/routes'
    ],
    /**
     * Define Application controller
     * @param {AntHill} AntHill
     * @param {BaseController} BaseController
     * @param {Routes} Routes
     * @returns {AppController}
     */
    function defineApplicationController(AntHill, BaseController, Routes) {

        /**
         * Define application controller
         * @class AppController
         * @extends AntHill
         * @extends BaseController
         * @extends Routes
         * @constructor
         */
        var AppController = function AppController() {
        };

        return AppController.extend(
            'AppController', {

                /**
                 * Define Load Application
                 * @member AppController
                 */
                loadApplication: function loadApplication() {

                    // Render app
                    this.view.render();

                    // Load initial
                    if (!this.model.loadData()) {

                        this.model.setConfig('loading', true);

                        this.api.createWorkspace([], true).
                            api.createPage([], true);

                        this.model.setConfig('loading', false);
                    }
                },

                /**
                 * Define global instance
                 * @member AppController
                 */
                defineGlobalInstance: function defineGlobalInstance() {
                    this.logger.debug(
                        'Define global instance',
                        this.model.getConfig('appName')
                    );
                },

                /**
                 * Define setting
                 * @member AppController
                 */
                defineSetting: function defineSetting() {
                    this.model.initGlobalSetting();
                    this.controller.ajaxSetup();
                },

                /**
                 * Update storage version
                 * @member AppController
                 * @param {number} version
                 */
                updateStorageVersion: function updateStorageVersion(version) {
                    this.logger.debug('Update storage version', version);
                    this.model.setConfig('version', version);
                    this.model.setConfig('activate', true);
                },

                /**
                 * Define ajax setup
                 * @member AppController
                 */
                ajaxSetup: function ajaxSetup() {

                    $.ajaxSetup({
                        beforeSend: function beforeSend(xhr, settings) {
                            if (typeof(settings.dataType) === 'undefined') {
                                xhr.setRequestHeader(
                                    'accept',
                                    '*/*;q=0.5, ' + settings.accepts.script
                                );
                            }
                            xhr.setRequestHeader(
                                'X-CSRF-Token',
                                this.getXCsrfToken()
                            );
                        }.bind(this),
                        error: this.handleError.bind(this)
                    });
                },

                /**
                 * Define error handler
                 * @member AppController
                 */
                handleError: function handleError(xhr, status, description) {
                    this.scope.logger.warn('Ajax error', arguments);
                },

                /**
                 * Load updated uuid
                 * @member AppController
                 * @param {string} uuid
                 */
                loadConfig: function loadConfig(uuid) {
                    this.model.setConfig('uuid', uuid);
                    this.scope.view.get$item().updateUUID();

                    this.scope.logger.debug('Update uuid after loading', uuid);
                },

                /**
                 * Init window resize
                 * @member AppController
                 */
                initResizeWindow: function initResizeWindow() {

                    this.logger.debug('Init window resize');

                    /**
                     * Define resize callback
                     * @type {function(this:Controller)}
                     */
                    var callback = this.controller.resizeWindowPublisher.
                        bind(this);

                    $(window).on('resizestop', callback);
                },

                /**
                 * Resize window publisher
                 * @member AppController
                 * @param e
                 */
                resizeWindowPublisher: function resizeWindowPublisher(e) {

                    if (e.target === window && this.model.getConfig('isResized')) {
                        this.observer.publish(
                            this.eventmanager.eventList.resizeWindow,
                            e
                        );
                    }
                },

                /**
                 * Resize window callback
                 * @member AppController
                 * @param e
                 */
                resizeWindow: function resizeWindow(e) {
                    this.logger.debug('Start resize window', e);

                    this.observer.publish(
                        this.eventmanager.eventList.resizeWindowHooks
                    );
                },

                /**
                 * Resize window hooks
                 * @member AppController
                 */
                resizeWindowHooks: function resizeWindowHooks() {
                    this.logger.debug('Start resize window hooks', arguments);
                },

                /**
                 * Create authoring panel
                 * @member AppController
                 */
                createAuthorPanel: function createAuthorPanel() {
                    this.logger.debug('Create authoring panel', arguments);
                },

                /**
                 * Create tool panel
                 * @member AppController
                 */
                createToolPanel: function createToolPanel() {
                    this.logger.debug('Create tool panel', arguments);
                },

                /**
                 * Approve clear data
                 * @member AppController
                 */
                approveClearData: function approveClearData() {

                    /**
                     * Define local scope
                     */
                    var scope = this.scope;

                    /**
                     * Define setting
                     * @type {Setting}
                     */
                    var setting = scope.model.setting,
                        $modal = scope.view.elements.$modal;

                    setting.clear();

                    scope.logger.warn('localStorage', setting.getStorage());

                    if (this.base.isDefined($modal)) {
                        $modal.selfDestroy();
                    }
                }

            },
            AntHill.prototype,
            BaseController.prototype,
            Routes.prototype
        );
    }
);<commit_msg>handle logs ajax<commit_after>/**
 * Created with JetBrains RubyMine.
 * User: teamco
 * Date: 11/5/12
 * Time: 9:17 PM
 * To change this template use File | Settings | File Templates.
 */
define(
    [
        'config/anthill',
        'modules/Controller',
        'config/routes'
    ],
    /**
     * Define Application controller
     * @param {AntHill} AntHill
     * @param {BaseController} BaseController
     * @param {Routes} Routes
     * @returns {AppController}
     */
    function defineApplicationController(AntHill, BaseController, Routes) {

        /**
         * Define application controller
         * @class AppController
         * @extends AntHill
         * @extends BaseController
         * @extends Routes
         * @constructor
         */
        var AppController = function AppController() {
        };

        return AppController.extend(
            'AppController', {

                /**
                 * Define Load Application
                 * @member AppController
                 */
                loadApplication: function loadApplication() {

                    // Render app
                    this.view.render();

                    // Load initial
                    if (!this.model.loadData()) {

                        this.model.setConfig('loading', true);

                        this.api.createWorkspace([], true).
                            api.createPage([], true);

                        this.model.setConfig('loading', false);
                    }
                },

                /**
                 * Define global instance
                 * @member AppController
                 */
                defineGlobalInstance: function defineGlobalInstance() {
                    this.logger.debug(
                        'Define global instance',
                        this.model.getConfig('appName')
                    );
                },

                /**
                 * Define setting
                 * @member AppController
                 */
                defineSetting: function defineSetting() {
                    this.model.initGlobalSetting();
                    this.controller.ajaxSetup();
                },

                /**
                 * Update storage version
                 * @member AppController
                 * @param {number} version
                 */
                updateStorageVersion: function updateStorageVersion(version) {
                    this.logger.debug('Update storage version', version);
                    this.model.setConfig('version', version);
                    this.model.setConfig('activate', true);
                },

                /**
                 * Define ajax setup
                 * @member AppController
                 */
                ajaxSetup: function ajaxSetup() {

                    $.ajaxSetup({
                        ifModified: true,
                        beforeSend: function beforeSend(xhr, settings) {
                            if (typeof(settings.dataType) === 'undefined') {
                                xhr.setRequestHeader(
                                    'accept',
                                    '*/*;q=0.5, ' + settings.accepts.script
                                );
                            }
                            xhr.setRequestHeader(
                                'X-CSRF-Token',
                                this.getXCsrfToken()
                            );
                        }.bind(this),
                        success: this._handleXhrLog.bind(this),
                        complete: this._handleXhrLog.bind(this),
                        error: this._handleXhrLog.bind(this)
                    });
                },

                /**
                 * Define error handler
                 * @member AppController
                 */
                _handleXhrLog: function _handleXhrLog(xhr, status, description) {
                    this.scope.logger[status === 'error' ? 'warn' : 'debug'](
                        status, description, arguments
                    );
                },

                /**
                 * Load updated uuid
                 * @member AppController
                 * @param {string} uuid
                 */
                loadConfig: function loadConfig(uuid) {
                    this.model.setConfig('uuid', uuid);
                    this.scope.view.get$item().updateUUID();

                    this.scope.logger.debug('Update uuid after loading', uuid);
                },

                /**
                 * Init window resize
                 * @member AppController
                 */
                initResizeWindow: function initResizeWindow() {

                    this.logger.debug('Init window resize');

                    /**
                     * Define resize callback
                     * @type {function(this:Controller)}
                     */
                    var callback = this.controller.resizeWindowPublisher.
                        bind(this);

                    $(window).on('resizestop', callback);
                },

                /**
                 * Resize window publisher
                 * @member AppController
                 * @param e
                 */
                resizeWindowPublisher: function resizeWindowPublisher(e) {

                    if (e.target === window && this.model.getConfig('isResized')) {
                        this.observer.publish(
                            this.eventmanager.eventList.resizeWindow,
                            e
                        );
                    }
                },

                /**
                 * Resize window callback
                 * @member AppController
                 * @param e
                 */
                resizeWindow: function resizeWindow(e) {
                    this.logger.debug('Start resize window', e);

                    this.observer.publish(
                        this.eventmanager.eventList.resizeWindowHooks
                    );
                },

                /**
                 * Resize window hooks
                 * @member AppController
                 */
                resizeWindowHooks: function resizeWindowHooks() {
                    this.logger.debug('Start resize window hooks', arguments);
                },

                /**
                 * Create authoring panel
                 * @member AppController
                 */
                createAuthorPanel: function createAuthorPanel() {
                    this.logger.debug('Create authoring panel', arguments);
                },

                /**
                 * Create tool panel
                 * @member AppController
                 */
                createToolPanel: function createToolPanel() {
                    this.logger.debug('Create tool panel', arguments);
                },

                /**
                 * Approve clear data
                 * @member AppController
                 */
                approveClearData: function approveClearData() {

                    /**
                     * Define local scope
                     */
                    var scope = this.scope;

                    /**
                     * Define setting
                     * @type {Setting}
                     */
                    var setting = scope.model.setting,
                        $modal = scope.view.elements.$modal;

                    setting.clear();

                    scope.logger.warn('localStorage', setting.getStorage());

                    if (this.base.isDefined($modal)) {
                        $modal.selfDestroy();
                    }
                }

            },
            AntHill.prototype,
            BaseController.prototype,
            Routes.prototype
        );
    }
);<|endoftext|>


<commit_before>var fs = require('fs'),
    cheerio = require('cheerio')

var txt = fs.readFileSync('./data/ui-xml/com.outfit7.talkingtom2free-83.xml', 'utf8')

//$ = cheerio.load(txt)
var $ = cheerio.load(txt, {
    recognizeSelfClosing: true
})

// number of buttons
$("Button").length

var n = $('ImageView[layout_centerInParent="true"]')
    // console.log(n)

$('ImageView').filter(function() {

    // console.log(this.attribs['android:scaletype'])

    return this.attribs['android:scaletype'] === 'fitCenter'

}).each(function() {

    console.log(">>",  this.attribs['android:id'])

    $(this).parents('File').each(function(){
        console.log(this.attribs)
    })
})<commit_msg>remove dead code<commit_after><|endoftext|>


<commit_before>l4.importScripts('src/sw/core.js');
l4.importScripts('src/sw/fetch.js');

l4.importScripts('src/sw/messaging-tasks/github/github.js');

l4.importScripts('src/external/focalStorage.js');

//l4.importScripts('src/sw/messaging-tasks/github/credentials.js');

(function() {

    var expression = /^(https:\/\/github.lively4\/)/;

    l4.fetchTask('fetch github', l4.urlMatch(expression), function(event) {
        var request = event.request

        console.log('GitHub fetch: ', request.url);
        // TODO: timeout?
        var ensureToken = function(githubToken) {
            return new Promise(function(resolve, reject) {
                if (!githubToken) {
                    console.log("githubToken not found")
                    var cbId = Date.now();
                    l4.registerCallback(cbId, function(token) {
                         return resolve(token);
                    })
                    self.clients.matchAll().then(function(clients) {
                        console.log("ask client for github token")
                        clients[0].postMessage({
                            name: "githubAuthTokenRequired",
                            callbackId: cbId
                        });
                    })
                } else {
                    resolve(githubToken)
                }
            });
        }
        var fetchWithToken = function(githubToken) {
            return new Promise(function(resolve, reject) {
                console.log("fetchWithToken " + githubToken)

                console.log('got githubCredentials');

                var githubCredentials = {
                    token: githubToken,
                    auth: 'oauth'
                }
                var s = request.url.replace(expression, '');
                var exp = new RegExp("([^/]*)/([^/]*)/([^/]*)/([^/]*)/(.*)")
                var match = exp.exec(s)

                // Example: https://github.lively4/repo/livelykernel/lively4-core/gh-pages/README.md

                var username = match[2],
                    reponame = match[3],
                    branch = match[4],
                    path = match[5]

                var method = request.method,
                    isPut = method === 'PUT';

                console.log('#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+');
                console.log('+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#');
                console.log('#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+');
                console.log(isPut);
                console.log('#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+');
                console.log('+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#');
                console.log('#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+#+');

                function sendGithubRequest(contentToWrite) {
                    var message = {
                        topLevelAPI: match[1],
                        topLevelArguments: [username, reponame],
                        method: isPut ? 'write' : 'read',
                        args: isPut ? [branch, path, contentToWrite, 'auto commit'] : [branch, path]
                    }

                    var topLevelAPIMapping = {
                        issues: 'getIssues',
                        repo: 'getRepo',
                        user: 'getUser',
                        gist: 'getGist'
                    };

                    var callback = function(err, data) {
                        console.log("resolve: " + resolve + " error:" + reject)
                        console.log("Github API response (fetch): ", err, data);

                        if(err) {
                            l4.broadCastMessage("Github error: " + JSON.stringify(err));
                            resolve(new Response("Error" + err))
                        }  else {
                            resolve(new Response(data))
                        }
                    };

                    var credentials = githubCredentials,
                        github = new Github(credentials),
                        topLevelAPIName = topLevelAPIMapping[message.topLevelAPI],
                        topLevelAPIFunction = github[topLevelAPIName],
                        apiObject = topLevelAPIFunction.apply(github, message.topLevelArguments),
                        methodName = message.method,
                        methodFunction = apiObject[methodName],
                        args = message.args.concat(callback);

                    methodFunction.apply(apiObject, args);
                }

                if(isPut) {
                    request.text().then(sendGithubRequest);
                } else {
                    sendGithubRequest();
                }
            });
        }

        return focalStorage.getItem("githubToken")
            .then(ensureToken)
            .then(fetchWithToken)
            .catch(function(err) {
                console.log("focalStorage Error: " + err)
                return // Error ??
            });
    })
})();
<commit_msg>clean up a bit<commit_after>l4.importScripts('src/sw/core.js');
l4.importScripts('src/sw/fetch.js');

l4.importScripts('src/sw/messaging-tasks/github/github.js');

l4.importScripts('src/external/focalStorage.js');

//l4.importScripts('src/sw/messaging-tasks/github/credentials.js');

(function() {
    var expression = /^(https:\/\/github.lively4\/)/;

    l4.fetchTask('fetch github', l4.urlMatch(expression), function(event) {
        var request = event.request;

        console.log('GitHub fetch: ', request.url);
        // TODO: timeout?
        function ensureToken(githubToken) {
            // TODO: user rejection not handled yet
            return new Promise(function(resolve, reject) {
                if (!githubToken) {
                    console.log("githubToken not found");
                    var cbId = Date.now();
                    l4.registerCallback(cbId, function(token) {
                         return resolve(token);
                    });
                    self.clients.matchAll().then(function(clients) {
                        console.log("ask client for github token");
                        clients[0].postMessage({
                            name: "githubAuthTokenRequired",
                            callbackId: cbId
                        });
                    })
                } else {
                    resolve(githubToken)
                }
            });
        }

        function fetchWithToken(githubToken) {
            return new Promise(function(resolve, reject) {
                console.log("fetchWithToken " + githubToken);

                console.log('got githubCredentials');

                var githubCredentials = {
                    token: githubToken,
                    auth: 'oauth'
                };
                var s = request.url.replace(expression, '');
                var exp = new RegExp("([^/]*)/([^/]*)/([^/]*)/([^/]*)/(.*)");
                var match = exp.exec(s);

                // Example: https://github.lively4/repo/livelykernel/lively4-core/gh-pages/README.md

                var username = match[2],
                    reponame = match[3],
                    branch = match[4],
                    path = match[5];

                var method = request.method,
                    isPut = method === 'PUT';

                function sendGithubRequest(contentToWrite) {
                    var message = {
                        topLevelAPI: match[1],
                        topLevelArguments: [username, reponame],
                        method: isPut ? 'write' : 'read',
                        args: isPut ? [branch, path, contentToWrite, 'auto commit'] : [branch, path]
                    };

                    var topLevelAPIMapping = {
                        issues: 'getIssues',
                        repo: 'getRepo',
                        user: 'getUser',
                        gist: 'getGist'
                    };

                    var callback = function(err, data) {
                        console.log("resolve: " + resolve + " error:" + reject);
                        console.log("Github API response (fetch): ", err, data);

                        if(err) {
                            l4.broadCastMessage("Github error: " + JSON.stringify(err));
                            resolve(new Response("Error" + err))
                        }  else {
                            resolve(new Response(data))
                        }
                    };

                    var credentials = githubCredentials,
                        github = new Github(credentials),
                        topLevelAPIName = topLevelAPIMapping[message.topLevelAPI],
                        topLevelAPIFunction = github[topLevelAPIName],
                        apiObject = topLevelAPIFunction.apply(github, message.topLevelArguments),
                        methodName = message.method,
                        methodFunction = apiObject[methodName],
                        args = message.args.concat(callback);

                    methodFunction.apply(apiObject, args);
                }

                if(isPut) {
                    request.text().then(sendGithubRequest);
                } else {
                    sendGithubRequest();
                }
            });
        }

        return focalStorage.getItem("githubToken")
            .then(ensureToken)
            .then(fetchWithToken)
            .catch(function(err) {
                console.log("focalStorage Error: " + err)
                return // Error ??
            });
    })
})();
<|endoftext|>


<commit_before>l4.importScripts('src/sw/core.js');
l4.importScripts('src/sw/fetch.js');

l4.importScripts('src/sw/messaging-tasks/github/github.js');

l4.importScripts('src/external/focalStorage.js');

//l4.importScripts('src/sw/messaging-tasks/github/credentials.js');

(function() {

    var expression = /^(https:\/\/github.lively4\/)/;

    l4.fetchTask('fetch github', l4.urlMatch(expression), function(event) {
        var request = event.request

        console.log('GitHub fetch: ', request.url);

        return focalStorage.getItem("githubToken").then(function(githubToken) {
            if (! githubToken) {
                console.log("githubToken not found")
                return new Response("No GitHub access token available.", { "status" : 404 , "statusText" : "Not found." })
            }

            return new Promise(function(resolve, reject) {
                console.log('got githubCredentials');

                var githubCredentials = {
                    token: githubToken,
                    auth: 'oauth'
                }
                var s = request.url.replace(expression, '');
                var exp = new RegExp("([^/]*)/([^/]*)/([^/]*)/([^/]*)/(.*)")
                var match = exp.exec(s)

                // Example: https://github.lively4/repo/livelykernel/lively4-core/gh-pages/README.md
                var message = {
                    topLevelAPI: match[1],
                    topLevelArguments: [match[2], match[3]],
                    method: 'read',
                    args: [match[4], match[5]]
                }

                var topLevelAPIMapping = {
                    issues: 'getIssues',
                    repo: 'getRepo',
                    user: 'getUser',
                    gist: 'getGist'
                };

                var callback = function(err, data) {
                    console.log(err, data);

                    if(err) {
                        l4.broadCastMessage(err);
                        resolve(new Response("Error" + err))
                    }  else {
                        resolve(new Response(data))
                    }
                };

                var credentials = githubCredentials,
                    github = new Github(credentials),
                    topLevelAPIName = topLevelAPIMapping[message.topLevelAPI],
                    topLevelAPIFunction = github[topLevelAPIName],
                    apiObject = topLevelAPIFunction.apply(github, message.topLevelArguments),
                    methodName = message.method,
                    methodFunction = apiObject[methodName],
                    args = message.args.concat(callback);

                methodFunction.apply(apiObject, args);
            });
        }).catch(function(err) {
                console.log("focalStorage Error: " + err)
                return // Error ??
        })

    });
})();
<commit_msg>draft ace editor<commit_after>l4.importScripts('src/sw/core.js');
l4.importScripts('src/sw/fetch.js');

l4.importScripts('src/sw/messaging-tasks/github/github.js');

l4.importScripts('src/external/focalStorage.js');

//l4.importScripts('src/sw/messaging-tasks/github/credentials.js');

(function() {

    var expression = /^(https:\/\/github.lively4\/)/;

    l4.fetchTask('fetch github', l4.urlMatch(expression), function(event) {
        var request = event.request

        console.log('GitHub fetch: ', request.url);

        return focalStorage.getItem("githubToken").then(function(githubToken) {
            if (! githubToken) {
                console.log("githubToken not found")
                return new Response("No GitHub access token available.", { "status" : 404 , "statusText" : "Not found." })
            }

            return new Promise(function(resolve, reject) {
                console.log('got githubCredentials');

                var githubCredentials = {
                    token: githubToken,
                    auth: 'oauth'
                }
                var s = request.url.replace(expression, '');
                var exp = new RegExp("([^/]*)/([^/]*)/([^/]*)/([^/]*)/(.*)")
                var match = exp.exec(s)

                // Example: https://github.lively4/repo/livelykernel/lively4-core/gh-pages/README.md

                var username = match[2],
                    reponame = match[3],
                    branch = match[4],
                    path = match[5]

                var message = {
                    topLevelAPI: match[1],
                    topLevelArguments: [username, reponame],
                    method: 'read',
                    args: [branch, path]
                }

                var topLevelAPIMapping = {
                    issues: 'getIssues',
                    repo: 'getRepo',
                    user: 'getUser',
                    gist: 'getGist'
                };

                var callback = function(err, data) {
                    console.log(err, data);

                    if(err) {
                        l4.broadCastMessage(err);
                        resolve(new Response("Error" + err))
                    }  else {
                        resolve(new Response(data))
                    }
                };

                var credentials = githubCredentials,
                    github = new Github(credentials),
                    topLevelAPIName = topLevelAPIMapping[message.topLevelAPI],
                    topLevelAPIFunction = github[topLevelAPIName],
                    apiObject = topLevelAPIFunction.apply(github, message.topLevelArguments),
                    methodName = message.method,
                    methodFunction = apiObject[methodName],
                    args = message.args.concat(callback);

                methodFunction.apply(apiObject, args);
            });
        }).catch(function(err) {
                console.log("focalStorage Error: " + err)
                return // Error ??
        })

    });
})();
<|endoftext|>


<commit_before>/**
 * jquery.cbpNTAccordion.min.js v1.0.0
 * http://www.codrops.com
 *
 * Licensed under the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 *
 * Copyright 2013, Codrops
 * http://www.codrops.com
 */
(function(d,b,e){var c=d("html, body");d.CBPNTAccordion=function(f,g){this.$el=d(g);this._init(f)};d.CBPNTAccordion.defaults={};d.CBPNTAccordion.prototype={_init:function(f){this.options=d.extend(true,{},d.CBPNTAccordion.defaults,f);this._config();this._initEvents()},_config:function(){this.$items=this.$el.find(".cbp-nttrigger")},_initEvents:function(){this.$items.on("click.cbpNTAccordion",function(){var f=d(this).parent();if(f.hasClass("cbp-ntopen")){f.removeClass("cbp-ntopen")}else{f.addClass("cbp-ntopen");c.scrollTop(f.offset().top)}})},destroy:function(){this.$items.off(".cbpNTAccordion").parent().removeClass("cbp-ntopen")}};var a=function(f){if(b.console){b.console.error(f)}};d.fn.cbpNTAccordion=function(g){if(typeof g==="string"){var f=Array.prototype.slice.call(arguments,1);this.each(function(){var h=d.data(this,"cbpNTAccordion");if(!h){a("cannot call methods on cbpNTAccordion prior to initialization; attempted to call method '"+g+"'");return}if(!d.isFunction(h[g])||g.charAt(0)==="_"){a("no such method '"+g+"' for cbpNTAccordion instance");return}h[g].apply(h,f)})}else{this.each(function(){var h=d.data(this,"cbpNTAccordion");if(h){h._init()}else{h=d.data(this,"cbpNTAccordion",new d.CBPNTAccordion(g,this))}})}return this}})(jQuery,window);<commit_msg>Update jquery.cbpNTAccordion.min.js<commit_after>
<|endoftext|>


<commit_before>/**
 * Initialize task.
 * Replaces all t3b_template strings and other meta-data with the data
 * specified inside the 'package.json'. (Should be run after downloading the extension).
 */

var fs = require('fs'),
	config = require("../Config"),
	helpers = require("../Libary/Helpers");

module.exports = function(grunt) {
	"use strict";

	grunt.registerTask("init", function() {
		// Replace general text-strings and paths.
		grunt.task.run("replace:preInit");

		if (!helpers.isPackageDefault() || grunt.option('env') === 'travis') {
			/*
			 * If the package.json contents are edited:
			 *		=> #1: replace all '<!=  !>' strings and set up the git hooks.
			 *		=> #1: remove the default git history.
			 *		=> #2: Copy a bare version of the extensions '.gitignore' into the root.
			 *		=> #3: Remove other files which aren't suitable for customized extensions.
			 */
			grunt.task.run(["replace:init", "clean:gitFolder"]); // #1
			helpers.copyFile("Build/Templates/.gitignore", ".gitignore"); // #2
			helpers.deleteFiles([".travis.yml", "CHANGELOG.md", "CONTRIBUTORS.md", "README.md"]); // #3
		} else {
			/*
			 * If the package.json contents are defaults:
			 *		=> Remove any previous set git hooks.
			 *		=> Copy the git hooks as they are not present by default.
			 */
			grunt.task.run(["shell:deleteGitHooks", "shell:hookUpGit"]);
		}

		// Create the base Stylesheet to prevent errors from ext:vhs(File not found).
		if (!fs.existsSync(config.Sass.cssDir + "/Main.css")) {
			grunt.task.run(["sass:dev"]);
		}

		// Fetch all bower components.
		grunt.task.run(["bower:install"]);
	});
};
<commit_msg>[TASK] Create an initial living styleguide upon 'grunt init'<commit_after>/**
 * Initialize task.
 * Replaces all t3b_template strings and other meta-data with the data
 * specified inside the 'package.json'. (Should be run after downloading the extension).
 */

var fs = require('fs'),
	config = require("../Config"),
	helpers = require("../Libary/Helpers");

module.exports = function(grunt) {
	"use strict";

	grunt.registerTask("init", function() {
		// Replace general text-strings and paths.
		grunt.task.run("replace:preInit");

		if (!helpers.isPackageDefault() || grunt.option('env') === 'travis') {
			/*
			 * If the package.json contents are edited:
			 *		=> #1: replace all '<!=  !>' strings and set up the git hooks.
			 *		=> #1: remove the default git history.
			 *		=> #2: Copy a bare version of the extensions '.gitignore' into the root.
			 *		=> #3: Remove other files which aren't suitable for customized extensions.
			 */
			grunt.task.run(["replace:init", "clean:gitFolder"]); // #1
			helpers.copyFile("Build/Templates/.gitignore", ".gitignore"); // #2
			helpers.deleteFiles([".travis.yml", "CHANGELOG.md", "CONTRIBUTORS.md", "README.md"]); // #3
		} else {
			/*
			 * If the package.json contents are defaults:
			 *		=> Remove any previous set git hooks.
			 *		=> Copy the git hooks as they are not present by default.
			 */
			grunt.task.run(["shell:deleteGitHooks", "shell:hookUpGit"]);
		}

		// Create the base Stylesheet to prevent errors from ext:vhs(File not found).
		if (!fs.existsSync(config.Sass.cssDir + "/Main.css")) {
			grunt.task.run(["sass:dev"]);
		}

		// Create the initial living styleguide.
		grunt.task.run("styleguide");

		// Fetch all bower components.
		grunt.task.run(["bower:install"]);
	});
};
<|endoftext|>


<commit_before>
// Collection()

(function(ns, mixin, undefined) {
	"use strict";

	var debug = false;

	function isDefined(val) {
		return val !== undefined && val !== null;
	}

	// Map functions

	function returnArg(arg) {
		return arg;
	}

	// Each functions

	function setValue(value, i) {
		this[i] = value;
	}

	function setListeners(data, i) {
		if (!sub.on) { return; }

		//sub
		//.on('change', this.trigger)
		//.on('destroy', this.remove);
	}

	// Sort functions

	function byGreater(a, b) {
		return a > b ? 1 : -1 ;
	}

	function byId(a, b) {
		return a.id > b.id ? 1 : -1 ;
	}

	// Object functions

	function extend(obj) {
		var i = 0,
		    length = arguments.length,
		    obj2, key;

		while (++i < length) {
			obj2 = arguments[i];

			for (key in obj2) {
				if (obj2.hasOwnProperty(key)) {
					obj[key] = obj2[key];
				}
			}
		}

		return obj;
	}

	// Collection functions

	function findByIndex(collection, id) {
		var index = collection.index;
		var l = collection.length;

		while (l--) {
			if (collection[l][index] === id) {
				return collection[l];
			}
		}
	}

	function findByObject(collection, object) {
		var i = collection.indexOf(object);

		if (i === -1) { return; }

		return collection[i];
	}

	function add(collection, object) {
		// Add an item, keeping the collection sorted by id.
		var index = collection.index;

		// If the object does not have an index key, push it
		// to the end of the collection.
		if (!isDefined(object[index])) {
			collection.push(object);
			return;
		}

		var l = collection.length;

		while (collection[--l] && (collection[l][index] > object[index] || !isDefined(collection[l][index])));
		collection.splice(l + 1, 0, object);
	}

	function remove(array, obj, i) {
		var found = false;

		if (i === undefined) { i = -1; }

		while (++i < array.length) {
			if (obj === array[i]) {
				array.splice(i, 1);
				--i;
				found = true;
			}
		}

		return found;
	}

	function invalidateCaches(collection) {

	}

	function toJSON(collection) {
		return collection.map(toArray);
	}

	function multiarg(fn) {
		return function(data) {
			var n = -1;
			var l = arguments.length;

			invalidateCaches(this);

			while (++n < l) {
				fn.call(this, arguments[n]);
			}

			return this;
		}
	}

	mixin.collection = {
		add: multiarg(function(item) {
			add(this, item);
			this.trigger('add', item);
		}),

		remove: multiarg(function(item) {
			var obj = this.find(item);

			if (!obj) { return; }

			remove(this, obj);
			this.trigger('remove', obj);
		}),

		update: multiarg(function(obj) {
			var item = this.find(obj);

			if (item) {
				extend(item, obj);
				this.trigger('update', item);
			}
			else {
				this.add(obj);
				this.trigger('add', obj);
			}

			return this;
		}),

		find: function(obj) {
			var index = this.index;

			return !isDefined(obj) ?
					undefined :
				typeof obj === 'string' || typeof obj === 'number' ?
					findByIndex(this, obj) :
				isDefined(obj[index]) ?
					findByIndex(this, obj[index]) :
					findByObject(this, obj) ;
		},

		contains: function(object) {
			return this.indexOf(object) !== -1;
		},

		// Get the value of a property of all the objects in
		// the collection if they all have the same value.
		// Otherwise return undefined.

		get: function(property) {
			var n = this.length;

			if (n === 0) { return; }

			while (--n) {
				if (this[n][property] !== this[n - 1][property]) { return; }
			}

			return this[n][property];
		},

		// Set a property on every object in the collection.

		set: function(property, value) {
			if (arguments.length !== 2) {
				throw new Error('Collection.set(property, value) requires 2 arguments. ' + arguments.length + ' given.');
			}

			var n = this.length;
			while (n--) { this[n][property] = value; }
			return this;
		},

		toJSON: function() {
			return this.map(returnArg);
		},

		toObject: function(key) {
			var object = {};
			var prop, type;

			if (!key) { key = this.index; }

			while (n--) {
				prop = this[n][key];
				type = typeof prop;

				if (type === 'string' || type === 'number' && prop > -Infinity && prop < Infinity) {
					object[prop] = this[n];
				}
				else {
					console.warn('Collection.toObject() ' + prop + ' cannot be used as a key.');
				}
			}

			return object;
		}
	};

	// Object constructor

	var prototype = extend({}, mixin.events, mixin.set, mixin.array, mixin.collection);

	var properties = {
		length: {
			value: 0,
			enumerable: false,
			writable: true,
			configurable: true
		}
	};

	function Collection(data, index) {
		var collection = Object.create(prototype, properties);

		index = index || 'id';

		function byIndex(a, b) {
			return a[index] > b[index] ? 1 : -1 ;
		}

		Object.defineProperties(collection, {
			// Define the name of the property that will be used to sort and
			// index this collection.
			index: { value: index }
		});

		if (data === undefined) {
			data = [];
		}
		else if (!(data instanceof Array)) {
			if (debug) console.log('Scribe: data not an array. Scribe cant do that yet.');
			data = [];
		}

		// Populate the collection
		data.forEach(setValue, collection);

		var length = collection.length = data.length;

		// Sort the collection
		collection.sort(byIndex);

		// Watch the length and delete indexes when the length becomes shorter
		// like a nice array does.
		observe(collection, 'length', function(collection) {
			while (length-- > collection.length) {
				// JIT compiler notes suggest that setting undefined is
				// quicker than deleting a property.
				collection[length] = undefined;
			}

			length = collection.length;
		});

		// Delegate events
		//collection
		//.each(setListeners);

		// Define caches
		//Object.defineProperties(collection, {
		//
		//});

		return collection;
	};

	Collection.prototype = prototype;
	Collection.add = add;
	Collection.remove = remove;

	ns.Collection = Collection;
})(this, this.mixin);
<commit_msg>Collection altered to support undefined as an index. Unsure of the wisdom of this move. We will have to see.<commit_after>
// Collection()

(function(ns, mixin, undefined) {
	"use strict";

	var debug = false;

	function isDefined(val) {
		return val !== undefined && val !== null;
	}

	// Map functions

	function returnArg(arg) {
		return arg;
	}

	// Each functions

	function setValue(value, i) {
		this[i] = value;
	}

	function setListeners(data, i) {
		if (!sub.on) { return; }

		//sub
		//.on('change', this.trigger)
		//.on('destroy', this.remove);
	}

	// Sort functions

	function byGreater(a, b) {
		return a > b ? 1 : -1 ;
	}

	function byId(a, b) {
		return a.id > b.id ? 1 : -1 ;
	}

	// Object functions

	function extend(obj) {
		var i = 0,
		    length = arguments.length,
		    obj2, key;

		while (++i < length) {
			obj2 = arguments[i];

			for (key in obj2) {
				if (obj2.hasOwnProperty(key)) {
					obj[key] = obj2[key];
				}
			}
		}

		return obj;
	}

	// Collection functions

	function findByIndex(collection, id) {
		var index = collection.index;
		var l = collection.length;

		while (l--) {
			if (collection[l][index] === id) {
				return collection[l];
			}
		}
	}

//	function findByObject(collection, object) {
//		var i = collection.indexOf(object);
//
//		if (i === -1) { return; }
//
//		return collection[i];
//	}

	function add(collection, object) {
		// Add an item, keeping the collection sorted by id.
		var index = collection.index;

		// If the object does not have an index key, push it
		// to the end of the collection.
		if (!isDefined(object[index])) {
			collection.push(object);
			return;
		}

		var l = collection.length;

		while (collection[--l] && (collection[l][index] > object[index] || !isDefined(collection[l][index])));
		collection.splice(l + 1, 0, object);
	}

	function remove(array, obj, i) {
		var found = false;

		if (i === undefined) { i = -1; }

		while (++i < array.length) {
			if (obj === array[i]) {
				array.splice(i, 1);
				--i;
				found = true;
			}
		}

		return found;
	}

	function invalidateCaches(collection) {

	}

	function toJSON(collection) {
		return collection.map(toArray);
	}

	function multiarg(fn) {
		return function(data) {
			var n = -1;
			var l = arguments.length;

			invalidateCaches(this);

			while (++n < l) {
				fn.call(this, arguments[n]);
			}

			return this;
		}
	}

	mixin.collection = {
		add: multiarg(function(item) {
			add(this, item);
			this.trigger('add', item);
		}),

		remove: multiarg(function(item) {
			var obj = this.find(item);

			if (!obj) { return; }

			remove(this, obj);
			this.trigger('remove', obj);
		}),

		update: multiarg(function(obj) {
			var item = this.find(obj);

			if (item) {
				extend(item, obj);
				this.trigger('update', item);
			}
			else {
				this.add(obj);
				this.trigger('add', obj);
			}

			return this;
		}),

		find: function(obj) {
			var index = this.index;

			return typeof obj === 'string' || typeof obj === 'number' || obj === undefined ?
				findByIndex(this, obj) :
				findByIndex(this, obj[index]) ;
		},

		contains: function(object) {
			return this.indexOf(object) !== -1;
		},

		// Get the value of a property of all the objects in
		// the collection if they all have the same value.
		// Otherwise return undefined.

		get: function(property) {
			var n = this.length;

			if (n === 0) { return; }

			while (--n) {
				if (this[n][property] !== this[n - 1][property]) { return; }
			}

			return this[n][property];
		},

		// Set a property on every object in the collection.

		set: function(property, value) {
			if (arguments.length !== 2) {
				throw new Error('Collection.set(property, value) requires 2 arguments. ' + arguments.length + ' given.');
			}

			var n = this.length;
			while (n--) { this[n][property] = value; }
			return this;
		},

		toJSON: function() {
			return this.map(returnArg);
		},

		toObject: function(key) {
			var object = {};
			var prop, type;

			if (!key) { key = this.index; }

			while (n--) {
				prop = this[n][key];
				type = typeof prop;

				if (type === 'string' || type === 'number' && prop > -Infinity && prop < Infinity) {
					object[prop] = this[n];
				}
				else {
					console.warn('Collection.toObject() ' + prop + ' cannot be used as a key.');
				}
			}

			return object;
		}
	};

	// Object constructor

	var prototype = extend({}, mixin.events, mixin.set, mixin.array, mixin.collection);

	var properties = {
		length: {
			value: 0,
			enumerable: false,
			writable: true,
			configurable: true
		}
	};

	function Collection(data, index) {
		var collection = Object.create(prototype, properties);

		index = index || 'id';

		function byIndex(a, b) {
			return a[index] > b[index] ? 1 : -1 ;
		}

		Object.defineProperties(collection, {
			// Define the name of the property that will be used to sort and
			// index this collection.
			index: { value: index }
		});

		if (data === undefined) {
			data = [];
		}
		else if (!(data instanceof Array)) {
			if (debug) console.log('Scribe: data not an array. Scribe cant do that yet.');
			data = [];
		}

		// Populate the collection
		data.forEach(setValue, collection);

		var length = collection.length = data.length;

		// Sort the collection
		collection.sort(byIndex);

		// Watch the length and delete indexes when the length becomes shorter
		// like a nice array does.
		observe(collection, 'length', function(collection) {
			while (length-- > collection.length) {
				// JIT compiler notes suggest that setting undefined is
				// quicker than deleting a property.
				collection[length] = undefined;
			}

			length = collection.length;
		});

		// Delegate events
		//collection
		//.each(setListeners);

		// Define caches
		//Object.defineProperties(collection, {
		//
		//});

		return collection;
	};

	Collection.prototype = prototype;
	Collection.add = add;
	Collection.remove = remove;

	ns.Collection = Collection;
})(this, this.mixin);
<|endoftext|>


<commit_before>function Queue() {
  this.queue = [];
}

Queue.prototype.enqueue = function(value) {
  this.queue.push(value);
};
Queue.prototype.dequeue = function() {
  return this.queue.shift();
};
Queue.prototype.peek = function() {
  return this.queue[this.queue.length - 1];
};
Queue.prototype.length = function() {
  return this.queue.length;
};
Queue.prototype.print = function() {
  console.log(this.queue.reduce(function(prev, curr) {
    return prev + curr + ' ';
  }, '').trim());
};

var queue = new Queue();
queue.enqueue(1);
queue.enqueue(2);
queue.enqueue(3);
queue.print(); // => 1 2 3
console.log('length is 3:', queue.length()); // => 3
console.log('peek is 3:', queue.peek()); // => 3
console.log('dequeue is 1:', queue.dequeue()); // => 1
queue.print(); // => 2 3
console.log('dequeue is 2:', queue.dequeue());  // => 2
console.log('length is 1:', queue.length()); // => 1
console.log('dequeue is 3:', queue.dequeue()); // => 3
queue.print(); // => ''
console.log('peek is undefined:', queue.peek()); // => undefined
console.log('dequeue is undefined:', queue.dequeue()); // => undefined
<commit_msg>Fix the queue peek method<commit_after>function Queue() {
  this.queue = [];
}

Queue.prototype.enqueue = function(value) {
  this.queue.push(value);
};
Queue.prototype.dequeue = function() {
  return this.queue.shift();
};
Queue.prototype.peek = function() {
  return this.queue[0];
};
Queue.prototype.length = function() {
  return this.queue.length;
};
Queue.prototype.print = function() {
  console.log(this.queue.reduce(function(prev, curr) {
    return prev + curr + ' ';
  }, '').trim());
};

var queue = new Queue();
queue.enqueue(1);
queue.enqueue(2);
queue.enqueue(3);
queue.print(); // => 1 2 3
console.log('length is 3:', queue.length()); // => 3
console.log('peek is 1:', queue.peek()); // => 3
console.log('dequeue is 1:', queue.dequeue()); // => 1
queue.print(); // => 2 3
console.log('dequeue is 2:', queue.dequeue());  // => 2
console.log('length is 1:', queue.length()); // => 1
console.log('dequeue is 3:', queue.dequeue()); // => 3
queue.print(); // => ''
console.log('peek is undefined:', queue.peek()); // => undefined
console.log('dequeue is undefined:', queue.dequeue()); // => undefined
<|endoftext|>