<commit_before>// Copyright 2015-present 650 Industries. All rights reserved.

'use strict';

import fs from 'fs';
import glob from 'glob';
import 'instapromise';
import path from 'path';
import * as Versions from '../Versions';

/**
 *  @param pathToTemplate path to template Podfile
 *  @param pathToOutput path to render final Podfile
 *  @param moreSubstitutions dictionary of additional substitution keys and values to replace
 *         in the template, such as: TARGET_NAME, EXPONENT_ROOT_PATH, REACT_NATIVE_PATH
 */
async function renderPodfileAsync(pathToTemplate, pathToOutput, moreSubstitutions) {
  if (!moreSubstitutions) {
    moreSubstitutions = {};
  }
  let templatesDirectory = path.dirname(pathToTemplate);
  let templateString = await fs.promise.readFile(pathToTemplate, 'utf8');
  let newestVersion = await Versions.newestSdkVersionAsync();

  let reactNativePath = moreSubstitutions.REACT_NATIVE_PATH;
  let rnDependencyOptions;
  if (reactNativePath) {
    rnDependencyOptions = { reactNativePath };
  } else {
    rnDependencyOptions = {
      isRemote: true,
      remoteTag: newestVersion.exponentReactNativeTag,
    };
  }

  let versionedDependencies = await renderVersionedReactNativeDependenciesAsync(templatesDirectory);
  let versionedPostinstalls = await renderVersionedReactNativePostinstallsAsync(templatesDirectory);

  let substitutions = {
    EXPONENT_CLIENT_DEPS: renderPodDependencies({ isPodfile: true }),
    PODFILE_UNVERSIONED_RN_DEPENDENCY: renderUnversionedReactNativeDependency(rnDependencyOptions),
    PODFILE_UNVERSIONED_POSTINSTALL: renderUnversionedPostinstall(),
    PODFILE_VERSIONED_RN_DEPENDENCIES: versionedDependencies,
    PODFILE_VERSIONED_POSTINSTALLS: versionedPostinstalls,
    PODFILE_TEST_TARGET: renderPodfileTestTarget(reactNativePath),
    ...moreSubstitutions,
  };

  let result = templateString;
  for (let key in substitutions) {
    if (substitutions.hasOwnProperty(key)) {
      let replacement = substitutions[key];
      result = result.replace(new RegExp(`\\\$\\\{${key}\\\}`, 'g'), replacement);
    }
  }

  await fs.promise.writeFile(pathToOutput, result);
}

async function renderExponentViewPodspecAsync(pathToTemplate, pathToOutput) {
  let templateString = await fs.promise.readFile(pathToTemplate, 'utf8');
  let dependencies = renderPodDependencies({ isPodfile: false });
  let result = templateString.replace(/\$\{IOS_EXPONENT_VIEW_DEPS\}/g, dependencies);

  await fs.promise.writeFile(pathToOutput, result);
}

function renderUnversionedReactNativeDependency(options) {
  let attributes;
  if (options.isRemote && options.remoteTag) {
    attributes = {
      git: 'https://github.com/exponentjs/react-native.git',
      tag: options.remoteTag,
    };
  } else if (options.reactNativePath) {
    attributes = {
      path: options.reactNativePath,
    };
  } else {
    throw new Error(`Unsupported options for RN dependency: ${options}`);
  }
  let attributesStrings = [];
  for (let key in attributes) {
    if (attributes.hasOwnProperty(key)) {
      attributesStrings.push(`    :${key} => '${attributes[key]}',\n`);
    }
  }
  attributes = attributesStrings.join('');
  return `
  pod 'React',
${attributes}
    :subspecs => [
      'Core',
      'ART',
      'RCTActionSheet',
      'RCTAnimation',
      'RCTCameraRoll',
      'RCTGeolocation',
      'RCTImage',
      'RCTNetwork',
      'RCTText',
      'RCTVibration',
      'RCTWebSocket',
    ]
`;
}

async function renderVersionedReactNativeDependenciesAsync(templatesDirectory) {
  // TODO: write these files with versioning script
  return concatTemplateFilesInDirectoryAsync(path.join(templatesDirectory, 'versioned-react-native', 'dependencies'));
}

async function renderVersionedReactNativePostinstallsAsync(templatesDirectory) {
  // TODO: write these files with versioning script
  return concatTemplateFilesInDirectoryAsync(path.join(templatesDirectory, 'versioned-react-native', 'postinstalls'));
}

async function concatTemplateFilesInDirectoryAsync(directory) {
  let templateFilenames = await glob.promise(path.join(directory, '*.rb'));
  let templateStrings = [];
  await Promise.all(templateFilenames.map(async (filename) => {
    let templateString = await fs.promise.readFile(filename, 'utf8');
    if (templateString) {
      templateStrings.push(templateString);
    }
  }));
  return templateStrings.join('\n');
}

function renderUnversionedPostinstall() {
  return `
    # Build React Native with RCT_DEV enabled
    next unless target.pod_name == 'React'
    target.native_target.build_configurations.each do |config|
      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)']
      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] << 'RCT_DEV=1'
    end
`;
}

function renderPodfileTestTarget(reactNativePath) {
  return `
  # if you run into problems pre-downloading this, rm Pods/Local\ Podspecs/RCTTest.podspec.json
  target 'ExponentIntegrationTests' do
    inherit! :search_paths
    pod 'RCTTest', :podspec => './RCTTest.podspec', :path => '${reactNativePath}'
  end
`;
}

function renderPodDependencies(options) {
  let dependencies = [
    { name: 'AppAuth', version: '~> 0.4' },
    { name: 'CocoaLumberjack', version: '~> 2.3' },
    { name: 'Crashlytics', version: '~> 3.8' },
    { name: 'Fabric', version: '~> 1.6' },
    { name: 'Google/SignIn', version: '~> 3.0' },
    { name: 'Amplitude-iOS', version: '~> 3.8' },
    { name: 'FBSDKCoreKit', version: '~> 4.15' },
    { name: 'FBSDKLoginKit', version: '~> 4.15' },
    { name: 'FBSDKShareKit', version: '~> 4.15' },
    { name: 'Analytics', version: '~> 3.5' },
  ];

  let type = (options.isPodfile) ? 'pod' : 's.dependency';
  let depsStrings = dependencies.map((dependency) => `  ${type} '${dependency.name}', '${dependency.version}'`);
  return depsStrings.join('\n');
}

export {
  renderExponentViewPodspecAsync,
  renderPodfileAsync,
};
<commit_msg>Specify pod deps in `dependencies.json`<commit_after>// Copyright 2015-present 650 Industries. All rights reserved.

'use strict';

import fs from 'fs';
import glob from 'glob';
import 'instapromise';
import JsonFile from '@exponent/json-file';
import path from 'path';
import * as Versions from '../Versions';

/**
 *  @param pathToTemplate path to template Podfile
 *  @param pathToOutput path to render final Podfile
 *  @param moreSubstitutions dictionary of additional substitution keys and values to replace
 *         in the template, such as: TARGET_NAME, EXPONENT_ROOT_PATH, REACT_NATIVE_PATH
 */
async function renderPodfileAsync(pathToTemplate, pathToOutput, moreSubstitutions) {
  if (!moreSubstitutions) {
    moreSubstitutions = {};
  }
  let templatesDirectory = path.dirname(pathToTemplate);
  let templateString = await fs.promise.readFile(pathToTemplate, 'utf8');
  let newestVersion = await Versions.newestSdkVersionAsync();

  let reactNativePath = moreSubstitutions.REACT_NATIVE_PATH;
  let rnDependencyOptions;
  if (reactNativePath) {
    rnDependencyOptions = { reactNativePath };
  } else {
    rnDependencyOptions = {
      isRemote: true,
      remoteTag: newestVersion.exponentReactNativeTag,
    };
  }

  let versionedDependencies = await renderVersionedReactNativeDependenciesAsync(templatesDirectory);
  let versionedPostinstalls = await renderVersionedReactNativePostinstallsAsync(templatesDirectory);
  let podDependencies = await renderPodDependenciesAsync(
    path.join(templatesDirectory, 'dependencies.json'),
    { isPodfile: true }
  );

  let substitutions = {
    EXPONENT_CLIENT_DEPS: podDependencies,
    PODFILE_UNVERSIONED_RN_DEPENDENCY: renderUnversionedReactNativeDependency(rnDependencyOptions),
    PODFILE_UNVERSIONED_POSTINSTALL: renderUnversionedPostinstall(),
    PODFILE_VERSIONED_RN_DEPENDENCIES: versionedDependencies,
    PODFILE_VERSIONED_POSTINSTALLS: versionedPostinstalls,
    PODFILE_TEST_TARGET: renderPodfileTestTarget(reactNativePath),
    ...moreSubstitutions,
  };

  let result = templateString;
  for (let key in substitutions) {
    if (substitutions.hasOwnProperty(key)) {
      let replacement = substitutions[key];
      result = result.replace(new RegExp(`\\\$\\\{${key}\\\}`, 'g'), replacement);
    }
  }

  await fs.promise.writeFile(pathToOutput, result);
}

async function renderExponentViewPodspecAsync(pathToTemplate, pathToOutput) {
  let templatesDirectory = path.dirname(pathToTemplate);
  let templateString = await fs.promise.readFile(pathToTemplate, 'utf8');
  let dependencies = await renderPodDependenciesAsync(
    path.join(templatesDirectory, 'dependencies.json'),
    { isPodfile: false }
  );
  let result = templateString.replace(/\$\{IOS_EXPONENT_VIEW_DEPS\}/g, dependencies);

  await fs.promise.writeFile(pathToOutput, result);
}

function renderUnversionedReactNativeDependency(options) {
  let attributes;
  if (options.isRemote && options.remoteTag) {
    attributes = {
      git: 'https://github.com/exponentjs/react-native.git',
      tag: options.remoteTag,
    };
  } else if (options.reactNativePath) {
    attributes = {
      path: options.reactNativePath,
    };
  } else {
    throw new Error(`Unsupported options for RN dependency: ${options}`);
  }
  let attributesStrings = [];
  for (let key in attributes) {
    if (attributes.hasOwnProperty(key)) {
      attributesStrings.push(`    :${key} => '${attributes[key]}',\n`);
    }
  }
  attributes = attributesStrings.join('');
  return `
  pod 'React',
${attributes}
    :subspecs => [
      'Core',
      'ART',
      'RCTActionSheet',
      'RCTAnimation',
      'RCTCameraRoll',
      'RCTGeolocation',
      'RCTImage',
      'RCTNetwork',
      'RCTText',
      'RCTVibration',
      'RCTWebSocket',
    ]
`;
}

async function renderVersionedReactNativeDependenciesAsync(templatesDirectory) {
  // TODO: write these files with versioning script
  return concatTemplateFilesInDirectoryAsync(path.join(templatesDirectory, 'versioned-react-native', 'dependencies'));
}

async function renderVersionedReactNativePostinstallsAsync(templatesDirectory) {
  // TODO: write these files with versioning script
  return concatTemplateFilesInDirectoryAsync(path.join(templatesDirectory, 'versioned-react-native', 'postinstalls'));
}

async function concatTemplateFilesInDirectoryAsync(directory) {
  let templateFilenames = await glob.promise(path.join(directory, '*.rb'));
  let templateStrings = [];
  await Promise.all(templateFilenames.map(async (filename) => {
    let templateString = await fs.promise.readFile(filename, 'utf8');
    if (templateString) {
      templateStrings.push(templateString);
    }
  }));
  return templateStrings.join('\n');
}

function renderUnversionedPostinstall() {
  return `
    # Build React Native with RCT_DEV enabled
    next unless target.pod_name == 'React'
    target.native_target.build_configurations.each do |config|
      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)']
      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] << 'RCT_DEV=1'
    end
`;
}

function renderPodfileTestTarget(reactNativePath) {
  return `
  # if you run into problems pre-downloading this, rm Pods/Local\ Podspecs/RCTTest.podspec.json
  target 'ExponentIntegrationTests' do
    inherit! :search_paths
    pod 'RCTTest', :podspec => './RCTTest.podspec', :path => '${reactNativePath}'
  end
`;
}

async function renderPodDependenciesAsync(dependenciesConfigPath, options) {
  let dependencies = await new JsonFile(dependenciesConfigPath).readAsync();
  let type = (options.isPodfile) ? 'pod' : 's.dependency';
  let depsStrings = dependencies.map((dependency) => `  ${type} '${dependency.name}', '${dependency.version}'`);
  return depsStrings.join('\n');
}

export {
  renderExponentViewPodspecAsync,
  renderPodfileAsync,
};
<|endoftext|>


<commit_before>'use strict';

const retrieveBSON = require('./connection/utils').retrieveBSON,
  EventEmitter = require('events'),
  BSON = retrieveBSON(),
  Binary = BSON.Binary,
  uuidV4 = require('./utils').uuidV4;

/**
 *
 */
class ClientSession extends EventEmitter {
  constructor(topology, sessionPool, options) {
    super();

    if (topology == null) {
      throw new Error('ClientSession requires a topology');
    }

    if (sessionPool == null || !(sessionPool instanceof ServerSessionPool)) {
      throw new Error('ClientSession requires a ServerSessionPool');
    }

    options = options || {};
    this.topology = topology;
    this.sessionPool = sessionPool;
    this.hasEnded = false;
    this.serverSession = sessionPool.acquire();

    this.supports = {
      causalConsistency: !!options.causalConsistency
    };

    options = options || {};
    if (typeof options.initialClusterTime !== 'undefined') {
      this.clusterTime = options.initialClusterTime;
    } else {
      this.clusterTime = null;
    }

    this.operationTime = null;
  }

  /**
   *
   */
  endSession(options, callback) {
    if (typeof options === 'function') (callback = options), (options = {});
    options = options || {};

    if (this.hasEnded) {
      if (typeof callback === 'function') callback(null, null);
      return;
    }

    if (!options.skipCommand) {
      // send the `endSessions` command
      this.topology.endSessions(this.id);
    }

    // mark the session as ended, and emit a signal
    this.hasEnded = true;
    this.emit('ended', this);

    // release the server session back to the pool
    this.sessionPool.release(this.serverSession);

    // spec indicates that we should ignore all errors for `endSessions`
    if (typeof callback === 'function') callback(null, null);
  }

  /**
   * Advances the operationTime for a ClientSession.
   *
   * @param {object} operationTime the `BSON.Timestamp` of the operation type it is desired to advance to
   */
  advanceOperationTime(operationTime) {
    if (this.operationTime == null) {
      this.operationTime = operationTime;
      return;
    }

    if (operationTime.greaterThan(this.operationTime)) {
      this.operationTime = operationTime;
    }
  }
}

Object.defineProperty(ClientSession.prototype, 'id', {
  get: function() {
    return this.serverSession.id;
  }
});

/**
 *
 */
class ServerSession {
  constructor() {
    this.id = { id: new Binary(uuidV4(), Binary.SUBTYPE_UUID) };
    this.lastUse = Date.now();
  }

  /**
   *
   * @param {*} sessionTimeoutMinutes
   */
  hasTimedOut(sessionTimeoutMinutes) {
    // Take the difference of the lastUse timestamp and now, which will result in a value in
    // milliseconds, and then convert milliseconds to minutes to compare to `sessionTimeoutMinutes`
    const idleTimeMinutes = Math.round(
      (((Date.now() - this.lastUse) % 86400000) % 3600000) / 60000
    );

    return idleTimeMinutes > sessionTimeoutMinutes - 1;
  }
}

/**
 *
 */
class ServerSessionPool {
  constructor(topology) {
    if (topology == null) {
      throw new Error('ServerSessionPool requires a topology');
    }

    this.topology = topology;
    this.sessions = [];
  }

  /**
   * @returns {ServerSession}
   */
  acquire() {
    const sessionTimeoutMinutes = this.topology.logicalSessionTimeoutMinutes;
    while (this.sessions.length) {
      const session = this.sessions.shift();
      if (!session.hasTimedOut(sessionTimeoutMinutes)) {
        return session;
      }
    }

    return new ServerSession();
  }

  /**
   *
   * @param {*} session
   */
  release(session) {
    const sessionTimeoutMinutes = this.topology.logicalSessionTimeoutMinutes;
    while (this.sessions.length) {
      const session = this.sessions[this.sessions.length - 1];
      if (session.hasTimedOut(sessionTimeoutMinutes)) {
        this.sessions.pop();
      } else {
        break;
      }
    }

    if (!session.hasTimedOut(sessionTimeoutMinutes)) {
      this.sessions.unshift(session);
    }
  }
}

module.exports = {
  ClientSession: ClientSession,
  ServerSession: ServerSession,
  ServerSessionPool: ServerSessionPool
};
<commit_msg>feat(sessions): add equality operator to ease readability<commit_after>'use strict';

const retrieveBSON = require('./connection/utils').retrieveBSON,
  EventEmitter = require('events'),
  BSON = retrieveBSON(),
  Binary = BSON.Binary,
  uuidV4 = require('./utils').uuidV4;

/**
 *
 */
class ClientSession extends EventEmitter {
  constructor(topology, sessionPool, options) {
    super();

    if (topology == null) {
      throw new Error('ClientSession requires a topology');
    }

    if (sessionPool == null || !(sessionPool instanceof ServerSessionPool)) {
      throw new Error('ClientSession requires a ServerSessionPool');
    }

    options = options || {};
    this.topology = topology;
    this.sessionPool = sessionPool;
    this.hasEnded = false;
    this.serverSession = sessionPool.acquire();

    this.supports = {
      causalConsistency: !!options.causalConsistency
    };

    options = options || {};
    if (typeof options.initialClusterTime !== 'undefined') {
      this.clusterTime = options.initialClusterTime;
    } else {
      this.clusterTime = null;
    }

    this.operationTime = null;
  }

  /**
   *
   */
  endSession(options, callback) {
    if (typeof options === 'function') (callback = options), (options = {});
    options = options || {};

    if (this.hasEnded) {
      if (typeof callback === 'function') callback(null, null);
      return;
    }

    if (!options.skipCommand) {
      // send the `endSessions` command
      this.topology.endSessions(this.id);
    }

    // mark the session as ended, and emit a signal
    this.hasEnded = true;
    this.emit('ended', this);

    // release the server session back to the pool
    this.sessionPool.release(this.serverSession);

    // spec indicates that we should ignore all errors for `endSessions`
    if (typeof callback === 'function') callback(null, null);
  }

  /**
   * Advances the operationTime for a ClientSession.
   *
   * @param {object} operationTime the `BSON.Timestamp` of the operation type it is desired to advance to
   */
  advanceOperationTime(operationTime) {
    if (this.operationTime == null) {
      this.operationTime = operationTime;
      return;
    }

    if (operationTime.greaterThan(this.operationTime)) {
      this.operationTime = operationTime;
    }
  }

  /**
   * Used to determine if this session equals another
   */
  equals(session) {
    if (!(session instanceof ClientSession)) {
      return false;
    }

    return this.id.id.buffer.equals(session.id.id.buffer);
  }
}

Object.defineProperty(ClientSession.prototype, 'id', {
  get: function() {
    return this.serverSession.id;
  }
});

/**
 *
 */
class ServerSession {
  constructor() {
    this.id = { id: new Binary(uuidV4(), Binary.SUBTYPE_UUID) };
    this.lastUse = Date.now();
  }

  /**
   *
   * @param {*} sessionTimeoutMinutes
   */
  hasTimedOut(sessionTimeoutMinutes) {
    // Take the difference of the lastUse timestamp and now, which will result in a value in
    // milliseconds, and then convert milliseconds to minutes to compare to `sessionTimeoutMinutes`
    const idleTimeMinutes = Math.round(
      (((Date.now() - this.lastUse) % 86400000) % 3600000) / 60000
    );

    return idleTimeMinutes > sessionTimeoutMinutes - 1;
  }
}

/**
 *
 */
class ServerSessionPool {
  constructor(topology) {
    if (topology == null) {
      throw new Error('ServerSessionPool requires a topology');
    }

    this.topology = topology;
    this.sessions = [];
  }

  /**
   * @returns {ServerSession}
   */
  acquire() {
    const sessionTimeoutMinutes = this.topology.logicalSessionTimeoutMinutes;
    while (this.sessions.length) {
      const session = this.sessions.shift();
      if (!session.hasTimedOut(sessionTimeoutMinutes)) {
        return session;
      }
    }

    return new ServerSession();
  }

  /**
   *
   * @param {*} session
   */
  release(session) {
    const sessionTimeoutMinutes = this.topology.logicalSessionTimeoutMinutes;
    while (this.sessions.length) {
      const session = this.sessions[this.sessions.length - 1];
      if (session.hasTimedOut(sessionTimeoutMinutes)) {
        this.sessions.pop();
      } else {
        break;
      }
    }

    if (!session.hasTimedOut(sessionTimeoutMinutes)) {
      this.sessions.unshift(session);
    }
  }
}

module.exports = {
  ClientSession: ClientSession,
  ServerSession: ServerSession,
  ServerSessionPool: ServerSessionPool
};
<|endoftext|>


<commit_before>(function($){

$.fn.limitedInput = function() {
    return this.each(function() {
        var area = $(this);
        var container = area.closest('.widget');
        var limit = area.attr('cms:charlimit');
        var count = area.val().length || 0;
        var suffix = '/' + limit;
        var label = count + suffix;
        var span = $('<span />').addClass('charlimit').html(label);
        container.append(span);
        area.bind("keyup focus blur onload", function (e) {
            var count = $(e.target).val().length;
            var label = count + suffix;
            if ((limit - count) < 0) {
                span.css("color", "#900").html(label);
            } else {
                span.css("color", "#000").html(label);
            }
        });
    });
};

$.fn.countedInput = function() {
    var self = $(this);
    var count = function() {
        var l = self.find('.editable').children().text().length || 0;
        var container = self.parent();
        container.find('.charcount').html(l + " Zeichen");
        if(l > 5000) {
          container.find('.charcount').addClass('charalert');
        } else {
          container.find('.charcount').removeClass('charalert');
        }
    };
    self.bind('keyup', count);
    count();
};

MochiKit.Signal.connect(window, 'cp-editor-loaded', function() {
    $('#article-editor-text').countedInput();
});

$(document).bind('fragment-ready', function(event) {
    $('[cms\\:charlimit]', event.__target).limitedInput();
});

}(jQuery));
<commit_msg>Re #12462: Update character counter on initial setup, too<commit_after>(function($){

var check_char_limit = function(target, span, limit) {
    var count = $(target).val().length;
    var label = count + '/' + limit;
    if ((limit - count) < 0) {
        span.css("color", "#900").html(label);
    } else {
        span.css("color", "#000").html(label);
    }
};

$.fn.limitedInput = function() {
    return this.each(function() {
        var area = $(this);
        var limit = area.attr('cms:charlimit');
        var container = area.closest('.widget');
        var span = $('<span />').addClass('charlimit');
        container.append(span);
        check_char_limit(area, span, limit);
        area.bind("keyup focus blur", function(event) {
            check_char_limit(event.target, span, limit);
        });
    });
};

$.fn.countedInput = function() {
    var self = $(this);
    var count = function() {
        var l = self.find('.editable').children().text().length || 0;
        var container = self.parent();
        container.find('.charcount').html(l + " Zeichen");
        if(l > 5000) {
          container.find('.charcount').addClass('charalert');
        } else {
          container.find('.charcount').removeClass('charalert');
        }
    };
    self.bind('keyup', count);
    count();
};

MochiKit.Signal.connect(window, 'cp-editor-loaded', function() {
    $('#article-editor-text').countedInput();
});

$(document).bind('fragment-ready', function(event) {
    $('[cms\\:charlimit]', event.__target).limitedInput();
});

}(jQuery));
<|endoftext|>


<commit_before>import Ember from 'ember';

export default Ember.Controller.extend({
    explorer: Ember.inject.service('explorer'),

    queryParams: ['cluster_id', 'bucket_type_id', 'bucket_id'],
    cluster_id: null,
    bucket_type_id: null,
    bucket_id: null,

    actions: {
        refreshKeys: function(keyList) {
            alert('in controller/refresh keys');
            this.get('explorer').keyCacheRefresh(keyList);

            this.transitionToRoute('key_list',
                { queryParams: {
                    cluster_id: keyList.get('bucket').get('clusterId'),
                    bucket_type_id: keyList.get('bucket').get('bucketTypeId'),
                    bucket_id: keyList.get('bucket').get('bucketId')
                }});
        }
    }
});
<commit_msg>Remove stray alert()<commit_after>import Ember from 'ember';

export default Ember.Controller.extend({
    explorer: Ember.inject.service('explorer'),

    queryParams: ['cluster_id', 'bucket_type_id', 'bucket_id'],
    cluster_id: null,
    bucket_type_id: null,
    bucket_id: null,

    actions: {
        refreshKeys: function(keyList) {
            this.get('explorer').keyCacheRefresh(keyList);

            this.transitionToRoute('key_list',
                { queryParams: {
                    cluster_id: keyList.get('bucket').get('clusterId'),
                    bucket_type_id: keyList.get('bucket').get('bucketTypeId'),
                    bucket_id: keyList.get('bucket').get('bucketId')
                }});
        }
    }
});
<|endoftext|>


<commit_before>(function(window,document,undefined){
    var Express = {};

    var Support = {};

    function getExpr(){
        var whitespace = "[\\x20\\t\\r\\n\\f]";//空白字符正则字符串
        var operators = "([*^$|!~]?=)";//可用的属性操作符
        var rcomma = "^" + whitespace + "*," + whitespace + "*";//并联选择器的正则
        var rcombinators = "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*";//关系选择器正则
        var characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+";//字符编码正则字符串
        var identifier = characterEncoding.replace( "w", "w#" );
        var attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
            "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]";//属性选择器正则
        var pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)";//伪类正则字符串
        var rtrim = "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$"; // 去掉两端空白和字符串中的反斜杠（如果连续两个去掉一个）
        //var rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/;//仅仅单个id或tag、class选择器正则（用来快速解析并获取元素）
        var rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/;
        var rnative = /^[^{]+\{\s*\[native code/;//原生函数正则
        var expando = "pizzle" + 1 * new Date();

        return {
            rcomma:new RegExp(rcomma),
            rcombinators:new RegExp(rcombinators),
            characterEncoding:characterEncoding,
            attributes:attributes,
            pseudos:pseudos,
            rtrim:new RegExp(rtrim,"g"),
            rquickExpr:new RegExp(rquickExpr),
            rnative:rnative,
            expando:expando
        };
    }

    function getMatchExpr(){
        var idExpr = "^#(" + Express.expr['characterEncoding'] + ")";
        var classExpr = "^\\.(" + Express.expr['characterEncoding'] + ")";
        var tagExpr =  "^(" + Express.expr['characterEncoding'].replace( "w", "w*" ) + ")";
        var attrExpr = "^" + Express.expr['attributes'];
        var pseudosExpr = "^" + Express.expr['pseudos'];
        var childEpr = "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + Express.expr['whitespace'] +
            "*(even|odd|(([+-]|)(\\d*)n|)" + Express.expr['whitespace'] + "*(?:([+-]|)" + Express.expr['whitespace'] +
            "*(\\d+)|))" + Express.expr['whitespace'] + "*\\)|)";

        return {
            "ID":new RegExp(idExpr),
            "CLASS":new RegExp(classExpr),
            "TAG":new RegExp(tagExpr),
            "ATTR":new RegExp(attrExpr),
            "PSEUDO":new RegExp(pseudosExpr),
            "CHILD":new RegExp(childEpr, "i" )
        };
    }

    function Pizzle(selector){
        if(!selector)
            return;

        return Pizzle.participle(selector);
    }

    Pizzle.init = function(){
        Express.expr = getExpr();
        Express.matchExpr = getMatchExpr();
        Support.isQSA = Express.expr['rnative'].test(document.querySelectorAll);
    };

    /**
     * participle selector
     * @param selector
     */
    Pizzle.participle = function(selector){
        if(typeof selector !== "string"){
            return [];
        }

        Pizzle.init();
        var match,matched,tokens = [],groups = [];

        //Handle HTML strings
        if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
            // Assume that strings that start and end with <> are HTML and skip the regex check
            var m = selector.substring(1,selector.length - 1);
            match = [ null, null,m, null ];
        } else {
            match = Express.expr.rquickExpr.exec(selector);
        }

        if(match){
            matched = match[1] || match[2] || match[3] ||'';
            var type = (matched == match[1]) ? "ID" : ((matched == match[2]) ? "TAG" : (matched == match[3]) ? "CLASS" : "");
            var sep = undefined,newMatched = undefined,oldMatched = match[0];
            if(oldMatched.charAt(0) === "#" || oldMatched.charAt(0) === "." || oldMatched.charAt(0) === ":"){
                sep = oldMatched.charAt(0);
                newMatched = oldMatched.substring(1,oldMatched.length);
            }

            tokens.push({
                value: newMatched ? newMatched : matched,
                type: type,
                sep: sep ? sep : "",
                matches: selector
            });

            groups.push(tokens);
            return groups;
        }else{
            return Pizzle.tokenize(selector);
        }
    };

    /**
     * participle many selectors
     * @param selector
     * @returns {Array}
     */
    Pizzle.tokenize = function(selector){
        var matched,match,tokens,type,str = selector,groups = [];
        while(str){
            //,
            if(!matched || (match = Express.expr.rcomma.exec(str))){
                if(match){
                    str = str.slice(match[0].length) || str;
                }
                groups.push(tokens = []);
            }

            matched = false;
            //+-~
            if((match = Express.expr.rcombinators.exec(str))!=null){
                matched = match.shift();
                tokens.push({
                    value:matched == " " ? matched : matched.trim(),
                    type:match[0].replace(Express.expr.rtrim," ")
                });

                str = str.slice(matched.length);
            }

            for(type in Express.matchExpr){
                if((match = Express.matchExpr[ type ].exec( str ))!=null){
                    matched = match.shift();
                    var sep = undefined,newMatched = undefined;
                    if(matched.charAt(0) === "#" || matched.charAt(0) === "." || matched.charAt(0) === ":"){
                        sep = matched.charAt(0);
                        newMatched = matched.substring(1,matched.length);
                    }
                    tokens.push({
                        value: newMatched ? newMatched : matched,
                        type: type,
                        sep: sep ? sep : "",
                        matches: match
                    });

                    str = str.slice(matched.length);
                }
            }

            if ( !matched ) {
                break;
            }
        }

        return groups;
    };

    Pizzle.error = function(message){
        throw new Error( "Syntax error, unrecognized expression: " + message );
    };

    Pizzle.isXml = function(elem){
        var documentElement = elem && (elem.ownerDocument || elem).documentElement;
        return documentElement ? documentElement.nodeName !== "HTML" : false;
    };

    window.Pizzle = Pizzle;
})(window,document,undefined);
<commit_msg>Update pizzle.js<commit_after>(function(window,document,undefined){
    var Express = {};

    var Support = {};

    function getExpr(){
        var whitespace = "[\\x20\\t\\r\\n\\f]";//空白字符正则字符串
        var operators = "([*^$|!~]?=)";//可用的属性操作符
        var rcomma = "^" + whitespace + "*," + whitespace + "*";//并联选择器的正则
        var rcombinators = "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*";//关系选择器正则
        var characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+";//字符编码正则字符串
        var identifier = characterEncoding.replace( "w", "w#" );
        var attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
            "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]";//属性选择器正则
        var pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)";//伪类正则字符串
        var rtrim = "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$"; // 去掉两端空白和字符串中的反斜杠（如果连续两个去掉一个）
        //var rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/;//仅仅单个id或tag、class选择器正则（用来快速解析并获取元素）
        var rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/;
        var rnative = /^[^{]+\{\s*\[native code/;//原生函数正则
        var expando = "pizzle" + 1 * new Date();

        return {
            rcomma:new RegExp(rcomma),
            rcombinators:new RegExp(rcombinators),
            characterEncoding:characterEncoding,
            attributes:attributes,
            pseudos:pseudos,
            rtrim:new RegExp(rtrim,"g"),
            rquickExpr:new RegExp(rquickExpr),
            rnative:rnative,
            expando:expando
        };
    }

    function getMatchExpr(){
        var idExpr = "^#(" + Express.expr['characterEncoding'] + ")";
        var classExpr = "^\\.(" + Express.expr['characterEncoding'] + ")";
        var tagExpr =  "^(" + Express.expr['characterEncoding'].replace( "w", "w*" ) + ")";
        var attrExpr = "^" + Express.expr['attributes'];
        var pseudosExpr = "^" + Express.expr['pseudos'];
        var childEpr = "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + Express.expr['whitespace'] +
            "*(even|odd|(([+-]|)(\\d*)n|)" + Express.expr['whitespace'] + "*(?:([+-]|)" + Express.expr['whitespace'] +
            "*(\\d+)|))" + Express.expr['whitespace'] + "*\\)|)";

        return {
            "ID":new RegExp(idExpr),
            "CLASS":new RegExp(classExpr),
            "TAG":new RegExp(tagExpr),
            "ATTR":new RegExp(attrExpr),
            "PSEUDO":new RegExp(pseudosExpr),
            "CHILD":new RegExp(childEpr, "i" )
        };
    }

    function Pizzle(selector){
        if(!selector)
            return;

        return Pizzle.participle(selector);
    }

    Pizzle.init = function(){
        Express.expr = getExpr();
        Express.matchExpr = getMatchExpr();
        Support.isQSA = Express.expr['rnative'].test(document.querySelectorAll);
    };

    /**
     * participle selector
     * @param selector
     */
    Pizzle.participle = function(selector){
        if(typeof selector !== "string"){
            return [];
        }

        Pizzle.init();
        var match,matched,tokens = [],groups = [];

        //Handle HTML strings
        if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
            // Assume that strings that start and end with <> are HTML and skip the regex check
            var m = selector.substring(1,selector.length - 1);
            match = [ null, null,m, null ];
        } else {
            match = Express.expr.rquickExpr.exec(selector);
        }

        if(match){
            matched = match[1] || match[2] || match[3] ||'';
            var type = (matched == match[1]) ? "ID" : ((matched == match[2]) ? "TAG" : (matched == match[3]) ? "CLASS" : "");
            var sep = undefined,newMatched = undefined,oldMatched = match[0];
            if(oldMatched.charAt(0) === "#" || oldMatched.charAt(0) === "." || oldMatched.charAt(0) === ":"){
                sep = oldMatched.charAt(0);
                newMatched = oldMatched.substring(1,oldMatched.length);
            }

            tokens.push({
                value: newMatched ? newMatched : matched,
                type: type,
                sep: sep ? sep : "",
                matches: selector
            });

            groups.push(tokens);
            return groups;
        }else{
            return Pizzle.tokenize(selector);
        }
    };

    /**
     * participle many selectors
     * @param selector
     * @returns {Array}
     */
    Pizzle.tokenize = function(selector){
        var matched,match,tokens,type,str = selector,groups = [];
        while(str){
            //,
            if(!matched || (match = Express.expr.rcomma.exec(str))){
                if(match){
                    str = str.slice(match[0].length) || str;
                }
                groups.push(tokens = []);
            }

            matched = false;
            //+-~
            if((match = Express.expr.rcombinators.exec(str))!=null){
                matched = match.shift();
                tokens.push({
                    value:matched == " " ? matched : matched.trim(),
                    type:match[0].replace(Express.expr.rtrim," ")
                });

                str = str.slice(matched.length);
            }

            for(type in Express.matchExpr){
                if((match = Express.matchExpr[ type ].exec( str ))!=null){
                    matched = match.shift();
                    var sep = undefined,newMatched = undefined;
                    if(matched.charAt(0) === "#" || matched.charAt(0) === "." || matched.charAt(0) === ":"){
                        sep = matched.charAt(0);
                        newMatched = matched.substring(1,matched.length);
                    }

                    var value = newMatched ? newMatched : matched;
                    var v = sep + value;
                    var child;
                    if((child =Express.matchExpr['CHILD'].exec(str))!=null){
                        var m = child.input;
                        var _value = m.substring(1,m.length);
                        tokens.push({
                            value: _value?_value:"",
                            type: 'CHILD',
                            sep: sep ? sep : "",
                            matches: m
                        });
                    }else{
                        tokens.push({
                            value:value,
                            type: type,
                            sep: sep ? sep : "",
                            matches: match
                        });
                    }

                    str = str.slice(matched.length);
                }
            }

            if ( !matched ) {
                break;
            }
        }

        return groups;
    };

    Pizzle.error = function(message){
        throw new Error( "Syntax error, unrecognized expression: " + message );
    };

    Pizzle.isXml = function(elem){
        var documentElement = elem && (elem.ownerDocument || elem).documentElement;
        return documentElement ? documentElement.nodeName !== "HTML" : false;
    };

    window.Pizzle = Pizzle;
})(window,document,undefined);
<|endoftext|>


<commit_before>var CONFIG = require('./config.js');
var CONSTANTS = require('./constants.js');
var util = require('./util.js');
var bidManager = require('./bidManager.js');
// todo: how we can do it optionally (include only iff required) ?
var prebid = require('./adapters/prebid.js');

var registeredAdapters = {};

exports.callAdapters = function(activeSlots){
	var impressionID = util.generateUUID();
	resetSlots(activeSlots, impressionID);
	callAdapter(registeredAdapters, activeSlots, impressionID);
};

function getRandomNumberBelow100(){
	return Math.floor(Math.random()*100);
}

// todo: give better name to this function
function callAdapter(adapters, slots, impressionID){
	var randomNumberBelow100 = getRandomNumberBelow100();
	util.forEachOnObject(adapters, function(adapterID, theAdapter){
		if(throttleAdapter(randomNumberBelow100, adapterID) == false){
			setInitTimeForSlotsForAdapter(slots, adapterID);
			theAdapter.fB(slots, impressionID);
		}else{
			util.log(adapterID+CONSTANTS.MESSAGES.M2);
		}
	});
}

// todo: where this function should go ? move to bidManager
function resetSlots(slots, impressionID){
	util.forEachOnObject(slots, function(key, slot){
		var divID = slot[CONSTANTS.SLOT_ATTRIBUTES.DIV_ID];
		bidManager.resetBid(divID, impressionID);
		bidManager.setSizes(divID, util.generateSlotNamesFromPattern(slot, '_W_x_H_'));
	});
}

function throttleAdapter(randomNumber, adapterID){
	return !(randomNumber >= CONFIG.getAdapterThrottle(adapterID));
}

// todo: where this function should go ? move to bidManager
function setInitTimeForSlotsForAdapter(slots, adapterID){
	util.forEachOnObject(slots, function(j){
		bidManager.setCallInitTime(slots[j][CONSTANTS.SLOT_ATTRIBUTES.DIV_ID], adapterID);
	});
}

function registerAdapter(bidAdaptor) {
	if (bidAdaptor) {
		var adapterID = bidAdaptor.ID();
		if (util.isFunction(bidAdaptor.fB)){
			registeredAdapters[adapterID] = bidAdaptor;
		} else {
			util.log(adapterID + CONSTANTS.MESSAGES.M3);
		}
	}
};

exports.registerAdapters = function(){
	registerAdapter(prebid.register());
};<commit_msg>a minor change<commit_after>var CONFIG = require('./config.js');
var CONSTANTS = require('./constants.js');
var util = require('./util.js');
var bidManager = require('./bidManager.js');
// todo: how we can do it optionally (include only iff required) ?
var prebid = require('./adapters/prebid.js');

var registeredAdapters = {};

exports.callAdapters = function(activeSlots){
	var impressionID = util.generateUUID();
	resetSlots(activeSlots, impressionID);
	callAdapter(registeredAdapters, activeSlots, impressionID);
};

function getRandomNumberBelow100(){
	return Math.floor(Math.random()*100);
}

// todo: give better name to this function
function callAdapter(adapters, slots, impressionID){
	var randomNumberBelow100 = getRandomNumberBelow100();
	util.forEachOnObject(adapters, function(adapterID, theAdapter){
		if(throttleAdapter(randomNumberBelow100, adapterID) == false){
			setInitTimeForSlotsForAdapter(slots, adapterID);
			theAdapter.fB(slots, impressionID);
		}else{
			util.log(adapterID+CONSTANTS.MESSAGES.M2);
		}
	});
}

// todo: where this function should go ? move to bidManager
function resetSlots(slots, impressionID){
	util.forEachOnObject(slots, function(key, slot){
		var divID = slot[CONSTANTS.SLOT_ATTRIBUTES.DIV_ID];
		bidManager.resetBid(divID, impressionID);
		bidManager.setSizes(divID, util.generateSlotNamesFromPattern(slot, '_W_x_H_'));
	});
}

function throttleAdapter(randomNumber, adapterID){
	return !(randomNumber >= CONFIG.getAdapterThrottle(adapterID));
}

// todo: where this function should go ? move to bidManager
function setInitTimeForSlotsForAdapter(slots, adapterID){
	util.forEachOnObject(slots, function(j, slot){
		bidManager.setCallInitTime(slot[CONSTANTS.SLOT_ATTRIBUTES.DIV_ID], adapterID);
	});
}

function registerAdapter(bidAdaptor) {
	if (bidAdaptor) {
		var adapterID = bidAdaptor.ID();
		if (util.isFunction(bidAdaptor.fB)){
			registeredAdapters[adapterID] = bidAdaptor;
		} else {
			util.log(adapterID + CONSTANTS.MESSAGES.M3);
		}
	}
};

exports.registerAdapters = function(){
	registerAdapter(prebid.register());
};<|endoftext|>


<commit_before>import Bluebird from 'bluebird'

import {
	LOG_MESSAGE,
	LOG_ERROR,
	START_PROGRESS,
	INCREMENT_PROGRESS,
	REMOVE_NOTIFICATION,
} from './constants'

export function removeNotification(id, delayBy = 0) {
	if (delayBy) {
		return {
			type: REMOVE_NOTIFICATION,
			payload: Bluebird.delay(delayBy, { id }),
		}
	}
	return { type: REMOVE_NOTIFICATION, payload: { id } }
}

export function logMessage(id, message) {
	return { type: LOG_MESSAGE, payload: { id, message } }
}

export function logError({id, error, quiet=false}, ...args) {
	if (!quiet && !TESTING) {
		console.error(error, ...args)
	}
	return { type: LOG_ERROR, payload: { id, error, quiet, args } }
}

export function startProgress(id, message = '', {value=0, max=1, showButton=false} = {}) {
	return { type: START_PROGRESS, payload: { id, message, value, max, showButton } }
}

export function incrementProgress(id, by = 1) {
	return { type: INCREMENT_PROGRESS, payload: { id, by } }
}
<commit_msg>add bugsnag reporting for handled errors<commit_after>import Bluebird from 'bluebird'

import {
	LOG_MESSAGE,
	LOG_ERROR,
	START_PROGRESS,
	INCREMENT_PROGRESS,
	REMOVE_NOTIFICATION,
} from './constants'

export function removeNotification(id, delayBy = 0) {
	if (delayBy) {
		return {
			type: REMOVE_NOTIFICATION,
			payload: Bluebird.delay(delayBy, { id }),
		}
	}
	return { type: REMOVE_NOTIFICATION, payload: { id } }
}

export function logMessage(id, message) {
	return { type: LOG_MESSAGE, payload: { id, message } }
}

export function logError({id, error, quiet=false}, ...args) {
	if (!quiet)  console.error(error, ...args)
	if (window.Bugsnag)  window.Bugsnag.notifyException(error)
	return { type: LOG_ERROR, payload: { id, error, quiet, args } }
}

export function startProgress(id, message = '', {value=0, max=1, showButton=false} = {}) {
	return { type: START_PROGRESS, payload: { id, message, value, max, showButton } }
}

export function incrementProgress(id, by = 1) {
	return { type: INCREMENT_PROGRESS, payload: { id, by } }
}
<|endoftext|>


<commit_before>require( [ "dojo/dom", "dojo/query", "dojo/dom-attr", "dojo/dom-class", "dojo/dom-construct",
	   "dojo/on",
	   "dojo/NodeList-dom" ],
	 function(dom, query, domAttr, domClass, domConstruct, on) {

	     // Add some classes to the cells of the table.
	     var i;
	     for (i = 1; i <= 6; i++) {
		 var tr = dom.byId("ca0" + i + "_row");
		 var j = 0;
		 query("td", tr).forEach(function(node) {
		     domClass.add(node, "space" + j++);
		     if (j === 5 || j === 10 || j === 11) {
g			 domClass.add(node, "breaktime");
		     }
		 });

	     }
	 });<commit_msg>Debugging whiteboard JS.<commit_after>require( [ "dojo/dom", "dojo/query", "dojo/dom-attr", "dojo/dom-class", "dojo/dom-construct",
	   "dojo/on",
	   "dojo/NodeList-dom" ],
	 function(dom, query, domAttr, domClass, domConstruct, on) {

	     // Add some classes to the cells of the table.
	     var i;
	     for (i = 1; i <= 6; i++) {
		 var tr = dom.byId("ca0" + i + "_row");
		 var j = 0;
		 query("td", tr).forEach(function(node) {
		     domClass.add(node, "space" + j);
		     if (j === 5 || j === 10 || j === 11) {
			 domClass.add(node, "breaktime");
		     }
		     j++;
		 });

	     }
	 });<|endoftext|>


<commit_before>import React, { Component } from 'react';
import Translate from '../../Translate/Translate.react';
import RaisedButton from 'material-ui/RaisedButton';
export default class ShareOnSocialMedia extends Component{
	constructor(props){
		super(props);
		this.state={
			style:{ margin:20},
			loginStatus: 'not connected',
		};
		this.Share=this.Share.bind(this);
		this.facebookLogin=this.facebookLogin.bind(this);
		this.statusChangeCallback=this.statusChangeCallback.bind(this);
		this.testAPI=this.testAPI.bind(this);
		this.checkLoginStatus=this.checkLoginStatus.bind(this);
	}

	facebookLoginAPI() {
    window.fbAsyncInit = function() {
    window.FB.init({
      appId      : '136831073699181',
      cookie     : true,
      xfbml      : true,
      version    : 'v2.11'
    });
    window.FB.AppEvents.logPageView();
  };

  (function(d, s, id){
     var js, fjs = d.getElementsByTagName(s)[0];
     if (d.getElementById(id)) {return;}
     js = d.createElement(s); js.id = id;
     js.src = 'https://connect.facebook.net/en_US/sdk.js';
     fjs.parentNode.insertBefore(js, fjs);
   }(document, 'script', 'facebook-jssdk'));
		  }
		  componentDidMount()
      {
				this.facebookLoginAPI();
			}
			testAPI()
      {
				window.FB.api('/me', function(response){});
				this.setState({loginStatus:'connected'});
			}
			statusChangeCallback (response)
      {
				if (response.status === 'connected')
        {
				  this.testAPI();
				} else if (response.status === 'not_authorized')
        {
					// console.log("login to SUSI");
				} else
        {
					// console.log("login to facebook.");
				}
			}

			checkLoginStatus()
      {
	      window.FB.getLoginStatus(function(response)
        {
          this.statusChangeCallback(response);
	      }.bind(this));
			}

			  facebookLogin()
        {
				      window.FB.login(this.checkLoginStatus);
				}

				Share(){
          if(this.state.loginStatus === 'connected' || this.state.loginStatus === 'not connected')
          {
            window.FB.ui({
            method: 'feed',
            link: 'https://chat.susi.ai',
            caption: 'SUSI by FOSSASIA',
            }, function(response){});
          }
				}

    render(){
        return (

								<Translate text="Share about SUSI on Facebook"/>

								<RaisedButton
                					label={<Translate text="Share on Facebook" />}
                					style={this.state.style}
                					backgroundColor='#4285f4'
                					labelColor='#fff'
                					keyboardFocused={false}
                					onTouchTap={this.Share}
                				/>

								<Translate text="Share about SUSI on Twitter"/>

								<RaisedButton
                					label={<Translate text="Share on Twitter" />}
                					style={this.state.style}
                					backgroundColor='#4285f4'
                					labelColor='#fff'
                					keyboardFocused={false}
                					onClick={()=> window.open('https://twitter.com/intent/tweet?text=Let%27s%20chat%20with%20SUSI,%20the%20Open%20Source%20personal%20assistant!%0Ahttps%3A%2F%2Fsusi.ai.%20It%27s%20awesome%20%23susiai!%0A@susiai_', '_blank')}
                				/>

								<Translate text="Share about SUSI on Google +"/>

								<RaisedButton
                					label={<Translate text="Share on Google+" />}
                					style={this.state.style}
                					backgroundColor='#4285f4'
                					labelColor='#fff'
                					keyboardFocused={false}
                					onClick={()=> window.open('https://plus.google.com/share?url=https://chat.susi.ai/', '_blank')}
                				/>

        );
    }
}
// Resources:
// https://developers.facebook.com/docs/facebook-login/web
// https://developers.facebook.com/docs/sharing/reference/share-dialog
// https://developers.facebook.com/docs/sharing/reference/feed-dialog
// https://developers.facebook.com/docs/javascript/quickstart
<commit_msg>fix #1175 - improve social media share page (#1179)<commit_after>import React, { Component } from 'react';
import Translate from '../../Translate/Translate.react';
import FontIcon from 'material-ui/FontIcon';
import RaisedButton from 'material-ui/RaisedButton';
export default class ShareOnSocialMedia extends Component{
	constructor(props){
		super(props);
		this.state={
			style:{ margin:20},
			loginStatus: 'not connected',
		};
		this.Share=this.Share.bind(this);
		this.facebookLogin=this.facebookLogin.bind(this);
		this.statusChangeCallback=this.statusChangeCallback.bind(this);
		this.testAPI=this.testAPI.bind(this);
		this.checkLoginStatus=this.checkLoginStatus.bind(this);
	}

	facebookLoginAPI() {
    window.fbAsyncInit = function() {
    window.FB.init({
      appId      : '136831073699181',
      cookie     : true,
      xfbml      : true,
      version    : 'v2.11'
    });
    window.FB.AppEvents.logPageView();
  };

  (function(d, s, id){
     var js, fjs = d.getElementsByTagName(s)[0];
     if (d.getElementById(id)) {return;}
     js = d.createElement(s); js.id = id;
     js.src = 'https://connect.facebook.net/en_US/sdk.js';
     fjs.parentNode.insertBefore(js, fjs);
   }(document, 'script', 'facebook-jssdk'));
		  }
		  componentDidMount()
      {
				this.facebookLoginAPI();
			}
			testAPI()
      {
				window.FB.api('/me', function(response){});
				this.setState({loginStatus:'connected'});
			}
			statusChangeCallback (response)
      {
				if (response.status === 'connected')
        {
				  this.testAPI();
				} else if (response.status === 'not_authorized')
        {
					// console.log("login to SUSI");
				} else
        {
					// console.log("login to facebook.");
				}
			}

			checkLoginStatus()
      {
	      window.FB.getLoginStatus(function(response)
        {
          this.statusChangeCallback(response);
	      }.bind(this));
			}

			  facebookLogin()
        {
				      window.FB.login(this.checkLoginStatus);
				}

				Share(){
          if(this.state.loginStatus === 'connected' || this.state.loginStatus === 'not connected')
          {
            window.FB.ui({
            method: 'share',
            href: 'https://chat.susi.ai',
            caption: 'SUSI by FOSSASIA',
						hashtag:'#FOSSASIA',
						quote:'Lets chat with susi, the open source personal assistant'
            }, function(response){});
          }
				}

    render(){
		const styles={
			buttonDiv:{
				marginTop: '10px',
				'marginBottom':'0px',
				fontSize: '15px',
				fontWeight: 'bold'
			}
		};
        return (

								<Translate text="Share about SUSI on Facebook"/>

								<RaisedButton
                					label={<Translate text="Share on Facebook" />}
                					style={this.state.style}
													backgroundColor='#3B5998'
                					labelColor='#fff'
													icon={<FontIcon className="fa fa-facebook" />}
                					keyboardFocused={false}
                					onTouchTap={this.Share}
                				/>

								<Translate text="Share about SUSI on Twitter"/>

								<RaisedButton
                					label={<Translate text="Share on Twitter" />}
                					style={this.state.style}
													backgroundColor='#00aced'
													labelColor='#fff'
													icon={<FontIcon className="fa fa-twitter" />}
                					keyboardFocused={false}
                					onClick={()=> window.open('https://twitter.com/intent/tweet?text=Let%27s%20chat%20with%20SUSI,%20the%20Open%20Source%20personal%20assistant!%0Ahttps%3A%2F%2Fsusi.ai.%20It%27s%20awesome%20%23susiai!%0A@susiai_', '_blank')}
                				/>

								<Translate text="Share about SUSI on Google +"/>

								<RaisedButton
                					label={<Translate text="Share on Google+" />}
                					style={this.state.style}
													backgroundColor='#d34836'
                					labelColor='#fff'
													icon={<FontIcon className="fa fa-google-plus" />}
                					keyboardFocused={false}
                					onClick={()=> window.open('https://plus.google.com/share?url=https://chat.susi.ai/', '_blank')}
                				/>

        );
    }
}
// Resources:
// https://developers.facebook.com/docs/facebook-login/web
// https://developers.facebook.com/docs/sharing/reference/share-dialog
// https://developers.facebook.com/docs/sharing/reference/feed-dialog
// https://developers.facebook.com/docs/javascript/quickstart
<|endoftext|>


<commit_before>define([
	"dojo/_base/declare", "dijit/layout/BorderContainer", "dojo/on",
	"./ActionBar","./ContainerActionBar","dijit/layout/TabContainer",
	"dijit/layout/ContentPane","circulus/Viewer","circulus/LineTrack",
	"circulus/SectionTrack","dojo/_base/lang","dojo/request"
], function(
	declare,BorderContainer,on,
	ActionBar, ContainerActionBar,TabContainer,
	ContentPane,CirculusViewer,LineTrack,SectionTrack,lang,xhr
){

	return declare([BorderContainer], {
		gutters: true,
		query: null,
		genome_id: "",
		apiServiceUrl: window.App.dataAPI,

		_setQueryAttr: function(query){
		},

		onSetGenomeId: function(attr,oldVal,gid){
			this.getReferenceSequences(gid).then(lang.hitch(this, function(refseqs){
				this.set("referenceSequences",refseqs)
			}))
		},

		getReferenceSequences: function(gid, includeSequences, refresh){

			var query = "?eq(genome_id," + gid + ")&select(topology,gi,accession,length,sequence_id,gc_content,owner,sequence_type,taxon_id,public,genome_id,genome_name,date_inserted,date_modified" + (includeSequences?",sequence":"")+ ")&sort(+accession)&limit(1000)";

			return xhr.get(this.apiServiceUrl + "/genome_sequence/" + query, {
				headers: {
					accept: "application/json",
					'X-Requested-With': null,
					'Authorization': (window.App.authorizationToken || "")
				},
				handleAs: "json"
			}).then(lang.hitch(this, function(refseqs){
				refseqs = refseqs.map(function(r){
					r.name = r.accession;
					r.start = 0;
					r.end = r.length;
					return r;
				}).sort(function(a,b){
					return a.name > b.name;
				})
				return refseqs;
			}));
		},

		addFeatureTrack: function(gid, filter, strand,fill,stroke,background){
			var fields=["feature_id","feature_type","sequence_id","segments","gi","na_length","pos_group","strand","public","aa_length","patric_id","owner",
						"location","protein_id","refseq_locus_tag","taxon_id","accession","end", "genome_name", "product","genome_id","annotation","start"]

			var query =  "?and(eq(genome_id," + gid + "),ne(feature_type,source)," + filter + ")&sort(+accession,+start)" + "&select(" + fields.join(",") + ")&limit(25000)";

			var track = this.viewer.addTrack({
				type: SectionTrack,
				options: {loading: true, trackWidth: 32,fill: fill, stroke: stroke, gap: 0, background: background},
			})

			return xhr.get(this.apiServiceUrl + "/genome_feature/" + query, {
				headers: {
					accept: "application/json",
					'X-Requested-With': null,
					'Authorization': (window.App.authorizationToken || "")
				},
				handleAs: "json"
			}).then(lang.hitch(this, function(refseqs){
				refseqs = refseqs.filter(function(r){
					if (strand === null){ return true};
					if (strand){
						return r.strand && r.strand=="+"
					}else{
						return r.strand != "+";
					}
				}).map(function(r){
					r.name = r.accession;
					r.length = r.end - r.start;
					return r;
				}).sort(function(a,b){
					return a.name > b.name;
				})

				console.log("Features: ", refseqs)

				track.set("data", refseqs)

				return refseqs;
			}));
		},

		onSetReferenceSequences: function(attr,oldVal, refseqs){
			console.log("RefSeqs: ", refseqs);

			this.viewer.addTrack({
				type: SectionTrack,
				options: {trackWidth: 10,fill: [2, 0, 123], stroke: null, gap: .5, background: {fill: null, stroke: null}},
				data: refseqs
			},"perimeter", true)

			this.addFeatureTrack(this.state.genome_ids[0], "and(eq(annotation,PATRIC),eq(feature_type,CDS),eq(strand,\+))", true, [50, 137, 34], null)
			this.addFeatureTrack(this.state.genome_ids[0], "and(eq(annotation,PATRIC),eq(feature_type,CDS),eq(strand,%22-%22))", false, [105, 243, 101], null)
			// this.addFeatureTrack(this.state.genome_ids[0], "ne(feature_type,CDS)", false, [105, 243, 101], null)
			this.addFeatureTrack(this.state.genome_ids[0], "and(eq(annotation,PATRIC),eq(feature_type,pseudogene))", null, [77, 83, 233], null, {stroke: "", fill: "#eeeeee"})
			this.addFeatureTrack(this.state.genome_ids[0], "and(eq(annotation,PATRIC),eq(feature_type,tRNA))", null, [162, 0, 152], null, {stroke: ""})
			this.addFeatureTrack(this.state.genome_ids[0], "and(eq(annotation,PATRIC),eq(feature_type,rRNA))", null, [243, 110, 0], null, {stroke: "",fill: "#eeeeee"})

			var gcContentTrack = this.viewer.addTrack({
				type: LineTrack,

				options: {max: 1, min: 0,trackWidth: 75,fill: [2, 0, 123], stroke: {width: .5,color: "black"}, gap: .35, background: {fill: [235, 213, 243], stroke: null}},
			},"outer")

			var gcSkewTrack = this.viewer.addTrack({
				type: LineTrack,
				options: {max: 1, min: -1, scoreProperty: "skew", trackWidth: 32,fill: [2, 0, 123], stroke: {width: .5,color: "black"}, gap: .35, background: {fill: [243, 206, 160], stroke: null}},
			},"outer")

			this.getReferenceSequences(this.genome_id, true).then(lang.hitch(this, function(data){
				var gcContentData = this.getGCContent(data);
				console.log("GC CONTENT: ", gcContentData);
				gcContentTrack.set('data', gcContentData)
				gcSkewTrack.set('data', gcContentData)
			}))
		},

		getGCContent: function(data,windowSize){
			windowSize = windowSize||400;

			var gcData=[]

			function calculateGC(accession, seq,ws){
				var cur = seq;
				var slen = seq.length;
				var gc=[];
				var current=0;
				for(current=0;current<seq.length;current+=ws){
					var win = seq.substr(current,ws);
					var wl = win.length;
					var gcs = win.replace(/A/g,"").replace(/T/g,"");
					var gs = gcs.replace(/C/g,"");
					var G = gs.length;
					var C = gcs.length-G;

					gcData.push({accession: accession, score: gcs.length/wl, skew: (G-C)/(G+C), start: current,end: current+wl});
				}
				return gc;
			}

			data.forEach(function(contig){
					calculateGC(contig.accession, contig.sequence,windowSize);
			})
			return gcData
		},

		onSetState: function(attr,oldVal,state){
			console.log("CircularViewerContainer onSetState", state);
			if (state.genome_ids && state.genome_ids[0]){
				this.set("genome_id", state.genome_ids[0]);

				// this.addFeatureTrack(state.genome_ids[0], "eq(feature_type,CDS)", false, [71, 154, 43], null)
				// this.addFeatureTrack(state.genome_ids[0], "eq(feature_type,tRNA)", null, [154, 58, 133], null)
				// this.addFeatureTrack(state.genome_ids[0], "eq(feature_type,pseudogene)", null, [154, 58, 133], null)
				// this.addFeatureTrack(state.genome_ids[0], "eq(feature_type,rRNA)", null, [154, 58, 133], null)
			}
		},

		postCreate: function(){
			this.inherited(arguments);
			this.watch("state", lang.hitch(this, "onSetState"));
			this.watch("genome_id", lang.hitch(this,"onSetGenomeId"));
			this.watch("referenceSequences",lang.hitch(this,"onSetReferenceSequences"));
		},

		visible: false,
		_setVisibleAttr: function(visible) {
			// console.log("GridContainer setVisible: ", visible)
			this.visible = visible;
			if (this.visible && !this._firstView) {
				// console.log("Trigger First View: ", this.id)
				this.onFirstView();
				this._firstView=true;
			}
		},

		onFirstView: function(){
			console.log("onFirstView()")
			if (this._firstView) {
				return;
			}
			if (!this.controlPanel){
				this.controlPanel = new ContentPane({content: "Controller", region: "left",splitter:true, style:"width:175px;"});
			}

			if (!this.viewer){
				this.viewer = new CirculusViewer({
					region: "center",
					centerRadius: 100
			    });
			}

			this.addChild(this.controlPanel);
			this.addChild(this.viewer);
		}
	});
});

<commit_msg>fixed a bug in getGCContent for GC content and GC skew calculation<commit_after>define([
	"dojo/_base/declare", "dijit/layout/BorderContainer", "dojo/on",
	"./ActionBar","./ContainerActionBar","dijit/layout/TabContainer",
	"dijit/layout/ContentPane","circulus/Viewer","circulus/LineTrack",
	"circulus/SectionTrack","dojo/_base/lang","dojo/request"
], function(
	declare,BorderContainer,on,
	ActionBar, ContainerActionBar,TabContainer,
	ContentPane,CirculusViewer,LineTrack,SectionTrack,lang,xhr
){

	return declare([BorderContainer], {
		gutters: true,
		query: null,
		genome_id: "",
		apiServiceUrl: window.App.dataAPI,

		_setQueryAttr: function(query){
		},

		onSetGenomeId: function(attr,oldVal,gid){
			this.getReferenceSequences(gid).then(lang.hitch(this, function(refseqs){
				this.set("referenceSequences",refseqs)
			}))
		},

		getReferenceSequences: function(gid, includeSequences, refresh){

			var query = "?eq(genome_id," + gid + ")&select(topology,gi,accession,length,sequence_id,gc_content,owner,sequence_type,taxon_id,public,genome_id,genome_name,date_inserted,date_modified" + (includeSequences?",sequence":"")+ ")&sort(+accession)&limit(1000)";

			return xhr.get(this.apiServiceUrl + "/genome_sequence/" + query, {
				headers: {
					accept: "application/json",
					'X-Requested-With': null,
					'Authorization': (window.App.authorizationToken || "")
				},
				handleAs: "json"
			}).then(lang.hitch(this, function(refseqs){
				refseqs = refseqs.map(function(r){
					r.name = r.accession;
					r.start = 0;
					r.end = r.length;
					return r;
				}).sort(function(a,b){
					return a.name > b.name;
				})
				return refseqs;
			}));
		},

		addFeatureTrack: function(gid, filter, strand,fill,stroke,background){
			var fields=["feature_id","feature_type","sequence_id","segments","gi","na_length","pos_group","strand","public","aa_length","patric_id","owner",
						"location","protein_id","refseq_locus_tag","taxon_id","accession","end", "genome_name", "product","genome_id","annotation","start"]

			var query =  "?and(eq(genome_id," + gid + "),ne(feature_type,source)," + filter + ")&sort(+accession,+start)" + "&select(" + fields.join(",") + ")&limit(25000)";

			var track = this.viewer.addTrack({
				type: SectionTrack,
				options: {loading: true, trackWidth: 32,fill: fill, stroke: stroke, gap: 0, background: background},
			})

			return xhr.get(this.apiServiceUrl + "/genome_feature/" + query, {
				headers: {
					accept: "application/json",
					'X-Requested-With': null,
					'Authorization': (window.App.authorizationToken || "")
				},
				handleAs: "json"
			}).then(lang.hitch(this, function(refseqs){
				refseqs = refseqs.filter(function(r){
					if (strand === null){ return true};
					if (strand){
						return r.strand && r.strand=="+"
					}else{
						return r.strand != "+";
					}
				}).map(function(r){
					r.name = r.accession;
					r.length = r.end - r.start;
					return r;
				}).sort(function(a,b){
					return a.name > b.name;
				})

				console.log("Features: ", refseqs)

				track.set("data", refseqs)

				return refseqs;
			}));
		},

		onSetReferenceSequences: function(attr,oldVal, refseqs){
			console.log("RefSeqs: ", refseqs);

			this.viewer.addTrack({
				type: SectionTrack,
				options: {trackWidth: 10,fill: [2, 0, 123], stroke: null, gap: .5, background: {fill: null, stroke: null}},
				data: refseqs
			},"perimeter", true)

			this.addFeatureTrack(this.state.genome_ids[0], "and(eq(annotation,PATRIC),eq(feature_type,CDS),eq(strand,\+))", true, [50, 137, 34], null)
			this.addFeatureTrack(this.state.genome_ids[0], "and(eq(annotation,PATRIC),eq(feature_type,CDS),eq(strand,%22-%22))", false, [105, 243, 101], null)
			// this.addFeatureTrack(this.state.genome_ids[0], "ne(feature_type,CDS)", false, [105, 243, 101], null)
			this.addFeatureTrack(this.state.genome_ids[0], "and(eq(annotation,PATRIC),eq(feature_type,pseudogene))", null, [77, 83, 233], null, {stroke: "", fill: "#eeeeee"})
			this.addFeatureTrack(this.state.genome_ids[0], "and(eq(annotation,PATRIC),eq(feature_type,tRNA))", null, [162, 0, 152], null, {stroke: ""})
			this.addFeatureTrack(this.state.genome_ids[0], "and(eq(annotation,PATRIC),eq(feature_type,rRNA))", null, [243, 110, 0], null, {stroke: "",fill: "#eeeeee"})

			var gcContentTrack = this.viewer.addTrack({
				type: LineTrack,

				options: {max: 1, min: 0,trackWidth: 75,fill: [2, 0, 123], stroke: {width: .5,color: "black"}, gap: .35, background: {fill: [235, 213, 243], stroke: null}},
			},"outer")

			var gcSkewTrack = this.viewer.addTrack({
				type: LineTrack,
				options: {max: 1, min: -1, scoreProperty: "skew", trackWidth: 32,fill: [2, 0, 123], stroke: {width: .5,color: "black"}, gap: .35, background: {fill: [243, 206, 160], stroke: null}},
			},"outer")

			this.getReferenceSequences(this.genome_id, true).then(lang.hitch(this, function(data){
				var gcContentData = this.getGCContent(data);
				console.log("GC CONTENT: ", gcContentData);
				gcContentTrack.set('data', gcContentData)
				gcSkewTrack.set('data', gcContentData)
			}))
		},

		getGCContent: function(data,windowSize){
			windowSize = windowSize||400;

			var gcData=[]

			function calculateGC(accession, seq,ws){
				var cur = seq;
				var slen = seq.length;
				var gc=[];
				var current=0;
				for(current=0;current<seq.length;current+=ws){
					var win = seq.substr(current,ws).toUpperCase();
					var wl = win.length;
					var G=0;
					var C=0;
					var gs = win.match(/G/g ||[]);
					if (gs) {
						G = gs.length;
					}

					var cs = win.match(/C/g ||[]);
					if (cs) {
						C = cs.length;
					}

					var GC = G+C; // for skew, (G-C)/(G+C), G+C can't be 0
					if (GC == 0){
						GC = 1;
					}
					gcData.push({accession: accession, score: (G+C)/wl, skew: (G-C)/GC, start: current,end: current+wl});
				}
				return gc;
			}

			data.forEach(function(contig){
					calculateGC(contig.accession, contig.sequence,windowSize);
			})
			return gcData
		},

		onSetState: function(attr,oldVal,state){
			console.log("CircularViewerContainer onSetState", state);
			if (state.genome_ids && state.genome_ids[0]){
				this.set("genome_id", state.genome_ids[0]);

				// this.addFeatureTrack(state.genome_ids[0], "eq(feature_type,CDS)", false, [71, 154, 43], null)
				// this.addFeatureTrack(state.genome_ids[0], "eq(feature_type,tRNA)", null, [154, 58, 133], null)
				// this.addFeatureTrack(state.genome_ids[0], "eq(feature_type,pseudogene)", null, [154, 58, 133], null)
				// this.addFeatureTrack(state.genome_ids[0], "eq(feature_type,rRNA)", null, [154, 58, 133], null)
			}
		},

		postCreate: function(){
			this.inherited(arguments);
			this.watch("state", lang.hitch(this, "onSetState"));
			this.watch("genome_id", lang.hitch(this,"onSetGenomeId"));
			this.watch("referenceSequences",lang.hitch(this,"onSetReferenceSequences"));
		},

		visible: false,
		_setVisibleAttr: function(visible) {
			// console.log("GridContainer setVisible: ", visible)
			this.visible = visible;
			if (this.visible && !this._firstView) {
				// console.log("Trigger First View: ", this.id)
				this.onFirstView();
				this._firstView=true;
			}
		},

		onFirstView: function(){
			console.log("onFirstView()")
			if (this._firstView) {
				return;
			}
			if (!this.controlPanel){
				this.controlPanel = new ContentPane({content: "Controller", region: "left",splitter:true, style:"width:175px;"});
			}

			if (!this.viewer){
				this.viewer = new CirculusViewer({
					region: "center",
					centerRadius: 100
			    });
			}

			this.addChild(this.controlPanel);
			this.addChild(this.viewer);
		}
	});
});

<|endoftext|>


<commit_before>'use strict';

module.exports =
angular.module('quill-grammar.services.crud', [
  'firebase'
])

.factory('CrudService', function(firebaseUrl, $firebase, $q) {
  function crud(entity) {
    if (firebaseUrl[firebaseUrl.length - 1] !== '/') {
      firebaseUrl = firebaseUrl + '/';
    }
    if (!entity || entity === '') {
      throw new Error('Firebase Entity MUST be defined');
    }
    var baseRef = new Firebase(firebaseUrl + entity);
    var baseCollection = $firebase(baseRef).$asArray();
    function save(entityItem) {
      var d = $q.defer();
      baseCollection.$loaded().then(function() {
        baseCollection.$add(entityItem).then(function(ref) {
          d.resolve(ref.key());
        }, function(error){
          d.reject(error);
        });
      });
      return d.promise;
    }

    function del(entityItem) {
      var d = $q.defer();
      baseCollection.$loaded().then(function() {
        baseCollection.$remove(entityItem).then(function(ref) {
          d.resolve(ref.key());
        }, function(error){
          d.reject(error);
        });
      });
      return d.promise;
    }

    function all() {
      var d = $q.defer();
      baseCollection.$loaded().then(function() {
        d.resolve(baseCollection);
      }, function(error) {
        d.reject(error);
      });
      return d.promise;
    }

    function get(entityId) {
      var d = $q.defer();
      baseCollection.$loaded().then(function() {
        var record = baseCollection.$getRecord(entityId);
        if (record) {
          d.resolve(record);
        } else {
          d.reject(new Error('Record with ' + entityId + ' not found.'));
        }
      });
      return d.promise;
    }

    return {
      save: save,
      del: del,
      all: all,
      get: get,
    };
  }

  return crud;
});
<commit_msg>Sanitize incomming models<commit_after>'use strict';

module.exports =
angular.module('quill-grammar.services.crud', [
  'firebase',
  'underscore',
])

.factory('CrudService', function(firebaseUrl, $firebase, $q, _) {
  function crud(entity, properties) {
    if (firebaseUrl[firebaseUrl.length - 1] !== '/') {
      firebaseUrl = firebaseUrl + '/';
    }
    if (!entity || entity === '') {
      throw new Error('Firebase Entity MUST be defined');
    }
    var baseRef = new Firebase(firebaseUrl + entity);
    var baseCollection = $firebase(baseRef).$asArray();

    function sanitize(item) {
      if (properties) {
        return _.pick(item, properties);
      }
      return item;
    }

    function save(item) {
      var d = $q.defer();
      var entityItem = sanitize(item);
      baseCollection.$loaded().then(function() {
        baseCollection.$add(entityItem).then(function(ref) {
          d.resolve(ref.key());
        }, function(error){
          d.reject(error);
        });
      });
      return d.promise;
    }

    function del(item) {
      var entityItem = sanitize(item);
      var d = $q.defer();
      baseCollection.$loaded().then(function() {
        baseCollection.$remove(entityItem).then(function(ref) {
          d.resolve(ref.key());
        }, function(error){
          d.reject(error);
        });
      });
      return d.promise;
    }

    function all() {
      var d = $q.defer();
      baseCollection.$loaded().then(function() {
        d.resolve(baseCollection);
      }, function(error) {
        d.reject(error);
      });
      return d.promise;
    }

    function get(entityId) {
      var d = $q.defer();
      baseCollection.$loaded().then(function() {
        var record = baseCollection.$getRecord(entityId);
        if (record) {
          d.resolve(record);
        } else {
          d.reject(new Error('Record with ' + entityId + ' not found.'));
        }
      });
      return d.promise;
    }

    return {
      save: save,
      del: del,
      all: all,
      get: get,
    };
  }

  return crud;
});
<|endoftext|>


<commit_before>var _config = {
	fixture: null,
	Test: [],
	stats: {
		all: 0,
		bad: 0
	},
	queue: [],
	blocking: true,
	timeout: null,
	expected: null,
	currentModule: null,
	asyncTimeout: 2 // seconds for async timeout
};

$(function() {
	$('#userAgent').html(navigator.userAgent);
	runTest();
});

function synchronize(callback) {
	_config.queue[_config.queue.length] = callback;
	if(!_config.blocking) {
		process();
	}
}

function process() {
	while(_config.queue.length && !_config.blocking) {
		var call = _config.queue[0];
		_config.queue = _config.queue.slice(1);
		call();
	}
}

function stop(allowFailure) {
	_config.blocking = true;
	var handler = allowFailure ? start : function() {
		ok( false, "Test timed out" );
		start();
	};
	_config.timeout = setTimeout(handler, _config.asyncTimeout * 1000);
}
function start() {
	if(_config.timeout)
		clearTimeout(_config.timeout);
	_config.blocking = false;
	process();
}

function runTest() {
	_config.blocking = false;
	var time = new Date();
	_config.fixture = document.getElementById('main').innerHTML;
	synchronize(function() {
		time = new Date() - time;
		$("
").html(['
Tests completed in ',
			time, ' milliseconds.
',
			_config.stats.bad, ' tests of ', _config.stats.all, ' failed.
']
			.join(''))
			.appendTo("body");
		$("#banner").addClass(_config.stats.bad ? "fail" : "pass");
	});
}

function test(name, callback, nowait) {
	if(_config.currentModule)
		name = _config.currentModule + " module: " + name;

	var filter = location.search.slice(1);
	if ( filter && encodeURIComponent(name) != filter )
		return;

	synchronize(function() {
		_config.Test = [];
		try {
			callback();
		} catch(e) {
			if( typeof console != "undefined" && console.error && console.warn ) {
				console.error("Test " + name + " died, exception and test follows");
				console.error(e);
				console.warn(callback.toString());
			}
			_config.Test.push( [ false, "Died on test #" + (_config.Test.length+1) + ": " + e ] );
		}
	});
	synchronize(function() {
		reset();

		// don't output pause tests
		if(nowait) return;

		if(_config.expected && _config.expected != _config.Test.length) {
			_config.Test.push( [ false, "Expected " + _config.expected + " assertions, but " + _config.Test.length + " were run" ] );
		}
		_config.expected = null;

		var good = 0, bad = 0;
		var ol = document.createElement("ol");
		ol.style.display = "none";
		var li = "", state = "pass";
		for ( var i = 0; i < _config.Test.length; i++ ) {
			var li = document.createElement("li");
			li.className = _config.Test[i][0] ? "pass" : "fail";
			li.innerHTML = _config.Test[i][1];
			ol.appendChild( li );

			_config.stats.all++;
			if ( !_config.Test[i][0] ) {
				state = "fail";
				bad++;
				_config.stats.bad++;
			} else good++;
		}

		var li = document.createElement("li");
		li.className = state;

		var b = document.createElement("strong");
		b.innerHTML = name + " (" + bad + ", " + good + ", " + _config.Test.length + ")";
		b.onclick = function(){
			var n = this.nextSibling;
			if ( jQuery.css( n, "display" ) == "none" )
				n.style.display = "block";
			else
				n.style.display = "none";
		};
		b.ondblclick = function(event) {
			var target = jQuery(event.target).filter("strong").clone();
			if ( target.length ) {
				target.children().remove();
				location.href = location.href.match(/^(.+?)(\?.*)?$/)[1] + "?" + encodeURIComponent($.trim(target.text()));
			}
		};
		li.appendChild( b );
		li.appendChild( ol );

		document.getElementById("tests").appendChild( li );
	});
}

// call on start of module test to prepend name to all tests
function module(moduleName) {
	_config.currentModule = moduleName;
}

/**
 * Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through.
 */
function expect(asserts) {
	_config.expected = asserts;
}

/**
 * Resets the test setup. Useful for tests that modify the DOM.
 */
function reset() {
	document.getElementById('main').innerHTML = _config.fixture;
}

/**
 * Asserts true.
 * @example ok( $("a").size() > 5, "There must be at least 5 anchors" );
 */
function ok(a, msg) {
	_config.Test.push( [ !!a, msg ] );
}

/**
 * Asserts that two arrays are the same
 */
function isSet(a, b, msg) {
	var ret = true;
	if ( a && b && a.length != undefined && a.length == b.length ) {
		for ( var i = 0; i < a.length; i++ )
			if ( a[i] != b[i] )
				ret = false;
	} else
		ret = false;
	if ( !ret )
		_config.Test.push( [ ret, msg + " expected: " + serialArray(b) + " result: " + serialArray(a) ] );
	else
		_config.Test.push( [ ret, msg ] );
}

/**
 * Asserts that two objects are equivalent
 */
function isObj(a, b, msg) {
	var ret = true;

	if ( a && b ) {
		for ( var i in a )
			if ( a[i] != b[i] )
				ret = false;

		for ( i in b )
			if ( a[i] != b[i] )
				ret = false;
	} else
		ret = false;

    _config.Test.push( [ ret, msg ] );
}

function serialArray( a ) {
	var r = [];

	if ( a && a.length )
        for ( var i = 0; i < a.length; i++ ) {
            var str = a[i].nodeName;
            if ( str ) {
                str = str.toLowerCase();
                if ( a[i].id )
                    str += "#" + a[i].id;
            } else
                str = a[i];
            r.push( str );
        }

	return "[ " + r.join(", ") + " ]"
}

/**
 * Returns an array of elements with the given IDs, eg.
 * @example q("main", "foo", "bar")
 * @result [
, , <input id="bar">]
 */
function q() {
	var r = [];
	for ( var i = 0; i < arguments.length; i++ )
		r.push( document.getElementById( arguments[i] ) );
	return r;
}

/**
 * Asserts that a select matches the given IDs
 * @example t("Check for something", "//[a]", ["foo", "baar"]);
 * @result returns true if "//[a]" return two elements with the IDs 'foo' and 'baar'
 */
function t(a,b,c) {
	var f = jQuery(b);
	var s = "";
	for ( var i = 0; i < f.length; i++ )
		s += (s && ",") + '"' + f[i].id + '"';
	isSet(f, q.apply(q,c), a + " (" + b + ")");
}

/**
 * Add random number to url to stop IE from caching
 *
 * @example url("data/test.html")
 * @result "data/test.html?10538358428943"
 *
 * @example url("data/test.php?foo=bar")
 * @result "data/test.php?foo=bar&10538358345554"
 */
function url(value) {
	return value + (/\?/.test(value) ? "&" : "?") + new Date().getTime() + "" + parseInt(Math.random()*100000);
}

/**
 * Checks that the first two arguments are equal, with an optional message.
 * Prints out both expected and actual values on failure.
 *
 * Prefered to ok( expected == actual, message )
 *
 * @example equals( "Expected 2 characters.", v.formatMessage("Expected {0} characters.", 2) );
 *
 * @param Object expected
 * @param Object actual
 * @param String message (optional)
 */
function equals(expected, actual, message) {
	var result = expected == actual;
	message = message || (result ? "okay" : "failed");
	_config.Test.push( [ result, result ? message + ": " + expected : message + " expected: " + expected + " actual: " + actual ] );
}

/**
 * Trigger an event on an element.
 *
 * @example triggerEvent( document.body, "click" );
 *
 * @param DOMElement elem
 * @param String type
 */
function triggerEvent( elem, type, event ) {
	if ( jQuery.browser.mozilla || jQuery.browser.opera ) {
		event = document.createEvent("MouseEvents");
		event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,
			0, 0, 0, 0, 0, false, false, false, false, 0, null);
		elem.dispatchEvent( event );
	} else if ( jQuery.browser.msie ) {
		elem.fireEvent("on"+type);
	}
}
<commit_msg>use jquery for dblclick handler to access event.target<commit_after>var _config = {
	fixture: null,
	Test: [],
	stats: {
		all: 0,
		bad: 0
	},
	queue: [],
	blocking: true,
	timeout: null,
	expected: null,
	currentModule: null,
	asyncTimeout: 2 // seconds for async timeout
};

$(function() {
	$('#userAgent').html(navigator.userAgent);
	runTest();
});

function synchronize(callback) {
	_config.queue[_config.queue.length] = callback;
	if(!_config.blocking) {
		process();
	}
}

function process() {
	while(_config.queue.length && !_config.blocking) {
		var call = _config.queue[0];
		_config.queue = _config.queue.slice(1);
		call();
	}
}

function stop(allowFailure) {
	_config.blocking = true;
	var handler = allowFailure ? start : function() {
		ok( false, "Test timed out" );
		start();
	};
	_config.timeout = setTimeout(handler, _config.asyncTimeout * 1000);
}
function start() {
	if(_config.timeout)
		clearTimeout(_config.timeout);
	_config.blocking = false;
	process();
}

function runTest() {
	_config.blocking = false;
	var time = new Date();
	_config.fixture = document.getElementById('main').innerHTML;
	synchronize(function() {
		time = new Date() - time;
		$("
").html(['
Tests completed in ',
			time, ' milliseconds.
',
			_config.stats.bad, ' tests of ', _config.stats.all, ' failed.
']
			.join(''))
			.appendTo("body");
		$("#banner").addClass(_config.stats.bad ? "fail" : "pass");
	});
}

function test(name, callback, nowait) {
	if(_config.currentModule)
		name = _config.currentModule + " module: " + name;

	var filter = location.search.slice(1);
	if ( filter && encodeURIComponent(name) != filter )
		return;

	synchronize(function() {
		_config.Test = [];
		try {
			callback();
		} catch(e) {
			if( typeof console != "undefined" && console.error && console.warn ) {
				console.error("Test " + name + " died, exception and test follows");
				console.error(e);
				console.warn(callback.toString());
			}
			_config.Test.push( [ false, "Died on test #" + (_config.Test.length+1) + ": " + e ] );
		}
	});
	synchronize(function() {
		reset();

		// don't output pause tests
		if(nowait) return;

		if(_config.expected && _config.expected != _config.Test.length) {
			_config.Test.push( [ false, "Expected " + _config.expected + " assertions, but " + _config.Test.length + " were run" ] );
		}
		_config.expected = null;

		var good = 0, bad = 0;
		var ol = document.createElement("ol");
		ol.style.display = "none";
		var li = "", state = "pass";
		for ( var i = 0; i < _config.Test.length; i++ ) {
			var li = document.createElement("li");
			li.className = _config.Test[i][0] ? "pass" : "fail";
			li.innerHTML = _config.Test[i][1];
			ol.appendChild( li );

			_config.stats.all++;
			if ( !_config.Test[i][0] ) {
				state = "fail";
				bad++;
				_config.stats.bad++;
			} else good++;
		}

		var li = document.createElement("li");
		li.className = state;

		var b = document.createElement("strong");
		b.innerHTML = name + " (" + bad + ", " + good + ", " + _config.Test.length + ")";
		b.onclick = function(){
			var n = this.nextSibling;
			if ( jQuery.css( n, "display" ) == "none" )
				n.style.display = "block";
			else
				n.style.display = "none";
		};
		$(b).dblclick(function(event) {
			var target = jQuery(event.target).filter("strong").clone();
			if ( target.length ) {
				target.children().remove();
				location.href = location.href.match(/^(.+?)(\?.*)?$/)[1] + "?" + encodeURIComponent($.trim(target.text()));
			}
		});
		li.appendChild( b );
		li.appendChild( ol );

		document.getElementById("tests").appendChild( li );
	});
}

// call on start of module test to prepend name to all tests
function module(moduleName) {
	_config.currentModule = moduleName;
}

/**
 * Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through.
 */
function expect(asserts) {
	_config.expected = asserts;
}

/**
 * Resets the test setup. Useful for tests that modify the DOM.
 */
function reset() {
	document.getElementById('main').innerHTML = _config.fixture;
}

/**
 * Asserts true.
 * @example ok( $("a").size() > 5, "There must be at least 5 anchors" );
 */
function ok(a, msg) {
	_config.Test.push( [ !!a, msg ] );
}

/**
 * Asserts that two arrays are the same
 */
function isSet(a, b, msg) {
	var ret = true;
	if ( a && b && a.length != undefined && a.length == b.length ) {
		for ( var i = 0; i < a.length; i++ )
			if ( a[i] != b[i] )
				ret = false;
	} else
		ret = false;
	if ( !ret )
		_config.Test.push( [ ret, msg + " expected: " + serialArray(b) + " result: " + serialArray(a) ] );
	else
		_config.Test.push( [ ret, msg ] );
}

/**
 * Asserts that two objects are equivalent
 */
function isObj(a, b, msg) {
	var ret = true;

	if ( a && b ) {
		for ( var i in a )
			if ( a[i] != b[i] )
				ret = false;

		for ( i in b )
			if ( a[i] != b[i] )
				ret = false;
	} else
		ret = false;

    _config.Test.push( [ ret, msg ] );
}

function serialArray( a ) {
	var r = [];

	if ( a && a.length )
        for ( var i = 0; i < a.length; i++ ) {
            var str = a[i].nodeName;
            if ( str ) {
                str = str.toLowerCase();
                if ( a[i].id )
                    str += "#" + a[i].id;
            } else
                str = a[i];
            r.push( str );
        }

	return "[ " + r.join(", ") + " ]"
}

/**
 * Returns an array of elements with the given IDs, eg.
 * @example q("main", "foo", "bar")
 * @result [
, , <input id="bar">]
 */
function q() {
	var r = [];
	for ( var i = 0; i < arguments.length; i++ )
		r.push( document.getElementById( arguments[i] ) );
	return r;
}

/**
 * Asserts that a select matches the given IDs
 * @example t("Check for something", "//[a]", ["foo", "baar"]);
 * @result returns true if "//[a]" return two elements with the IDs 'foo' and 'baar'
 */
function t(a,b,c) {
	var f = jQuery(b);
	var s = "";
	for ( var i = 0; i < f.length; i++ )
		s += (s && ",") + '"' + f[i].id + '"';
	isSet(f, q.apply(q,c), a + " (" + b + ")");
}

/**
 * Add random number to url to stop IE from caching
 *
 * @example url("data/test.html")
 * @result "data/test.html?10538358428943"
 *
 * @example url("data/test.php?foo=bar")
 * @result "data/test.php?foo=bar&10538358345554"
 */
function url(value) {
	return value + (/\?/.test(value) ? "&" : "?") + new Date().getTime() + "" + parseInt(Math.random()*100000);
}

/**
 * Checks that the first two arguments are equal, with an optional message.
 * Prints out both expected and actual values on failure.
 *
 * Prefered to ok( expected == actual, message )
 *
 * @example equals( "Expected 2 characters.", v.formatMessage("Expected {0} characters.", 2) );
 *
 * @param Object expected
 * @param Object actual
 * @param String message (optional)
 */
function equals(expected, actual, message) {
	var result = expected == actual;
	message = message || (result ? "okay" : "failed");
	_config.Test.push( [ result, result ? message + ": " + expected : message + " expected: " + expected + " actual: " + actual ] );
}

/**
 * Trigger an event on an element.
 *
 * @example triggerEvent( document.body, "click" );
 *
 * @param DOMElement elem
 * @param String type
 */
function triggerEvent( elem, type, event ) {
	if ( jQuery.browser.mozilla || jQuery.browser.opera ) {
		event = document.createEvent("MouseEvents");
		event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,
			0, 0, 0, 0, 0, false, false, false, false, 0, null);
		elem.dispatchEvent( event );
	} else if ( jQuery.browser.msie ) {
		elem.fireEvent("on"+type);
	}
}
<|endoftext|>


<commit_before>window.Bugle = ( function() {

	'use strict';

	// validation util functions
	const _verify = {

		'is': function(obj, type) {
			return Object.prototype.toString.call(obj).slice(8, -1) === type;
		},

		'areAll': function(items, type) {

			var status = false,
				self = this;

			items.forEach(function(item) {
				status = self.is(item, type);
			});

			return status;
		},
	},

	// ensures the we get 'true' sync behaviour
	_async = function(fn) {
		setTimeout(fn, 0);
	},

	// convenience object for throwing helpful errors
	_throwable = (function() {

		var throwError = (message) => {
			throw message;
		};

		return {

			'failedToPublish': function(topic, error) {
				throwError('Failed to publish to instance on topic "' +
					topic + '" [' + error.message + ']')
			},

			'InvalidTopicType': function() {
				throwError('first paren, "topic", must be of type String');
			},

			'InvalidinstanceType': function() {
				throwError('instance value being pushed to topic must be of type Object');
			}
		};

	})();

	// Bugle function constructor
	function Bugle() {

		// holds each topic along with its subscribers
		this.topics = [];

		// tracks the location of an object instance on a topic
		this.oId = 0;
	}

	Bugle.prototype = {

		// pub some data to a topic
		// notify all objects subscribed to the given topic with the data received
		pub: function(topic, data) {

			var emit = () => {

				if(this.topics[topic]) {

					var topicLine = this.topics[topic];

					// execute each topic in topic line in order
					for(var index in topicLine) {

						var obj = topicLine[index],
						args = [data, topic, index];

						try {
							obj.fn.apply(obj.instance, args);
						} catch(e) {

							_async(function() {
								_throwable.failedToPublish(topic, e);
							});
						}
					}
				}
			},

			isTopicString = _verify.is(topic, 'String');

			if(isTopicString) {

				_async(function() { emit(); });

			} else {

				_throwable.InvalidTopicType();
			}

			return true;
		},

		// sub an instance to a topic using a given toCall function to execute on pub
		sub: function(topic, instance, toCall) {

			// verify that param #1 & #3 are of type String
			var areString = _verify.areAll([topic, toCall], 'String'),

			// verify instance is an Object
			isObject = _verify.is(instance, 'Object');

			if(areString) {

				if(isObject) {

					if(!this.topics[topic]) {
						this.topics[topic] = [];
					}

					this.topics[topic].push({
						'oId': (++this.oId),
						'instance': instance,
						'fn': instance[toCall]
					});

					return this.oId;

				} else {
					_throwable.InvalidinstanceType();
				}

			} else {

				_throwable.InvalidTopicType();
			}
		},

		// remove an object from the subscriptions list on a topic with its assigned oId
		unsub: function(topic, oId) {

			var isTopicString = _verify.is(topic, 'String'),

			unsub = () => {

				if(this.topics[topic]) {

					var topicLine = this.topics[topic];

					for(var index in topicLine) {

						var subscriber = topicLine[index];

						if(subscriber.oId === oId) {
							topicLine.splice(index, 1);
						};
					}
				}
			};

			if(isTopicString) {

				_async(function() { unsub(); });

			} else {

				_throwable.InvalidTopicType();
			}
		}
	};

	// user does not have to specify that silly 'new' keyword
	return function(props) {
		return new Bugle();
	};

} )();<commit_msg>updated pub with forEach in place of generic for in loop<commit_after>window.Bugle = ( function() {

	'use strict';

	// validation util functions
	const _verify = {

		'is': function(obj, type) {
			return Object.prototype.toString.call(obj).slice(8, -1) === type;
		},

		'areAll': function(items, type) {

			var status = false,
				self = this;

			items.forEach(function(item) {
				status = self.is(item, type);
			});

			return status;
		},
	},

	// ensures the we get 'true' sync behaviour
	_async = function(fn) {
		setTimeout(fn, 0);
	},

	// convenience object for throwing helpful errors
	_throwable = (function() {

		var throwError = (message) => {
			throw message;
		};

		return {

			'failedToPublish': function(topic, error) {
				throwError('Failed to publish to instance on topic "' +
					topic + '" [' + error.message + ']')
			},

			'InvalidTopicType': function() {
				throwError('first paren, "topic", must be of type String');
			},

			'InvalidinstanceType': function() {
				throwError('instance value being pushed to topic must be of type Object');
			}
		};

	})();

	// Bugle function constructor
	function Bugle() {

		// holds each topic along with its subscribers
		this.topics = [];

		// tracks the location of an object instance on a topic
		this.oId = 0;
	}

	Bugle.prototype = {

		// pub some data to a topic
		// notify all objects subscribed to the given topic with the data received
		pub: function(topic, data) {

			var args = [data, topic],

			emit = () => {

				if(this.topics[topic]) {

					var topicLine = this.topics[topic];

					// execute each topic in topic line in order
					topicLine.forEach(function(subscriber, index) {

						args.push(index);

						try {

							// apply current sub object and pub args to sub function
							subscriber.fn.apply(subscriber.instance, args);

						} catch(e) {

							_async(function() {
								_throwable.failedToPublish(topic, e);
							});
						}

					});
				}
			},

			isTopicString = _verify.is(topic, 'String');

			if(isTopicString) {

				_async(function() { emit(); });

			} else {

				_throwable.InvalidTopicType();
			}

			return true;
		},

		// sub an instance to a topic using a given toCall function to execute on pub
		sub: function(topic, instance, toCall) {

			// verify that param #1 & #3 are of type String
			var areString = _verify.areAll([topic, toCall], 'String'),

			// verify instance is an Object
			isObject = _verify.is(instance, 'Object');

			if(areString) {

				if(isObject) {

					if(!this.topics[topic]) {
						this.topics[topic] = [];
					}

					this.topics[topic].push({
						'oId': (++this.oId),
						'instance': instance,
						'fn': instance[toCall]
					});

					return this.oId;

				} else {
					_throwable.InvalidinstanceType();
				}

			} else {

				_throwable.InvalidTopicType();
			}
		},

		// remove an object from the subscriptions list on a topic with its assigned oId
		unsub: function(topic, oId) {

			var isTopicString = _verify.is(topic, 'String'),

			unsub = () => {

				if(this.topics[topic]) {

					var topicLine = this.topics[topic];

					// loop for specified oId until we get a match
					for(var index in topicLine) {

						if(topicLine[index].oId === oId) {
							topicLine.splice(index, 1);
							return;
						};
					}
				}
			};

			if(isTopicString) {

				_async(function() { unsub(); });

			} else {

				_throwable.InvalidTopicType();
			}
		}
	};

	// user does not have to specify that silly 'new' keyword
	return function(props) {
		return new Bugle();
	};

} )();<|endoftext|>