<commit_before>'use strict';

import core from 'bower:metal/src/core';
import dom from 'bower:metal/src/dom/dom';
import Attribute from 'bower:metal/src/attribute/Attribute';
import EventHandler from 'bower:metal/src/events/EventHandler';

class Toggler extends Attribute {
  constructor(opt_config) {
    super(opt_config);

    this.headerEventHandler_ = new EventHandler();

    this.on('expandedChanged', this.syncExpanded);
    this.on('headerChanged', this.syncHeader);

    this.syncExpanded();
    this.syncHeader();
  }

  handleKeydown(event) {
    if (event.keyCode === 13 || event.keyCode === 32) {
      this.toggle();
      event.preventDefault();
    }
  }

  syncExpanded() {
    if (this.expanded) {
      dom.addClasses(this.content, Toggler.CSS_EXPANDED);
      dom.removeClasses(this.content, Toggler.CSS_COLLAPSED);
    } else {
      dom.removeClasses(this.content, Toggler.CSS_EXPANDED);
      dom.addClasses(this.content, Toggler.CSS_COLLAPSED);
    }
  }

  syncHeader() {
    this.headerEventHandler_.removeAllListeners();
    if (this.header) {
      this.headerEventHandler_.add(
        dom.on(this.header, 'click', this.toggle.bind(this)),
        dom.on(this.header, 'keydown', this.handleKeydown.bind(this))
      );
    }
  }

  toggle() {
    this.expanded = !this.expanded;
  }
}

Toggler.ATTRS = {
  content: {
    setter: dom.toElement,
    validator: value => core.isString(value) || core.isElement(value)
  },

  expanded: {
    value: false
  },

  header: {
    setter: dom.toElement,
    validator: value => core.isString(value) || core.isElement(value)
  }
};

Toggler.CSS_EXPANDED = 'toggler-expanded';
Toggler.CSS_COLLAPSED = 'toggler-collapsed';

export default Toggler;
<commit_msg>Adds documentation<commit_after>'use strict';

import core from 'bower:metal/src/core';
import dom from 'bower:metal/src/dom/dom';
import Attribute from 'bower:metal/src/attribute/Attribute';
import EventHandler from 'bower:metal/src/events/EventHandler';

/**
 * Toggler component.
 */
class Toggler extends Attribute {
	/**
	 * @inheritDoc
	 */
  constructor(opt_config) {
    super(opt_config);

    this.headerEventHandler_ = new EventHandler();

    this.on('expandedChanged', this.syncExpanded);
    this.on('headerChanged', this.syncHeader);

    this.syncExpanded();
    this.syncHeader();
  }

  /**
   * Handles a `keydown` event on the header.
   * @param {!Event} event
   * @protected
   */
  handleKeydown_(event) {
    if (event.keyCode === 13 || event.keyCode === 32) {
      this.toggle();
      event.preventDefault();
    }
  }

  /**
   * Syncs the component according to the value of the `expanded` attribute,
   * updating the css class of the `content` element.
   */
  syncExpanded() {
    if (this.expanded) {
      dom.addClasses(this.content, Toggler.CSS_EXPANDED);
      dom.removeClasses(this.content, Toggler.CSS_COLLAPSED);
    } else {
      dom.removeClasses(this.content, Toggler.CSS_EXPANDED);
      dom.addClasses(this.content, Toggler.CSS_COLLAPSED);
    }
  }

  /**
   * Syncs the component according to the value of the `header` attribute,
   * attaching events to the new element and detaching from any previous one.
   */
  syncHeader() {
    this.headerEventHandler_.removeAllListeners();
    if (this.header) {
      this.headerEventHandler_.add(
        dom.on(this.header, 'click', this.toggle.bind(this)),
        dom.on(this.header, 'keydown', this.handleKeydown_.bind(this))
      );
    }
  }

  /**
   * Toggles the content's visibility.
   */
  toggle() {
    this.expanded = !this.expanded;
  }
}

/**
 * Attributes configuration.
 */
Toggler.ATTRS = {
  /**
   * The element that should be expanded/collapsed by this toggler.
   * @type {string|!Element}
   */
  content: {
    setter: dom.toElement,
    validator: value => core.isString(value) || core.isElement(value)
  },

  /**
   * Flag indicating if the content is currently expanded or collapsed.
   * @type {boolean}
   */
  expanded: {
    value: false
  },

  /**
   * The element that should be trigger toggling.
   * @type {string|!Element}
   */
  header: {
    setter: dom.toElement,
    validator: value => core.isString(value) || core.isElement(value)
  }
};

/**
 * The CSS class added to the content when it's collapsed.
 */
Toggler.CSS_COLLAPSED = 'toggler-collapsed';

/**
 * The CSS class added to the content when it's expanded.
 */
Toggler.CSS_EXPANDED = 'toggler-expanded';

export default Toggler;
<|endoftext|>


<commit_before>/*
	UIModal.js

	Copyright (c) 2014-2020 dangered wolf, et al
	Released under the MIT License
*/

export class UIModal {
	modalRoot = "#settings-modal";
	sharedRoot = false;

	constructor() {

	}

	display() {

		if (typeof $(this.modalRoot)[0] !== "undefined") {
			new TD.components.GlobalSettings;

			$(this.modalRoot + ">.mdl").remove();
			$(this.modalRoot).append(this.element);
		} else {
			$(".js-modals-container").append(
				make("div").addClass("ovl mtd-login-overlay").attr("style","display: block;").append(this.element).click(event => {
					if (event.currentTarget === event.target) {
						mtdPrepareWindows();
					}
				})
			);
		}
	}

	dismiss() {
		this.element.remove?.();
		if (!this.sharedRoot) {
			$(this.modalRoot).attr("style","display: none;")
		}
	}
}
<commit_msg>Fixed modals breaking in login screen mode<commit_after>/*
	UIModal.js

	Copyright (c) 2014-2020 dangered wolf, et al
	Released under the MIT License
*/

import { make } from "./Utils.js";

export class UIModal {
	modalRoot = "#settings-modal";
	sharedRoot = false;

	constructor() {

	}

	display() {

		console.log( $(this.modalRoot)[0])

		if (typeof $(this.modalRoot)[0] !== "undefined") {
			new TD.components.GlobalSettings;

			$(this.modalRoot + ">.mdl").remove();
			$(this.modalRoot).append(this.element);
		} else {
			mtdPrepareWindows();
			$(".js-modals-container").append(
				make("div").addClass("ovl mtd-login-overlay").attr("style","display: block;").append(this.element).click(event => {
					if (event.currentTarget === event.target) {
						mtdPrepareWindows();
					}
				})
			);
		}
	}

	dismiss() {
		this.element.remove?.();
		if (!this.sharedRoot) {
			$(this.modalRoot).attr("style","display: none;")
		}
	}
}
<|endoftext|>


<commit_before>const request = require('request');
const Constants = require('./Constants');
const Encode = require('./util/Encode');
const Video = require('./structures/Video');
const Playlist = require('./structures/Playlist');

class YouTube {
    constructor(key) {
        this.key = key;
        this.Constants = Constants;
    }

    request(endpoint, uriOptions) {
        return new Promise((resolve, reject) => {
            request(`https://www.googleapis.com/youtube/v3/${endpoint}?${Encode(uriOptions)}`, (err, resp, body) => {
                if (err) return reject(`An error occured: ${err}`);
                if (resp.statusCode !== 200) return reject(`Status Code ${resp.statusCode}\n${body}`);
                return resolve(JSON.parse(body));
            });
        });
    }

    videoById(videoId) {
        return new Promise((resolve, reject) => {
            this.request('videos', {'id': videoId, 'key': this.key, 'part': Constants.PARTS.VideoByID})
                .then(result => {
                    return resolve(result.items.map(item => {
                        return new Video(this, item);
                    }));
                })
                .catch(reject);
        });
    }

    playlistById(playlistId) {
        return new Promise((resolve, reject) => {
            this.request('playlists', {'id': playlistId, 'key': this.key, 'part': Constants.PARTS.Playlist})
                .then(result => {
                    return resolve(result.items.map(item => {
                        return new Playlist(this, item);
                    }));
                })
                .catch(reject);
        });
    }

    search(query, results = 5) {
        return new Promise((resolve, reject) => {
            this.request('search', {'q': query, 'maxResults': results, 'key': this.key, 'part': Constants.PARTS.Search})
                .then(result => {
                    const items = result.items;
                    return resolve(result.items.map(item => {
                        return new Video(this, item);
                    }));
                })
                .catch(reject);
        });
    }
}

module.exports = YouTube;

/*
    search(query, results = 5) {
        return new Promise((resolve, reject) => {
            sendRequest('search', {'q': query, 'maxResults': results, 'key': this.key, 'part': parts.search}).then(resolve).catch(reject);
        });
    }

    getPlaylistItems(playlistId) {
        return new Promise((resolve, reject) => {
            sendRequest('playlistItems', {'playlistId': playlistId, 'key': this.key, 'part': parts.playlistItems}).then(resolve).catch(reject);
        });
    }
*/
<commit_msg>Add JSDocs Syntax<commit_after>const request = require('request');
const Constants = require('./Constants');
const Encode = require('./util/Encode');
const Video = require('./structures/Video');
const Playlist = require('./structures/Playlist');

/**
 * The YouTube API module
 */

class YouTube {
    /**
     * Create the YouTube API caller
     * @param {String} key your youtube data api v3 key
     */
    constructor(key) {
        /**
         * Your YouTube Data API key
         * @type {?String}
         */
        this.key = key;
    }

    /**
     * Make a request to the YouTube API
     * @param {String} endpoint the endpoint of the api
     * @param {Object} uriOptions the uri options to send to the api
     * @returns {Promise<Object, Error>}
     */
    request(endpoint, uriOptions) {
        return new Promise((resolve, reject) => {
            request(`https://www.googleapis.com/youtube/v3/${endpoint}?${Encode(uriOptions)}`, (err, resp, body) => {
                if (err) return reject(`An error occured: ${err}`);
                if (resp.statusCode !== 200) return reject(`Status Code ${resp.statusCode}\n${body}`);
                return resolve(JSON.parse(body));
            });
        });
    }

    /**
     * Get a video by id
     * @param {String} videoId the video id
     * @returns {Promise<Array<Video>, Error>}
     * @example
     * Api.videoById('3odIdmuFfEY')
     *  .then(results => {
     *    console.log(`The videos' title is ${resolts[0].title}`);
     *  })
     *  .catch(console.log);
     */
    videoById(videoId) {
        return new Promise((resolve, reject) => {
            this.request('videos', {'id': videoId, 'key': this.key, 'part': Constants.PARTS.VideoByID})
                .then(result => {
                    return resolve(result.items.map(item => {
                        return new Video(this, item);
                    }));
                })
                .catch(reject);
        });
    }

    /**
     * Get a playlist by id
     * @param {String} playlistId the playlist id
     * @returns {Promise<Array<Playlist>, Error>}
     * @example
     * Api.playlistById('PL2BN1Zd8U_MsyMeK8r9Vdv1lnQGtoJaSa')
     *  .then(results => {
     *    console.log(`The playlists' title is ${resolts[0].title}`);
     *  })
     *  .catch(console.log);
     */
    playlistById(playlistId) {
        return new Promise((resolve, reject) => {
            this.request('playlists', {'id': playlistId, 'key': this.key, 'part': Constants.PARTS.Playlist})
                .then(result => {
                    return resolve(result.items.map(item => {
                        return new Playlist(this, item);
                    }));
                })
                .catch(reject);
        });
    }

    /**
     * Get a video by name
     * @param {String} query the query to search
     * @param {Number} [results = 5] the max amount of results
     * @returns {Promise<Array<Playlist>, Error>}
     * @example
     * Api.search('Centuries')
     *  .then(results => {
     *    console.log(`I got ${results.length} videos`);
     *  })
     *  .catch(console.log);
     */
    search(query, results = 5) {
        return new Promise((resolve, reject) => {
            this.request('search', {'q': query, 'maxResults': results, 'key': this.key, 'part': Constants.PARTS.Search})
                .then(result => {
                    const items = result.items;
                    return resolve(result.items.map(item => {
                        return new Video(this, item);
                    }));
                })
                .catch(reject);
        });
    }
}

module.exports = YouTube;

/*
    search(query, results = 5) {
        return new Promise((resolve, reject) => {
            sendRequest('search', {'q': query, 'maxResults': results, 'key': this.key, 'part': parts.search}).then(resolve).catch(reject);
        });
    }

    getPlaylistItems(playlistId) {
        return new Promise((resolve, reject) => {
            sendRequest('playlistItems', {'playlistId': playlistId, 'key': this.key, 'part': parts.playlistItems}).then(resolve).catch(reject);
        });
    }
*/
<|endoftext|>


<commit_before>/**
 * Module dependencies
 */

import React from 'react';
import uniqueId from 'lodash/uniqueId';
import isEqual from 'lodash/isEqual';
import youTubePlayer from 'youtube-player';

/**
 * Create a new `YouTube` component.
 */

class YouTube extends React.Component {
  static propTypes = {
    videoId: React.PropTypes.string.isRequired,

    // custom ID for player element
    id: React.PropTypes.string,

    // custom class name for player element
    className: React.PropTypes.string,

    // https://developers.google.com/youtube/iframe_api_reference#Loading_a_Video_Player
    opts: React.PropTypes.object,

    // event subscriptions
    onReady: React.PropTypes.func,
    onError: React.PropTypes.func,
    onPlay: React.PropTypes.func,
    onPause: React.PropTypes.func,
    onEnd: React.PropTypes.func,
    onStateChange: React.PropTypes.func,
  };

  static defaultProps = {
    opts: {},
    onReady: () => {},
    onError: () => {},
    onPlay: () => {},
    onPause: () => {},
    onEnd: () => {},
    onStateChange: () => {},
  };

  /**
   * @param {Object} props
   */

  constructor(props) {
    super(props);

    this._containerId = props.id || uniqueId('player_');
    this._internalPlayer = null;
  }

  componentDidMount() {
    this.createPlayer();
  }

  componentDidUpdate(prevProps) {
    const optsHaveChanged = !(isEqual(prevProps.opts, this.props.opts));
    const videoHasChanged = prevProps.videoId !== this.props.videoId;

    if (optsHaveChanged) {
      return this.resetPlayer();
    }

    if (videoHasChanged) {
      this.updateVideo();
    }
  }

  componentWillUnmount() {
    this.destroyPlayer();
  }

  /**
   * https://developers.google.com/youtube/iframe_api_reference#onReady
   *
   * @param {Object} event
   *   @param {Object} target - player object
   */

  onPlayerReady(event) {
    this.props.onReady(event);
  }

  /**
   * https://developers.google.com/youtube/iframe_api_reference#onError
   *
   * @param {Object} event
   *   @param {Integer} data  - error type
   *   @param {Object} target - player object
   */

  onPlayerError(event) {
    this.props.onError(event);
  }

  /**
   * https://developers.google.com/youtube/iframe_api_reference#onStateChange
   *
   * @param {Object} event
   *   @param {Integer} data  - status change type
   *   @param {Object} target - actual YT player
   */

  onPlayerStateChange(event) {
    this.props.onStateChange(event);
    switch (event.data) {

    case window.YT.PlayerState.ENDED:
      this.props.onEnd(event);
      break;

    case window.YT.PlayerState.PLAYING:
      this.props.onPlay(event);
      break;

    case window.YT.PlayerState.PAUSED:
      this.props.onPause(event);
      break;

    default:
      return;
    }
  }

  createPlayer() {
    // do not attempt to create a player server-side, it won't work
    if (typeof document === 'undefined') return;
    // create player
    this._internalPlayer = youTubePlayer(this._containerId, { ...this.props.opts });
    // attach event handlers
    this._internalPlayer.on('ready', ::this.onPlayerReady);
    this._internalPlayer.on('error', ::this.onPlayerError);
    this._internalPlayer.on('stateChange', ::this.onPlayerStateChange);
    // update video
    this.updateVideo();
  }

  destroyPlayer() {
    return this._internalPlayer.destroy();
  }

  resetPlayer() {
    this.destroyPlayer().then(::this.createPlayer);
  }

  updateVideo() {
    // set queueing options
    let autoplay = false;
    const opts = {
      videoId: this.props.videoId,
    };
    if ('playerVars' in this.props.opts) {
      autoplay = this.props.opts.playerVars.autoplay === 1;
      if ('start' in this.props.opts.playerVars) {
        opts.startSeconds = this.props.opts.playerVars.start;
      }
      if ('end' in this.props.opts.playerVars) {
        opts.endSeconds = this.props.opts.playerVars.end;
      }
    }

    // if autoplay is enabled loadVideoById
    if (autoplay) {
      this._internalPlayer.loadVideoById(opts);
      return;
    }
    // default behaviour just cues the video
    this._internalPlayer.cueVideoById(opts);
  }

  /**
   * @returns Object
   */

  render() {
    return (

    );
  }
}

/**
 * Expose `YouTube`
 */

export default YouTube;
<commit_msg>Do not reset player when playerVars.{start,end} change<commit_after>/**
 * Module dependencies
 */

import React from 'react';
import uniqueId from 'lodash/uniqueId';
import isEqual from 'lodash/isEqual';
import youTubePlayer from 'youtube-player';

/**
 * Check whether a `props` change should result in the video being updated.
 *
 * @param {Object} prevProps
 * @param {Object} props
 */

function shouldUpdateVideo(prevProps, props) {
  // A changing video should always trigger an update
  if (prevProps.videoId !== props.videoId) {
    return true;
  }

  // Otherwise, a change in the start/end time playerVars also requires a player
  // update.
  const prevVars = prevProps.opts.playerVars || {};
  const vars = props.opts.playerVars || {};

  return prevVars.start !== vars.start || prevVars.end !== vars.end;
}

/**
 * Neutralise API options that only require a video update, leaving only options
 * that require a player reset. The results can then be compared to see if a
 * player reset is necessary.
 *
 * @param {Object} opts
 */

function filterResetOptions(opts) {
  return {
    ...opts,
    playerVars: {
      ...opts.playerVars,
      start: 0,
      end: 0
    }
  };
}

/**
 * Check whether a `props` change should result in the player being reset.
 * The player is reset when the `props.opts` change, except if the only change
 * is in the `start` and `end` playerVars, because a video update can deal with
 * those.
 *
 * @param {Object} prevProps
 * @param {Object} props
 */

function shouldResetPlayer(prevProps, props) {
  return !isEqual(
    filterResetOptions(prevProps.opts),
    filterResetOptions(props.opts)
  );
}

/**
 * Create a new `YouTube` component.
 */

class YouTube extends React.Component {
  static propTypes = {
    videoId: React.PropTypes.string.isRequired,

    // custom ID for player element
    id: React.PropTypes.string,

    // custom class name for player element
    className: React.PropTypes.string,

    // https://developers.google.com/youtube/iframe_api_reference#Loading_a_Video_Player
    opts: React.PropTypes.object,

    // event subscriptions
    onReady: React.PropTypes.func,
    onError: React.PropTypes.func,
    onPlay: React.PropTypes.func,
    onPause: React.PropTypes.func,
    onEnd: React.PropTypes.func,
    onStateChange: React.PropTypes.func,
  };

  static defaultProps = {
    opts: {},
    onReady: () => {},
    onError: () => {},
    onPlay: () => {},
    onPause: () => {},
    onEnd: () => {},
    onStateChange: () => {},
  };

  /**
   * @param {Object} props
   */

  constructor(props) {
    super(props);

    this._containerId = props.id || uniqueId('player_');
    this._internalPlayer = null;
  }

  componentDidMount() {
    this.createPlayer();
  }

  componentDidUpdate(prevProps) {
    if (shouldResetPlayer(prevProps, this.props)) {
      return this.resetPlayer();
    }

    if (shouldUpdateVideo(prevProps, this.props)) {
      this.updateVideo();
    }
  }

  componentWillUnmount() {
    this.destroyPlayer();
  }

  /**
   * https://developers.google.com/youtube/iframe_api_reference#onReady
   *
   * @param {Object} event
   *   @param {Object} target - player object
   */

  onPlayerReady(event) {
    this.props.onReady(event);
  }

  /**
   * https://developers.google.com/youtube/iframe_api_reference#onError
   *
   * @param {Object} event
   *   @param {Integer} data  - error type
   *   @param {Object} target - player object
   */

  onPlayerError(event) {
    this.props.onError(event);
  }

  /**
   * https://developers.google.com/youtube/iframe_api_reference#onStateChange
   *
   * @param {Object} event
   *   @param {Integer} data  - status change type
   *   @param {Object} target - actual YT player
   */

  onPlayerStateChange(event) {
    this.props.onStateChange(event);
    switch (event.data) {

    case window.YT.PlayerState.ENDED:
      this.props.onEnd(event);
      break;

    case window.YT.PlayerState.PLAYING:
      this.props.onPlay(event);
      break;

    case window.YT.PlayerState.PAUSED:
      this.props.onPause(event);
      break;

    default:
      return;
    }
  }

  createPlayer() {
    // do not attempt to create a player server-side, it won't work
    if (typeof document === 'undefined') return;
    // create player
    this._internalPlayer = youTubePlayer(this._containerId, { ...this.props.opts });
    // attach event handlers
    this._internalPlayer.on('ready', ::this.onPlayerReady);
    this._internalPlayer.on('error', ::this.onPlayerError);
    this._internalPlayer.on('stateChange', ::this.onPlayerStateChange);
    // update video
    this.updateVideo();
  }

  destroyPlayer() {
    return this._internalPlayer.destroy();
  }

  resetPlayer() {
    this.destroyPlayer().then(::this.createPlayer);
  }

  updateVideo() {
    // set queueing options
    let autoplay = false;
    const opts = {
      videoId: this.props.videoId,
    };
    if ('playerVars' in this.props.opts) {
      autoplay = this.props.opts.playerVars.autoplay === 1;
      if ('start' in this.props.opts.playerVars) {
        opts.startSeconds = this.props.opts.playerVars.start;
      }
      if ('end' in this.props.opts.playerVars) {
        opts.endSeconds = this.props.opts.playerVars.end;
      }
    }

    // if autoplay is enabled loadVideoById
    if (autoplay) {
      this._internalPlayer.loadVideoById(opts);
      return;
    }
    // default behaviour just cues the video
    this._internalPlayer.cueVideoById(opts);
  }

  /**
   * @returns Object
   */

  render() {
    return (

    );
  }
}

/**
 * Expose `YouTube`
 */

export default YouTube;
<|endoftext|>


<commit_before>$(function () {
	var replayName = getGET("replay");

	if(replayName != null && replayName != undefined) {
		var data = textFromURL(replayName, function(data) {
			console.log(data)
			if(data != null) {
				showGame(data, true);
			}
		});
	} else {
		var $dropZone = $("

Drop a replay file here!

");
		$("#pageContent").append($dropZone);

		$dropZone.on('dragover', function(e) {
			e.stopPropagation();
			e.preventDefault();
		});
		$dropZone.on('drop', function(e) {
			e.stopPropagation();
			e.preventDefault();
			var files = e.originalEvent.dataTransfer.files; // Array of all files
			for(var i=0, file; file=files[i]; i++) {
				console.log(file)
				var reader = new FileReader();

				reader.onload = function(e2) { // finished reading file data.
					$dropZone.remove();
					showGame(textToGame(e2.target.result, file.name), true);
				};
				reader.readAsText(file); // start reading the file data.
			}
		});
	}
})
<commit_msg>Bugfix regarding showGame<commit_after>$(function () {
	var replayName = getGET("replay");

	if(replayName != null && replayName != undefined) {
		var data = textFromURL(replayName, function(data) {
			console.log(data)
			if(data != null) {
				showGame(data, replayName);
			}
		});
	} else {
		var $dropZone = $("

Drop a replay file here!

");
		$("#pageContent").append($dropZone);

		$dropZone.on('dragover', function(e) {
			e.stopPropagation();
			e.preventDefault();
		});
		$dropZone.on('drop', function(e) {
			e.stopPropagation();
			e.preventDefault();
			var files = e.originalEvent.dataTransfer.files; // Array of all files
			for(var i=0, file; file=files[i]; i++) {
				console.log(file)
				var reader = new FileReader();

				reader.onload = function(e2) { // finished reading file data.
					$dropZone.remove();
					showGame(textToGame(e2.target.result, file.name), true);
				};
				reader.readAsText(file); // start reading the file data.
			}
		});
	}
})
<|endoftext|>


<commit_before>})(FIRE || (FIRE = {}));
<commit_msg>support CMD<commit_after>})(FIRE || (FIRE = {}));

if (typeof module !== 'undefined') {
    module.exports = FIRE;
}<|endoftext|>


<commit_before>'use strict';

var account = function (params) {
  var balance = 0 || params.balance;
  var interest = {};
  interest.debit = 0 || params.debit;
  interest.credit = 0 || params.credit;
  var operations = [];
  var tickAccount = function (divider) {
    if (balance >= 0) {
      var diff = (balance * interest.credit) / divider;
    } else {
      var diff = -(balance * interest.debit) / divider;
    }
    balance += diff;
  };

  var self = {
    operation: function (p) {
      if (!p || !p.ammount) {
        return false;
      }
      balance += p.ammount;
      operations.push(p);
      return true;
    },
    balance: function () {
      return balance;
    },
    interest: function () {
      return interest;
    },
    tick: function (period) {
      tickAccount(period);
    },
    operations: function () {
      return operations;
    }
  };
  return self;
}

module.exports = account;
<commit_msg>update comments<commit_after>'use strict';

// account function

var account = function (params) {
  var balance = 0 || params.balance;
  var interest = {};
  interest.debit = 0 || params.debit;
  interest.credit = 0 || params.credit;
  var operations = [];
  var tickAccount = function (divider) {
    if (balance >= 0) {
      var diff = (balance * interest.credit) / divider;
    } else {
      var diff = -(balance * interest.debit) / divider;
    }
    balance += diff;
  };

  var self = {
    operation: function (p) {
      if (!p || !p.ammount) {
        return false;
      }
      balance += p.ammount;
      operations.push(p);
      return true;
    },
    balance: function () {
      return balance;
    },
    interest: function () {
      return interest;
    },
    tick: function (period) {
      tickAccount(period);
    },
    operations: function () {
      return operations;
    }
  };
  return self;
}

module.exports = account;
<|endoftext|>


<commit_before>(function($, $$) {

Mavo.attributes.push("mv-action");

var _ = Mavo.Actions = {
	listener: evt => {
		var element = evt.target.closest("[mv-action]");

		if (element) {
			_.run(element.getAttribute("mv-action"), element);
		}
	},

	run: (code, element) => {
		if (code) {
			var node = Mavo.Node.getClosest(element);

			if (node) {
				var expression = new Mavo.Expression(code);
				return expression.eval(node.getLiveData(), "Mavo.Actions.Functions");
			}
		}
	},

	getNodes: ref => {
		var node = _.getNode(ref);

		if (node) {
			return [node];
		}

		return Mavo.toArray(ref).map(n => _.getNode(n)).filter(n => n !== undefined);
	},

	getNode: node => {
		if (node instanceof Mavo.Node) {
			return node;
		}
		else if (node && node[Mavo.toNode]) {
			return node[Mavo.toNode];
		}
	},

	Functions: {
		add: (ref, data, index) => {
			if (!ref) {
				return;
			}

			var nodes = _.getNodes(ref);

			return nodes.map(node => {
				var collection = node.closestCollection;

				if (!collection) {
					return;
				}

				if (index === undefined && !(node instanceof Mavo.Collection)) {
					// If there is no index, get index from collection item
					index = node.closestItem.index;
				}

				var item = collection.add(undefined, index);

				if (data !== undefined) {
					item.render(data);
				}

				return item.getLiveData();
			}).filter(n => n !== undefined);
		},
		clear: (...ref) => {
			if (!ref.length || !ref[0]) {
				return;
			}

			var nodes = _.getNodes(Mavo.flatten(ref));
			var itemsToDelete = [];

			nodes.forEach(node => {
				if (!node) {
					return;
				}

				if (node instanceof Mavo.Collection) {
					// Clear collection
					itemsToDelete.push(...node.children);
				}
				else if (node.collection) {
					// Collection item, delete
					itemsToDelete.push(node);
				}
				else {
					// Ordinary node, just clear its data
					node.walk(n => {
						if (n instanceof Mavo.Primitive) {
							n.value = null;
						}
						else if (n !== node) {
							_.clear(n);
						}
					});
				}
			});

			Mavo.Collection.delete(itemsToDelete);

			return nodes;
		},

		/**
		 * Set node(s) to value(s)
		 * If ref is a single node, set it to values
		 * If ref is multiple nodes, set it to corresponding value
		 * If ref is multiple nodes and values is not an array, set all nodes to values
		 */
		set: (ref, values) => {
			if (!ref) {
				return;
			}

			var wasArray = Array.isArray(ref);
			var nodes = _.getNodes(ref);

			return Mavo.Script.binaryOperation(wasArray? nodes : nodes[0], values, {
				scalar: (node, value) => node.render(value)
			});
		}
	}
};

})(Bliss, Bliss.$);
<commit_msg>[actions] Make new item editable, if collection is being edited<commit_after>(function($, $$) {

Mavo.attributes.push("mv-action");

var _ = Mavo.Actions = {
	listener: evt => {
		var element = evt.target.closest("[mv-action]");

		if (element) {
			_.run(element.getAttribute("mv-action"), element);
		}
	},

	run: (code, element) => {
		if (code) {
			var node = Mavo.Node.getClosest(element);

			if (node) {
				var expression = new Mavo.Expression(code);
				return expression.eval(node.getLiveData(), "Mavo.Actions.Functions");
			}
		}
	},

	getNodes: ref => {
		var node = _.getNode(ref);

		if (node) {
			return [node];
		}

		return Mavo.toArray(ref).map(n => _.getNode(n)).filter(n => n !== undefined);
	},

	getNode: node => {
		if (node instanceof Mavo.Node) {
			return node;
		}
		else if (node && node[Mavo.toNode]) {
			return node[Mavo.toNode];
		}
	},

	Functions: {
		add: (ref, data, index) => {
			if (!ref) {
				return;
			}

			var nodes = _.getNodes(ref);

			return nodes.map(node => {
				var collection = node.closestCollection;

				if (!collection) {
					return;
				}

				if (index === undefined && !(node instanceof Mavo.Collection)) {
					// If there is no index, get index from collection item
					index = node.closestItem.index;
				}

				var item = collection.add(undefined, index);

				if (data !== undefined) {
					item.render(data);
				}

				if (collection.editing) {
					collection.editItem(item);
				}

				return item.getLiveData();
			}).filter(n => n !== undefined);
		},
		clear: (...ref) => {
			if (!ref.length || !ref[0]) {
				return;
			}

			var nodes = _.getNodes(Mavo.flatten(ref));
			var itemsToDelete = [];

			nodes.forEach(node => {
				if (!node) {
					return;
				}

				if (node instanceof Mavo.Collection) {
					// Clear collection
					itemsToDelete.push(...node.children);
				}
				else if (node.collection) {
					// Collection item, delete
					itemsToDelete.push(node);
				}
				else {
					// Ordinary node, just clear its data
					node.walk(n => {
						if (n instanceof Mavo.Primitive) {
							n.value = null;
						}
						else if (n !== node) {
							_.clear(n);
						}
					});
				}
			});

			Mavo.Collection.delete(itemsToDelete);

			return nodes;
		},

		/**
		 * Set node(s) to value(s)
		 * If ref is a single node, set it to values
		 * If ref is multiple nodes, set it to corresponding value
		 * If ref is multiple nodes and values is not an array, set all nodes to values
		 */
		set: (ref, values) => {
			if (!ref) {
				return;
			}

			var wasArray = Array.isArray(ref);
			var nodes = _.getNodes(ref);

			return Mavo.Script.binaryOperation(wasArray? nodes : nodes[0], values, {
				scalar: (node, value) => node.render(value)
			});
		}
	}
};

})(Bliss, Bliss.$);
<|endoftext|>


<commit_before>import { networkApis } from './generateNetworkApi';

const NAMESPACE = 'web3-redux';

export const actions = {
  XHR: `${NAMESPACE} xhr update`,
  NETWORK_SET_WEB3: `${NAMESPACE} network set web3`,
  NETWORK_REMOVED: `${NAMESPACE} network removed`,
  WEB3_METHOD_SUCCESS: `${NAMESPACE} web3 method success`,
  TRANSACTION_UPDATED: `${NAMESPACE} transaction updated`,
  CONTRACT_METHOD_SUCCESS: `${NAMESPACE} contract method success`,
  CONTRACT_TRANSACTION_CREATED: `${NAMESPACE} contract transaction created`,
};

function removeWeb3(networkId) {
  if (networkApis[networkId]) {
    if (networkApis[networkId].web3) {
      networkApis[networkId].web3.reset();
    }
    delete networkApis[networkId];
  }
}

export function setNetwork({ networkId, web3, getDefaultAddress }) {
  removeWeb3(networkId);
  networkApis[networkId] = { web3, getDefaultAddress };
  return { type: actions.NETWORK_SET_WEB3, networkId, payload: { enabled: !!web3, connecting: !!web3 } };
}

export function updateNetwork({ networkId, payload }) {
  return { type: actions.NETWORK_SET_WEB3, networkId, payload };
}

export function removeNetwork({ networkId }) {
  removeWeb3(networkId);
  return { type: actions.NETWORK_REMOVED, networkId };
}

export function decorateTransactionArgs({ args = [], networkId }) {
  const { getDefaultAddress, web3 } = networkApis[networkId];
  // if getter isn't set, do nothign
  if (!getDefaultAddress) {
    return args;
  }
  // if the last argument already sets `from`, do nothing
  const lastArg = args[args.length - 1] || {};
  if (lastArg.from) {
    return args;
  }
  // if the default address isn't gettable
  const from = getDefaultAddress();
  if (!from) {
    return args;
  }
  // if the last argument isn't an object (or is a big number), concat the `from`
  if (typeof lastArg !== 'object' || !web3.utils.isBigNumber(lastArg)) {
    return args.concat([{ from }]);
  }
  // otherwise, merge `from` into the last arg
  return args.slice(0, -1).concat([{ ...lastArg, from }]);
}

function callMethod({ method, args, networkId, transaction }, callback) {
  const decoratedArgs = transaction ? decorateTransactionArgs({ args, networkId }) : args;
  return (dispatch) => {
    dispatch({ type: actions.XHR, networkId, count: 1 });
    return new Promise((resolve, reject) => {
      try {
        method(...decoratedArgs, (err, value) => {
          if (err) {
            dispatch({ type: actions.XHR, networkId, count: -1 });
            return reject(err);
          }
          dispatch({ type: actions.XHR, networkId, count: -1 });
          callback({ dispatch, value });
          return resolve(value);
        });
      } catch (err) {
        dispatch({ type: actions.XHR, networkId, count: -1 });
        reject(err);
      }
    });
  };
}

export function web3Method({ method, networkId, args, key }) {
  return callMethod({ method, args, networkId }, ({ dispatch, value }) => {
    dispatch({ type: actions.WEB3_METHOD_SUCCESS, networkId, key, payload: { value, updated: new Date() } });
  });
}

export function getTransaction({ args, method, networkId }) {
  return callMethod({ method, args, networkId }, ({ dispatch, value }) => {
    dispatch({ type: actions.TRANSACTION_UPDATED, networkId, key: args[0], payload: { value, updated: new Date() } });
  });
}

export function createTransaction({ args, method, networkId }) {
  return callMethod({ method, args, networkId, transaction: true }, ({ dispatch, value }) => {
    dispatch({ type: actions.TRANSACTION_UPDATED, networkId, key: value, payload: { created: new Date() } });
  });
}

export function callContractMethod({ networkId, key, args, address, method }) {
  return callMethod({ method, args, networkId }, ({ dispatch, value }) => {
    dispatch({ type: actions.CONTRACT_METHOD_SUCCESS, address, networkId, key, payload: { value, updated: new Date() } });
  });
}
export function createContractTransaction({ networkId, args, address, method }) {
  return callMethod({ method, args, networkId, transaction: true }, ({ dispatch, value }) => {
    dispatch({ type: actions.TRANSACTION_UPDATED, networkId, key: value, payload: { created: new Date() } });
    dispatch({ type: actions.CONTRACT_TRANSACTION_CREATED, address, networkId, payload: { value } }); // relational
  });
}
<commit_msg>[bugfix] manually check for bigNumber<commit_after>import { networkApis } from './generateNetworkApi';

const NAMESPACE = 'web3-redux';

export const actions = {
  XHR: `${NAMESPACE} xhr update`,
  NETWORK_SET_WEB3: `${NAMESPACE} network set web3`,
  NETWORK_REMOVED: `${NAMESPACE} network removed`,
  WEB3_METHOD_SUCCESS: `${NAMESPACE} web3 method success`,
  TRANSACTION_UPDATED: `${NAMESPACE} transaction updated`,
  CONTRACT_METHOD_SUCCESS: `${NAMESPACE} contract method success`,
  CONTRACT_TRANSACTION_CREATED: `${NAMESPACE} contract transaction created`,
};

function removeWeb3(networkId) {
  if (networkApis[networkId]) {
    if (networkApis[networkId].web3) {
      networkApis[networkId].web3.reset();
    }
    delete networkApis[networkId];
  }
}

export function setNetwork({ networkId, web3, getDefaultAddress }) {
  removeWeb3(networkId);
  networkApis[networkId] = { web3, getDefaultAddress };
  return { type: actions.NETWORK_SET_WEB3, networkId, payload: { enabled: !!web3, connecting: !!web3 } };
}

export function updateNetwork({ networkId, payload }) {
  return { type: actions.NETWORK_SET_WEB3, networkId, payload };
}

export function removeNetwork({ networkId }) {
  removeWeb3(networkId);
  return { type: actions.NETWORK_REMOVED, networkId };
}

export function decorateTransactionArgs({ args = [], networkId }) {
  const { getDefaultAddress } = networkApis[networkId];
  // if getter isn't set, do nothign
  if (!getDefaultAddress) {
    return args;
  }
  // if the last argument already sets `from`, do nothing
  const lastArg = args[args.length - 1] || {};
  if (lastArg.from) {
    return args;
  }
  // if the default address isn't gettable
  const from = getDefaultAddress();
  if (!from) {
    return args;
  }
  // if the last argument isn't an object (or is a big number), concat the `from`
  if (typeof lastArg !== 'object' || lastArg.constructor && lastArg.constructor.name === 'BigNumber') {
    return args.concat([{ from }]);
  }
  // otherwise, merge `from` into the last arg
  return args.slice(0, -1).concat([{ ...lastArg, from }]);
}

function callMethod({ method, args, networkId, transaction }, callback) {
  const decoratedArgs = transaction ? decorateTransactionArgs({ args, networkId }) : args;
  return (dispatch) => {
    dispatch({ type: actions.XHR, networkId, count: 1 });
    return new Promise((resolve, reject) => {
      try {
        method(...decoratedArgs, (err, value) => {
          if (err) {
            dispatch({ type: actions.XHR, networkId, count: -1 });
            return reject(err);
          }
          dispatch({ type: actions.XHR, networkId, count: -1 });
          callback({ dispatch, value });
          return resolve(value);
        });
      } catch (err) {
        dispatch({ type: actions.XHR, networkId, count: -1 });
        reject(err);
      }
    });
  };
}

export function web3Method({ method, networkId, args, key }) {
  return callMethod({ method, args, networkId }, ({ dispatch, value }) => {
    dispatch({ type: actions.WEB3_METHOD_SUCCESS, networkId, key, payload: { value, updated: new Date() } });
  });
}

export function getTransaction({ args, method, networkId }) {
  return callMethod({ method, args, networkId }, ({ dispatch, value }) => {
    dispatch({ type: actions.TRANSACTION_UPDATED, networkId, key: args[0], payload: { value, updated: new Date() } });
  });
}

export function createTransaction({ args, method, networkId }) {
  return callMethod({ method, args, networkId, transaction: true }, ({ dispatch, value }) => {
    dispatch({ type: actions.TRANSACTION_UPDATED, networkId, key: value, payload: { created: new Date() } });
  });
}

export function callContractMethod({ networkId, key, args, address, method }) {
  return callMethod({ method, args, networkId }, ({ dispatch, value }) => {
    dispatch({ type: actions.CONTRACT_METHOD_SUCCESS, address, networkId, key, payload: { value, updated: new Date() } });
  });
}
export function createContractTransaction({ networkId, args, address, method }) {
  return callMethod({ method, args, networkId, transaction: true }, ({ dispatch, value }) => {
    dispatch({ type: actions.TRANSACTION_UPDATED, networkId, key: value, payload: { created: new Date() } });
    dispatch({ type: actions.CONTRACT_TRANSACTION_CREATED, address, networkId, payload: { value } }); // relational
  });
}
<|endoftext|>


<commit_before>/**
 * # BoxSelector
 * Copyright(c) 2019 Stefano Balietti
 * MIT Licensed
 *
 * Creates a simple box that opens a menu of items to choose from
 *
 * www.nodegame.org
 */
(function(node) {

    "use strict";

    var NDDB =  node.NDDB;

    node.widgets.register('BoxSelector', BoxSelector);

    // ## Meta-data

    BoxSelector.version = '1.0.0';
    BoxSelector.description = 'Creates a simple box that opens a menu ' +
        'of items to choose from.';

    BoxSelector.panel = false;
    BoxSelector.title = false;
    BoxSelector.className = 'boxselector';

    // ## Dependencies

    BoxSelector.dependencies = {
        JSUS: {}
    };

    /**
     * ## BoxSelector constructor
     *
     * `BoxSelector` is a simple configurable chat
     *
     * @see BoxSelector.init
     */
    function BoxSelector() {

        /**
         * ### BoxSelector.button
         *
         * The button that if pressed shows the items
         *
         * @see BoxSelector.ul
         */
        this.button = null;

        /**
         * ### BoxSelector.buttonText
         *
         * The text on the button
         *
         * @see BoxSelector.button
         */
        this.buttonText = '';

        /**
         * ### BoxSelector.items
         *
         * List of items to choose from
         */
        this.items = [];

        /**
         * ### BoxSelector.clickCb
         *
         * A callback to call when an item from the list is clicked
         *
         * Optional. If not specified, items won't be clickable.
         *
         * @see BoxSelector.items
         */
        this.clickCb = null;

        /**
         * ### BoxSelector.getText
         *
         * A callback that renders an element into a text
         */
        this.getText = null;

        /**
         * ### BoxSelector.getId
         *
         * A callback that returns the id of an item
         *
         * Default: returns item.id.
         */
        this.getId = function(item) { return item.id; };

        /**
         * ### BoxSelector.ul
         *
         * The HTML UL element displaying the list of items
         *
         * @see BoxSelector.items
         */
        this.ul = null;
    }

    // ## BoxSelector methods

    /**
     * ### BoxSelector.init
     *
     * Initializes the widget
     *
     * @param {object} options Configuration options.
     */
    BoxSelector.prototype.init = function(options) {
        if (options.clickCb) {
            if ('function' !== typeof options.clickCb) {
                throw new Error('BoxSelector.init: options.getId must be ' +
                                'function or undefined. Found: ' +
                                options.getId);
            }
            this.clickCb = options.clickCb;
        }

        if ('function' !== typeof options.getText) {
            throw new Error('BoxSelector.init: options.getText must be ' +
                            'function. Found: ' + options.getText);
        }
        this.getText = options.getText;

        if (options.getId && 'function' !== typeof options.getId) {
            throw new Error('BoxSelector.init: options.getId must be ' +
                            'function or undefined. Found: ' + options.getId);
        }
        this.getId = options.getId;

    };

    BoxSelector.prototype.append = function() {
        var that, ul, btn, btnGroup, toggled;

        btnGroup = W.add('div', this.bodyDiv);
        btnGroup.role = 'group';
        btnGroup['aria-label'] = 'Select Items';
        btnGroup.className = 'btn-group dropup';

        // Here we create the Button holding the treatment.
        btn = this.button = W.add('button', btnGroup);
        btn.className = 'btn btn-default btn dropdown-toggle';
        btn['data-toggle'] = 'dropdown';
        btn['aria-haspopup'] = 'true';
        btn['aria-expanded'] = 'false';
        btn.innerHTML = this.buttonText + ' ';

        W.add('span', btn, { className: 'caret' });

        // Here the create the UL of treatments.
        // It will be populated later.
        ul = this.ul = W.add('ul', btnGroup);
        ul.className = 'dropdown-menu';
        ul.style.display = 'none';

        // Variable toggled controls if the dropdown menu
        // is displayed (we are not using bootstrap js files)
        // and we redo the job manually here.
        toggled = false;
        btn.onclick = function() {
            if (toggled) {
                ul.style.display = 'none';
                toggled = false;
            }
            else {
                ul.style.display = 'block';
                toggled = true;
            }
        };

        if (this.clickCb) {
            that = this;
            ul.onclick = function(eventData) {
                var id, i, len;
                id = eventData.target;
                // When '' is hidden by bootstrap class.
                ul.style.display = '';
                toggled = false;
                id = id.parentNode.id;
                // Clicked on description?
                if (!id) id = eventData.target.parentNode.parentNode.id;
                // Nothing relevant clicked (e.g., header).
                if (!id) return;
                len = that.items.length;
                // Call the clickCb.
                for ( i = 0 ; i < len ; i++) {
                    if (that.getId(that.items[i]) === id) {
                        that.clickCb(that.items[i], id);
                        break;
                    }
                }
            };
        }
    };

    BoxSelector.prototype.addItem = function(item) {
        var ul, li, a, tmp;
        ul = this.ul;
        li = document.createElement('li');
        // Text.
        tmp = this.getText(item);
        if (!tmp || 'string' !== typeof tmp) {
            throw new Error('BoxSelector.addItem: getText did not return a ' +
                            'string. Found: ' + tmp + '. Item: ' + item);
        }
        if (this.clickCb) {
            a = document.createElement('a');
            a.href = '#';
            a.innerHTML = tmp;
            li.appendChild(a);
        }
        else {
            li.innerHTML = tmp;
        }
        // Id.
        tmp = this.getId(item);
        if (!tmp || 'string' !== typeof tmp) {
            throw new Error('BoxSelector.addItem: getId did not return a ' +
                            'string. Found: ' + tmp + '. Item: ' + item);
        }
        li.id = tmp;
        li.className = 'dropdown-header';
        ul.appendChild(li);
        this.items.push(item);
    };

    BoxSelector.prototype.getValues = function() {
        return this.items;
    };

    // ## Helper functions.

})(node);
<commit_msg>boxselector removeItem<commit_after>/**
 * # BoxSelector
 * Copyright(c) 2019 Stefano Balietti
 * MIT Licensed
 *
 * Creates a simple box that opens a menu of items to choose from
 *
 * www.nodegame.org
 */
(function(node) {

    "use strict";

    var NDDB =  node.NDDB;

    node.widgets.register('BoxSelector', BoxSelector);

    // ## Meta-data

    BoxSelector.version = '1.0.0';
    BoxSelector.description = 'Creates a simple box that opens a menu ' +
        'of items to choose from.';

    BoxSelector.panel = false;
    BoxSelector.title = false;
    BoxSelector.className = 'boxselector';

    // ## Dependencies

    BoxSelector.dependencies = {
        JSUS: {}
    };

    /**
     * ## BoxSelector constructor
     *
     * `BoxSelector` is a simple configurable chat
     *
     * @see BoxSelector.init
     */
    function BoxSelector() {

        /**
         * ### BoxSelector.button
         *
         * The button that if pressed shows the items
         *
         * @see BoxSelector.ul
         */
        this.button = null;

        /**
         * ### BoxSelector.buttonText
         *
         * The text on the button
         *
         * @see BoxSelector.button
         */
        this.buttonText = '';

        /**
         * ### BoxSelector.items
         *
         * List of items to choose from
         */
        this.items = [];

        /**
         * ### BoxSelector.onclick
         *
         * A callback to call when an item from the list is clicked
         *
         * Callback is executed with the BoxSelector instance as context.
         *
         * Optional. If not specified, items won't be clickable.
         *
         * @see BoxSelector.items
         */
        this.onclick = null;

        /**
         * ### BoxSelector.getText
         *
         * A callback that renders an element into a text
         */
        this.getText = null;

        /**
         * ### BoxSelector.getId
         *
         * A callback that returns the id of an item
         *
         * Default: returns item.id.
         */
        this.getId = function(item) { return item.id; };

        /**
         * ### BoxSelector.ul
         *
         * The HTML UL element displaying the list of items
         *
         * @see BoxSelector.items
         */
        this.ul = null;
    }

    // ## BoxSelector methods

    /**
     * ### BoxSelector.init
     *
     * Initializes the widget
     *
     * @param {object} options Configuration options.
     */
    BoxSelector.prototype.init = function(options) {
        if (options.onclick) {
            if ('function' !== typeof options.onclick) {
                throw new Error('BoxSelector.init: options.getId must be ' +
                                'function or undefined. Found: ' +
                                options.getId);
            }
            this.onclick = options.onclick;
        }

        if ('function' !== typeof options.getText) {
            throw new Error('BoxSelector.init: options.getText must be ' +
                            'function. Found: ' + options.getText);
        }
        this.getText = options.getText;

        if (options.getId && 'function' !== typeof options.getId) {
            throw new Error('BoxSelector.init: options.getId must be ' +
                            'function or undefined. Found: ' + options.getId);
        }
        this.getId = options.getId;

    };

    BoxSelector.prototype.append = function() {
        var that, ul, btn, btnGroup, toggled;

        btnGroup = W.add('div', this.bodyDiv);
        btnGroup.role = 'group';
        btnGroup['aria-label'] = 'Select Items';
        btnGroup.className = 'btn-group dropup';

        // Here we create the Button holding the treatment.
        btn = this.button = W.add('button', btnGroup);
        btn.className = 'btn btn-default btn dropdown-toggle';
        btn['data-toggle'] = 'dropdown';
        btn['aria-haspopup'] = 'true';
        btn['aria-expanded'] = 'false';
        btn.innerHTML = this.buttonText + ' ';

        W.add('span', btn, { className: 'caret' });

        // Here the create the UL of treatments.
        // It will be populated later.
        ul = this.ul = W.add('ul', btnGroup);
        ul.className = 'dropdown-menu';
        ul.style.display = 'none';

        // Variable toggled controls if the dropdown menu
        // is displayed (we are not using bootstrap js files)
        // and we redo the job manually here.
        toggled = false;
        btn.onclick = function() {
            if (toggled) {
                ul.style.display = 'none';
                toggled = false;
            }
            else {
                ul.style.display = 'block';
                toggled = true;
            }
        };

        if (this.onclick) {
            that = this;
            ul.onclick = function(eventData) {
                var id, i, len;
                id = eventData.target;
                // When '' is hidden by bootstrap class.
                ul.style.display = '';
                toggled = false;
                id = id.parentNode.id;
                // Clicked on description?
                if (!id) id = eventData.target.parentNode.parentNode.id;
                // Nothing relevant clicked (e.g., header).
                if (!id) return;
                len = that.items.length;
                // Call the onclick.
                for ( i = 0 ; i < len ; i++) {
                    if (that.getId(that.items[i]) === id) {
                        that.onclick.call(that, that.items[i], id);
                        break;
                    }
                }
            };
        }
    };

    BoxSelector.prototype.addItem = function(item) {
        var ul, li, a, tmp;
        ul = this.ul;
        li = document.createElement('li');
        // Text.
        tmp = this.getText(item);
        if (!tmp || 'string' !== typeof tmp) {
            throw new Error('BoxSelector.addItem: getText did not return a ' +
                            'string. Found: ' + tmp + '. Item: ' + item);
        }
        if (this.onclick) {
            a = document.createElement('a');
            a.href = '#';
            a.innerHTML = tmp;
            li.appendChild(a);
        }
        else {
            li.innerHTML = tmp;
        }
        // Id.
        tmp = this.getId(item);
        if (!tmp || 'string' !== typeof tmp) {
            throw new Error('BoxSelector.addItem: getId did not return a ' +
                            'string. Found: ' + tmp + '. Item: ' + item);
        }
        li.id = tmp;
        li.className = 'dropdown-header';
        ul.appendChild(li);
        this.items.push(item);
    };

    BoxSelector.prototype.removeItem = function(id) {
        var i, len, elem;
        len = this.items.length;
        for ( i = 0 ; i < len ; i++) {
            if (this.getId(this.items[i]) === id) {
                elem = W.gid(id);
                this.ul.removeChild(elem);
                return this.items.splice(i, 1);
            }
        }
        return false;
    };

    BoxSelector.prototype.getValues = function() {
        return this.items;
    };

    // ## Helper functions.

})(node);
<|endoftext|>


<commit_before>/**
 * autoSuggest
 *
 * @version 0.6.8 2013-01-14
 * @author Gregor Kofler
 *
 * @param {Object} elem input element
 * @param {Object} xhr request object containing command and URI
 * @param {Object} config additional parameters to configure dropdown
 *	maxEntries:			{Number} max entries in list
 *	keyElem:			{Object} optional input element for storing key values
 *	keyProp:			{String} property name, which identifies the property stored as key value
 *	searchMode:			{Boolean} switches from suggest to search mode
 *	restrict:			{Boolean} restrict to provided entries when true (suggest mode only)
 *	minLength:			{Number} minimum length of search string, which triggers a request (search mode only)
 *	customShow:			{Function} callback function applying fx, when element is shown
 *	customHide:			{Function} callback function applying fx, when element is hidden
 *	enterIsCancelled:	{Boolean} when true, and no list shown, the default action of the enter key will be prevented
 *
 * served events: "choose", "showWidget", "hideWidget", "submitNoMatch"
 */

vxJS.widget.autoSuggest = function(elem, xhrReq, config) {

	config = config || {};

	var	typeAheadTimeout = 250, timeoutId,
		keyProp = config.keyProp || "key", keyElem = config.keyElem, enableTypeAhead, keyListened, sentString, chosen, that = {}, shown,
		searchMode = !!config.searchMode,
		initData = {
			text: elem.value,
			key: keyElem ? keyElem.value : null
		},
		list = vxJS.widget.shared.list({hoverSelect: !searchMode }),
		layer = function() {
			var l = "div".setProp("class", "vxJS_autoSuggest").create(list.element);
			l.style.display = "none";
			return l;
		}(),
		generateEntriesCallback,
		xhr = vxJS.xhr(xhrReq || {}, { limit: config.maxEntries || 10, text: "" }),
		xhrImg = function() {
			var i = "div".setProp("class", "vxJS_xhrThrobber").create();
			i.style.position = "absolute";
			vxJS.dom.setElementPosition(i,  { x: -100, y: -100 } );
			vxJS.dom.getBody().appendChild(i);
			return i;
		}(), xhrImgSize;

	var setValue = function(v) {
		elem.value = v.text;
		if(keyElem) {
			keyElem.value = v[keyProp];
		}
	};

	var placeLayer = function() {
		var ePos = vxJS.dom.getElementOffset(elem), eSize = vxJS.dom.getElementSize(elem),
			scroll = vxJS.dom.getDocumentScroll(), size, s = layer.style, y;

		if(shown) {
			size = vxJS.dom.getElementSize(layer);
		}
		else {
			s.visibility = "hidden";
			s.display = "";
			size = vxJS.dom.getElementSize(layer);
			s.display = "none";
			s.visibility = "visible";
		}

		if((ePos.y + eSize.y + size.y > vxJS.dom.getViewportSize().y + scroll.y) && (ePos.y - size.y > scroll.y)) {
			y = ePos.y - size.y;
		}
		else {
			y = ePos.y + eSize.y;
		}
		layer.style.width = eSize.x+"px";
		vxJS.dom.setElementPosition(layer, new Coord(ePos.x, y));
	};

	var show = function() {
		placeLayer();

		if(!shown) {
			if(typeof config.customShow == "function") {
				config.customShow.apply(that);
			}
			else {
				layer.style.display = "";
			}
			shown = true;
			vxJS.event.serve(that, "showWidget");
		}
	};

	var hide = function() {
		if(shown) {
			if(typeof config.customHide == "function") {
				config.customHide.apply(that);
			}
			else {
				layer.style.display = "none";
			}
			shown = false;
			vxJS.event.serve(that, "hideWidget");
		}
	};

	var handleXhrResponse = function() {
		var txt, r = this.response, v = elem.value.toUpperCase(), i;

		if(sentString !== v || !r || !r.entries || !r.entries.length) {
			list.fill();
			hide();
			return;
		}

		if(searchMode) {
			list.fill(r.entries);
			if(vxJS.widget.shared.hiLite) {
				if(!r.hiLite || r.hiLite == "string") {
					vxJS.widget.shared.hiLite(r.hiLite || sentString, list.element);
				}
				else {
					while(i = r.hiLite.shift()) {
						vxJS.widget.shared.hiLite(i, list.element);
					}
				}
			}
			show();
			return;
		}

		if(config.restrict) {
			txt = r.entries[0].text.toUpperCase();
			while(v.length && txt.indexOf(v) != 0) {
				v = v.slice(0, -1);
			}
			sentString = v;
		}

		if (enableTypeAhead) {
			setValue(r.entries[0]);
			vxJS.selection.set(elem, sentString.length);
		}

		list.fill(r.entries);
		show();
	};

	var initRequest = function() {
		var p, s, v = elem.value, response;

		if(sentString === v.toUpperCase()) {
			return;
		}

		if(!v || (searchMode && v.length < (config.minLength || 3))) {
			hide();
			return;
		}

		sentString = v.toUpperCase();

		// if provided retrieve matching suggestions not from server, but by custom callback

		if(generateEntriesCallback) {
			handleXhrResponse.call({
				response: generateEntriesCallback( {
					text: v,
					limit: config.maxEntries || 10
				} )
			});
		}

		// else retrieve data by XHR

		else {
			if(!xhrImgSize) {
				xhrImgSize = vxJS.dom.getElementSize(xhrImg);
			}
			p = vxJS.dom.getElementOffset(elem);
			s = vxJS.dom.getElementSize(elem);
			p.x += s.x-xhrImgSize.x-4;
			p.y += (s.y-xhrImgSize.y)/2;
			vxJS.dom.setElementPosition(xhrImg, p);

			xhr.use(null, { text: v }, { node: xhrImg });
			xhr.submit();
		}
	};

	var handleChoose = function() {
		chosen = list.getSelected()[0];
		setValue(chosen);
		initData = { text: elem.value, key: keyElem ? keyElem.value : null };

		if(!searchMode) {
			vxJS.selection.setCaretPosition(elem, "end");
		}

		vxJS.event.serve(that, "choose");
		sentString = null;
		hide();
	};

	var handleKeyDown = function(e) {
		var kc = e.keyCode;

		keyListened = true;

		if(kc < 32 && kc != 13 && kc != 27 && kc != 8 && kc != 0) {
			return;
		}

		switch (kc) {
			case 38:
				list.up();
				break;

			case 40:
				list.down();
				break;

			case 27:
				if(!searchMode) {
					setValue(initData);
				}
				sentString = null;
				hide();
				break;

			case 13:
				if(shown) {
					handleChoose();
					vxJS.event.preventDefault(e);
				}
				else {
					vxJS.event.serve(that, "submitNoMatch");
					if(config.enterIsCancelled) {
						vxJS.event.preventDefault(e);
					}
				}
				break;

			default:
				keyListened = false;
		}
	};

	var handleKeyUp = function(e) {
		var kc = e.keyCode;

		if(elem.value.toUpperCase() != sentString) {
			sentString = null;
		}

		if (keyListened || (kc < 32 && kc != 8 && kc != 0) || (kc >= 33 && kc < 46) || (kc >= 112 && kc <= 123)) {
			return;
		}
		enableTypeAhead = !(kc == 8 || kc == 46);	// BS & DEL - Suggestions without Typeahead

		window.clearTimeout(timeoutId);
		timeoutId = window.setTimeout(initRequest, typeAheadTimeout);
	};

	elem.setAttribute("autocomplete", "off");
	vxJS.dom.getBody().appendChild(layer);

	vxJS.event.addListener(elem, "keydown",	handleKeyDown);
	vxJS.event.addListener(elem, "keyup",	handleKeyUp);
	vxJS.event.addListener(elem, "blur",	hide);

	vxJS.event.addListener(list, "choose",	handleChoose);

	vxJS.event.addListener(xhr, "complete",	handleXhrResponse);
	vxJS.event.addListener(xhr, "timeout", function() { window.alert("Response took to long!");});

	that.element = layer;
	that.xhr = xhr;

	that.setGenerateEntriesCallback	= function(cb) { generateEntriesCallback = cb; };
	that.getChosen					= function() { return chosen; };

	return that;
};<commit_msg>Fix issue when clicking scrollbar in IE and Chrome.<commit_after>/**
 * autoSuggest
 *
 * @version 0.6.8 2013-02-23
 * @author Gregor Kofler
 *
 * @param {Object} elem input element
 * @param {Object} xhr request object containing command and URI
 * @param {Object} config additional parameters to configure dropdown
 *	maxEntries:			{Number} max entries in list
 *	keyElem:			{Object} optional input element for storing key values
 *	keyProp:			{String} property name, which identifies the property stored as key value
 *	searchMode:			{Boolean} switches from suggest to search mode
 *	restrict:			{Boolean} restrict to provided entries when true (suggest mode only)
 *	minLength:			{Number} minimum length of search string, which triggers a request (search mode only)
 *	customShow:			{Function} callback function applying fx, when element is shown
 *	customHide:			{Function} callback function applying fx, when element is hidden
 *	enterIsCancelled:	{Boolean} when true, and no list shown, the default action of the enter key will be prevented
 *
 * served events: "choose", "showWidget", "hideWidget", "submitNoMatch"
 */

vxJS.widget.autoSuggest = function(elem, xhrReq, config) {

	config = config || {};

	var	typeAheadTimeout = 250, timeoutId,
		keyProp = config.keyProp || "key", keyElem = config.keyElem, enableTypeAhead, keyListened, sentString, chosen, that = {}, shown,
		searchMode = !!config.searchMode,
		initData = {
			text: elem.value,
			key: keyElem ? keyElem.value : null
		},
		list = vxJS.widget.shared.list({hoverSelect: !searchMode }),
		layer = function() {
			var l = "div".setProp("class", "vxJS_autoSuggest").create(list.element);
			l.style.display = "none";
			return l;
		}(),
		generateEntriesCallback, mousedownOnList,
		xhr = vxJS.xhr(xhrReq || {}, { limit: config.maxEntries || 10, text: "" }),
		xhrImg = function() {
			var i = "div".setProp("class", "vxJS_xhrThrobber").create();
			i.style.position = "absolute";
			vxJS.dom.setElementPosition(i,  { x: -100, y: -100 } );
			vxJS.dom.getBody().appendChild(i);
			return i;
		}(), xhrImgSize;

	var setValue = function(v) {
		elem.value = v.text;
		if(keyElem) {
			keyElem.value = v[keyProp];
		}
	};

	var placeLayer = function() {
		var ePos = vxJS.dom.getElementOffset(elem), eSize = vxJS.dom.getElementSize(elem),
			scroll = vxJS.dom.getDocumentScroll(), size, s = layer.style, y;

		if(shown) {
			size = vxJS.dom.getElementSize(layer);
		}
		else {
			s.visibility = "hidden";
			s.display = "";
			size = vxJS.dom.getElementSize(layer);
			s.display = "none";
			s.visibility = "visible";
		}

		if((ePos.y + eSize.y + size.y > vxJS.dom.getViewportSize().y + scroll.y) && (ePos.y - size.y > scroll.y)) {
			y = ePos.y - size.y;
		}
		else {
			y = ePos.y + eSize.y;
		}
		layer.style.width = eSize.x+"px";
		vxJS.dom.setElementPosition(layer, new Coord(ePos.x, y));
	};

	var show = function() {
		placeLayer();

		if(!shown) {
			if(typeof config.customShow == "function") {
				config.customShow.apply(that);
			}
			else {
				layer.style.display = "";
			}
			shown = true;
			vxJS.event.serve(that, "showWidget");
		}
	};

	var hide = function() {
		if(shown) {
			if(typeof config.customHide == "function") {
				config.customHide.apply(that);
			}
			else {
				layer.style.display = "none";
			}
			shown = false;
			vxJS.event.serve(that, "hideWidget");
		}
	};

	var handleXhrResponse = function() {
		var txt, r = this.response, v = elem.value.toUpperCase(), i;

		if(sentString !== v || !r || !r.entries || !r.entries.length) {
			list.fill();
			hide();
			return;
		}

		if(searchMode) {
			list.fill(r.entries);
			if(vxJS.widget.shared.hiLite) {
				if(!r.hiLite || r.hiLite == "string") {
					vxJS.widget.shared.hiLite(r.hiLite || sentString, list.element);
				}
				else {
					while(i = r.hiLite.shift()) {
						vxJS.widget.shared.hiLite(i, list.element);
					}
				}
			}
			show();
			return;
		}

		if(config.restrict) {
			txt = r.entries[0].text.toUpperCase();
			while(v.length && txt.indexOf(v) != 0) {
				v = v.slice(0, -1);
			}
			sentString = v;
		}

		if (enableTypeAhead) {
			setValue(r.entries[0]);
			vxJS.selection.set(elem, sentString.length);
		}

		list.fill(r.entries);
		show();
	};

	var initRequest = function() {
		var p, s, v = elem.value, response;

		if(sentString === v.toUpperCase()) {
			return;
		}

		if(!v || (searchMode && v.length < (config.minLength || 3))) {
			hide();
			return;
		}

		sentString = v.toUpperCase();

		// if provided retrieve matching suggestions not from server, but by custom callback

		if(generateEntriesCallback) {
			handleXhrResponse.call({
				response: generateEntriesCallback( {
					text: v,
					limit: config.maxEntries || 10
				} )
			});
		}

		// else retrieve data by XHR

		else {
			if(!xhrImgSize) {
				xhrImgSize = vxJS.dom.getElementSize(xhrImg);
			}
			p = vxJS.dom.getElementOffset(elem);
			s = vxJS.dom.getElementSize(elem);
			p.x += s.x-xhrImgSize.x-4;
			p.y += (s.y-xhrImgSize.y)/2;
			vxJS.dom.setElementPosition(xhrImg, p);

			xhr.use(null, { text: v }, { node: xhrImg });
			xhr.submit();
		}
	};

	var handleChoose = function() {
		chosen = list.getSelected()[0];
		setValue(chosen);
		initData = { text: elem.value, key: keyElem ? keyElem.value : null };

		if(!searchMode) {
			vxJS.selection.setCaretPosition(elem, "end");
		}

		vxJS.event.serve(that, "choose");
		sentString = null;
		hide();
	};

	var handleKeyDown = function(e) {
		var kc = e.keyCode;

		keyListened = true;

		if(kc < 32 && kc != 13 && kc != 27 && kc != 8 && kc != 0) {
			return;
		}

		switch (kc) {
			case 38:
				list.up();
				break;

			case 40:
				list.down();
				break;

			case 27:
				if(!searchMode) {
					setValue(initData);
				}
				sentString = null;
				hide();
				break;

			case 13:
				if(shown) {
					handleChoose();
					vxJS.event.preventDefault(e);
				}
				else {
					vxJS.event.serve(that, "submitNoMatch");
					if(config.enterIsCancelled) {
						vxJS.event.preventDefault(e);
					}
				}
				break;

			default:
				keyListened = false;
		}
	};

	var handleKeyUp = function(e) {
		var kc = e.keyCode;

		if(elem.value.toUpperCase() != sentString) {
			sentString = null;
		}

		if (keyListened || (kc < 32 && kc != 8 && kc != 0) || (kc >= 33 && kc < 46) || (kc >= 112 && kc <= 123)) {
			return;
		}
		enableTypeAhead = !(kc == 8 || kc == 46);	// BS & DEL - Suggestions without Typeahead

		window.clearTimeout(timeoutId);
		timeoutId = window.setTimeout(initRequest, typeAheadTimeout);
	};

	elem.setAttribute("autocomplete", "off");
	vxJS.dom.getBody().appendChild(layer);

	vxJS.event.addListener(elem,	"keydown",		handleKeyDown);
	vxJS.event.addListener(elem,	"keyup",		handleKeyUp);

	// workaround required for IE and Chrome, which lose focus, when scrollbar of list is clicked

	vxJS.event.addListener(layer,	"mousedown", 	function() { mousedownOnList = true; });
	vxJS.event.addListener(layer,	"mouseup", 		function() { mousedownOnList = false; });
	vxJS.event.addListener(elem,	"blur",			function() {
														if(!mousedownOnList) {
															hide();
														}
														else {
															elem.focus();
															mousedownOnList = false;
														}
													});

	vxJS.event.addListener(list,	"choose",		handleChoose);

	vxJS.event.addListener(xhr,		"complete",		handleXhrResponse);
	vxJS.event.addListener(xhr,		"timeout",		function() { window.alert("Response took to long!");});

	that.element = layer;
	that.xhr = xhr;

	that.setGenerateEntriesCallback	= function(cb) { generateEntriesCallback = cb; };
	that.getChosen					= function() { return chosen; };

	return that;
};<|endoftext|>


<commit_before>var _ = require('../../src/utils');

window.matchMedia = window.matchMedia || window.webkitMatchMedia || window.mozMatchMedia || window.msMatchMedia;

var modal = document.querySelector('.modal'),
    isMobile = window.matchMedia('( max-width: 767px )');

function closeModal (resolved, value) {
  modal.className = 'modal is-closing';

  parent.window.postMessage({
    aplazame: 'modal',
    event: 'closing'
  }, '*');

  parent.window.postMessage({
    aplazame: 'modal',
    event: 'resolved',
    value: value
  }, '*');

  setTimeout(function () {
    parent.window.postMessage({
      aplazame: 'modal',
      event: 'close'
    }, '*');
  }, isMobile.matches ? 0 : 600 );
}

_.listen( modal.querySelector('.card'), 'click', function (e) {
  e.stopPropagation();
});

_.listen(document.body, 'click', function () {
  closeModal(false);
});

[].forEach.call( document.querySelectorAll('[modal-resolve]'), function (element) {
  _.listen( element, 'click', function (e) {
    closeModal(true, element.getAttribute('modal-resolve') );
  });
});

[].forEach.call( document.querySelectorAll('[modal-reject]'), function (element) {
  _.listen( element, 'click', function (e) {
    e.stopPropagation();
    closeModal(false, element.getAttribute('modal-reject') );
  });
});
<commit_msg>skipping update widget when modal rejected<commit_after>var _ = require('../../src/utils');

window.matchMedia = window.matchMedia || window.webkitMatchMedia || window.mozMatchMedia || window.msMatchMedia;

var modal = document.querySelector('.modal'),
    isMobile = window.matchMedia('( max-width: 767px )');

function closeModal (resolved, value) {
  modal.className = 'modal is-closing';

  parent.window.postMessage({
    aplazame: 'modal',
    event: 'closing'
  }, '*');

  if( resolved ) {
    parent.window.postMessage({
      aplazame: 'modal',
      event: 'resolved',
      value: value
    }, '*');
  }

  setTimeout(function () {
    parent.window.postMessage({
      aplazame: 'modal',
      event: 'close'
    }, '*');
  }, isMobile.matches ? 0 : 600 );
}

_.listen( modal.querySelector('.card'), 'click', function (e) {
  e.stopPropagation();
});

_.listen(document.body, 'click', function () {
  closeModal(false);
});

[].forEach.call( document.querySelectorAll('[modal-resolve]'), function (element) {
  _.listen( element, 'click', function (e) {
    closeModal(true, element.getAttribute('modal-resolve') );
  });
});

[].forEach.call( document.querySelectorAll('[modal-reject]'), function (element) {
  _.listen( element, 'click', function (e) {
    e.stopPropagation();
    closeModal(false, element.getAttribute('modal-reject') );
  });
});
<|endoftext|>


<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Here will be stored slave functions related to components
 * @type {Object}
 */

var App = require('app');
module.exports = {
  /**
   * Format and load info about components to StackServiceComponent model.
   *
   * @method loadStackServiceComponentModel
   * @param data {object} response from server
   * @return {object} formatted info about components
   */
  loadStackServiceComponentModel: function(data) {
    var serviceComponents = {items: []};
    data.items.forEach(function(item){
      item.serviceComponents.forEach(function(_serviceComponent){
        var stackServiceComponents =  _serviceComponent.StackServiceComponents;
        var serviceComponent = {
          component_name: stackServiceComponents.component_name,
          service_name: stackServiceComponents.service_name,
          component_category: stackServiceComponents.component_category,
          is_master: stackServiceComponents.is_master,
          is_client: stackServiceComponents.is_client,
          stack_name: stackServiceComponents.stack_name,
          stack_version: stackServiceComponents.stack_version
        };
        serviceComponents.items.pushObject(serviceComponent);
      },this);
    },this);
    App.stackServiceComponentMapper.map(serviceComponents);
    App.handleStackDependedComponents();
    return serviceComponents;
  }
};
<commit_msg>AMBARI-6169. Installer wizard: ambari web-client issues invalid requests after switching stacks. (jaimin)<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Here will be stored slave functions related to components
 * @type {Object}
 */

var App = require('app');
module.exports = {

  /**
   * This needs to be done because mapper functions like App.stackServiceComponentMapper.map(data) does not override
   * but unions the instances. So on re-navigation if the stack is switched and this function is not called then union of
   * StackServiceComponent of both the stacks will be mapped to the model.
   */
  clearStackModel: function() {
    if (App.StackServiceComponent.find().get('content').length) {
      App.StackServiceComponent.find().set('content', []);
    }
  },

  /**
   * Format and load info about components to StackServiceComponent model.
   *
   * @method loadStackServiceComponentModel
   * @param data {object} response from server
   * @return {object} formatted info about components
   */
  loadStackServiceComponentModel: function(data) {
    this.clearStackModel();
    var serviceComponents = {items: []};
    data.items.forEach(function(item){
      item.serviceComponents.forEach(function(_serviceComponent){
        var stackServiceComponents =  _serviceComponent.StackServiceComponents;
        var serviceComponent = {
          component_name: stackServiceComponents.component_name,
          service_name: stackServiceComponents.service_name,
          component_category: stackServiceComponents.component_category,
          is_master: stackServiceComponents.is_master,
          is_client: stackServiceComponents.is_client,
          stack_name: stackServiceComponents.stack_name,
          stack_version: stackServiceComponents.stack_version
        };
        serviceComponents.items.pushObject(serviceComponent);
      }, this);
    }, this);
    App.stackServiceComponentMapper.map(serviceComponents);
    App.handleStackDependedComponents();
    return serviceComponents;
  }
};
<|endoftext|>


<commit_before>const http = require('http');
const path = require('path');
const express = require('express');
const socketio = require('socket.io');
const parseArgs = require('minimist');
const fs = require('fs');

const app = express();
const server = http.createServer(app);
const io = socketio(server);

const args = parseArgs(process.argv.slice(2));
const { name = 'default', port = '8080'} = args;

app.use(express.static(path.join(__dirname, 'public')));

app.get('/api/test', (req, res) => {
  res.json({
    headers: req.headers,
    address: req.connection.remoteAddress
  });
});

app.get('/api/name', (req, res) => {
  res.json({ name });
});

app.get('/api/file', (req, res) => {
  fs.readFile(`${__dirname}/version.txt`, 'utf8', (err, version) => {
    res.json({
      version,
      dirname: __dirname,
      cwd: process.cwd()
    });
  });
});

io.on('connection', (sock) => {
  console.log('Client connected');

  sock.on('heartbeat', (payload) => {
    payload.nodeName = name;
    sock.emit('heartbeat', payload);
  });

  sock.on('disconnect', () => {
    console.log('Socket Disconnected');
  });
});

server.listen(+port, '0.0.0.0', (err) => {
  if (err) {
    console.log(err.stack);
    return;
  }

  console.log(`Node [${name}] listens on http://127.0.0.1:${port}.`);
});
<commit_msg>Changed /file API to /info, added default version 0, if version.txt is not found<commit_after>const http = require('http');
const path = require('path');
const express = require('express');
const socketio = require('socket.io');
const parseArgs = require('minimist');
const fs = require('fs');

const app = express();
const server = http.createServer(app);
const io = socketio(server);

const args = parseArgs(process.argv.slice(2));
const { name = 'default', port = '8080'} = args;

app.use(express.static(path.join(__dirname, 'public')));

app.get('/api/test', (req, res) => {
  res.json({
    headers: req.headers,
    address: req.connection.remoteAddress
  });
});

app.get('/api/name', (req, res) => {
  res.json({ name });
});

app.get('/api/info', (req, res) => {
  fs.readFile(`${__dirname}/version.txt`, 'utf8', (err, version) => {
    res.json({
      version: version || 0,
      dirname: __dirname,
      cwd: process.cwd()
    });
  });
});

io.on('connection', (sock) => {
  console.log('Client connected');

  sock.on('heartbeat', (payload) => {
    payload.nodeName = name;
    sock.emit('heartbeat', payload);
  });

  sock.on('disconnect', () => {
    console.log('Socket Disconnected');
  });
});

server.listen(+port, '0.0.0.0', (err) => {
  if (err) {
    console.log(err.stack);
    return;
  }

  console.log(`Node [${name}] listens on http://127.0.0.1:${port}.`);
});
<|endoftext|>


<commit_before>var $soloModal = null // Used when allowMultiple = false.

// The public API.
Modal = {

	allowMultiple: false,

	show: function(templateName, data){

		if($soloModal == null || this.allowMultiple){

			var parentNode = document.body

			var view = Blaze.renderWithData(Template[templateName], data, parentNode)

			var domRange = view._domrange // TODO: Don't violate against the public API.

			var $modal = domRange.$('.modal')

			$modal.on('shown.bs.modal', function(event){
				$modal.find('[autofocus]').focus()
			})

			$modal.on('hidden.bs.modal', function(event){
				Blaze.remove(view)
				$soloModal = null
			})

			$soloModal = $modal

			$modal.modal()

		}

	},

	hide: function(/* optional */ template){

		if(template instanceof Blaze.TemplateInstance){

			template.$('.modal').modal('hide')

		}else if($soloModal != null){

			$soloModal.modal('hide')

		}

	}

}<commit_msg>Allow an `options` to be passed when initializing modal<commit_after>var $soloModal = null // Used when allowMultiple = false.

// The public API.
Modal = {

	allowMultiple: false,

	show: function(templateName, data, options){

		if($soloModal == null || this.allowMultiple){

			var parentNode = document.body

			var view = Blaze.renderWithData(Template[templateName], data, parentNode)

			var domRange = view._domrange // TODO: Don't violate against the public API.

			var $modal = domRange.$('.modal')

			$modal.on('shown.bs.modal', function(event){
				$modal.find('[autofocus]').focus()
			})

			$modal.on('hidden.bs.modal', function(event){
				Blaze.remove(view)
				$soloModal = null
			})

			$soloModal = $modal

			$modal.modal(options)

		}

	},

	hide: function(/* optional */ template){

		if(template instanceof Blaze.TemplateInstance){

			template.$('.modal').modal('hide')

		}else if($soloModal != null){

			$soloModal.modal('hide')

		}

	}

}
<|endoftext|>


<commit_before>/**
 Work with World Cap API and Apps script to get interesting insights

 Author: Ido Green
 Date: 19-June-2014

 Improvements:
 1. Integration with BigQuery to give more stats on match vs different worlds cap.
 2. Gain more data (e.g. bets, weather and http://fivethirtyeight.com/) to try and find better prediction.

Thanks to: http://softwareforgood.com/soccer-good/ for their API!
*/

//
// A Menu to work with this service
//
function onOpen() {
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var entries = [{name : "Fetch Today's Scores", functionName : "fetchScoresToday"},
                 {name : "Fetch All Games", functionName : "fetchAll"}
                ];
  spreadsheet.addMenu("World Cap 2014", entries);
};

//
function fetchAll() {
  var url = "http://worldcup.sfg.io/matches";
  fetchScores("ALL", url);
}

//
function fetchScoresToday() {
  var url = "http://worldcup.sfg.io/matches/today";
  fetchScores("Today", url);
}

//
// Fetch the scores and push them to the sheet
//
function fetchScores(sheetname, url) {
  var response = UrlFetchApp.fetch(url);
  var rawData = JSON.parse(response.getContentText());
  var data = new Array();
  for (i in rawData){
   var curObj = new Object();

   curObj.match_number = rawData[i].match_number;
   curObj.location = rawData[i].location;

   var tmpDate = rawData[i].datetime;
   tmpDate = tmpDate.replace("\.000", "");
   //Logger.log("date: " + tmpDate);
   curObj.date = (tmpDate);
   curObj.status = rawData[i].status;
   curObj.winner = rawData[i].winner;
   curObj.match_number = rawData[i].match_number;
   curObj.match_number = rawData[i].match_number;

   curObj.htcountry = rawData[i].home_team.country;
   curObj.htcode = rawData[i].home_team.code;
   curObj.htgoals = rawData[i].home_team.goals;

   curObj.atcountry = rawData[i].home_team.country;
   curObj.atcode = rawData[i].home_team.code;
   curObj.atgoals = rawData[i].home_team.goals;
    data.push(curObj);
  }

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var allSheet = ss.getSheetByName(sheetname);
  ss.toast("Yep! We are now inserting "+data.length+" rows into " + sheetname);
  setRowsData(allSheet, data);
}

// ======================================================================================
// setRowsData fills in one row of data per object defined in the objects Array.
// For every Column, it checks if data objects define a value for it.
// Arguments:
//   - sheet: the Sheet Object where the data will be written
//   - objects: an Array of Objects, each of which contains data for a row
//   - optHeadersRange: a Range of cells where the column headers are defined. This
//     defaults to the entire first row in sheet.
//   - optFirstDataRowIndex: index of the first row where data should be written. This
//     defaults to the row immediately below the headers.
function setRowsData(sheet, objects, optHeadersRange, optFirstDataRowIndex) {
  var headersRange = optHeadersRange || sheet.getRange(1, 1, 1, sheet.getMaxColumns());
  var firstDataRowIndex = optFirstDataRowIndex || headersRange.getRowIndex() + 1;
  var headers = normalizeHeaders(headersRange.getValues()[0]);

  var data = [];
  for (var i = 0; i < objects.length; ++i) {
    var values = []
    for (j = 0; j < headers.length; ++j) {
      var header = headers[j];
      values.push(header.length > 0 && objects[i][header] ? objects[i][header] : "");
    }
    data.push(values);
  }
  var colInx = headersRange.getColumnIndex();
  var destinationRange = sheet.getRange(firstDataRowIndex, colInx, objects.length, headers.length);
  destinationRange.setValues(data);
}

// getRowsData iterates row by row in the input range and returns an array of objects.
// Each object contains all the data for a given row, indexed by its normalized column name.
// Arguments:
//   - sheet: the sheet object that contains the data to be processed
//   - range: the exact range of cells where the data is stored
//   - columnHeadersRowIndex: specifies the row number where the column names are stored.
//       This argument is optional and it defaults to the row immediately above range;
// Returns an Array of objects.
function getRowsData(sheet, range, columnHeadersRowIndex) {
  columnHeadersRowIndex = columnHeadersRowIndex || range.getRowIndex() - 1;
  var numColumns = range.getEndColumn() - range.getColumn() + 1;
  var headersRange = sheet.getRange(columnHeadersRowIndex, range.getColumn(), 1, numColumns);
  var headers = headersRange.getValues()[0];
  return getObjects(range.getValues(), normalizeHeaders(headers));
}

// For every row of data in data, generates an object that contains the data. Names of
// object fields are defined in keys.
// Arguments:
//   - data: JavaScript 2d array
//   - keys: Array of Strings that define the property names for the objects to create
function getObjects(data, keys) {
  var objects = [];
  for (var i = 0; i < data.length; ++i) {
    var object = {};
    var hasData = false;
    for (var j = 0; j < data[i].length; ++j) {
      var cellData = data[i][j];
      if (isCellEmpty(cellData)) {
        continue;
      }
      object[keys[j]] = cellData;
      hasData = true;
    }
    if (hasData) {
      objects.push(object);
    }
  }
  return objects;
}

// Returns an Array of normalized Strings.
// Arguments:
//   - headers: Array of Strings to normalize
function normalizeHeaders(headers) {
  var keys = [];
  for (var i = 0; i < headers.length; ++i) {
    var key = normalizeHeader(headers[i]);
    if (key.length > 0) {
      keys.push(key);
    }
  }
  return keys;
}

// Normalizes a string, by removing all alphanumeric characters and using mixed case
// to separate words. The output will always start with a lower case letter.
// This function is designed to produce JavaScript object property names.
// Arguments:
//   - header: string to normalize
// Examples:
//   "First Name" -> "firstName"
//   "Market Cap (millions) -> "marketCapMillions
//   "1 number at the beginning is ignored" -> "numberAtTheBeginningIsIgnored"
function normalizeHeader(header) {
  var key = "";
  var upperCase = false;
  for (var i = 0; i < header.length; ++i) {
    var letter = header[i];
    if (letter == " " && key.length > 0) {
      upperCase = true;
      continue;
    }
    //if (!isAlnum(letter)) {
    //  continue;
    //}
    if (key.length == 0 && isDigit(letter)) {
      continue; // first character must be a letter
    }
    if (upperCase) {
      upperCase = false;
      key += letter.toUpperCase();
    } else {
      key += letter.toLowerCase();
    }
  }
  return key;
}

// Returns true if the cell where cellData was read from is empty.
// Arguments:
//   - cellData: string
function isCellEmpty(cellData) {
  return typeof(cellData) == "string" && cellData == "";
}

// Returns true if the character char is alphabetical, false otherwise.
function isAlnum(char) {
  return char >= 'A' && char <= 'Z' ||
    char >= 'a' && char <= 'z' ||
    isDigit(char);
}

// Returns true if the character char is a digit, false otherwise.
function isDigit(char) {
  return char >= '0' && char <= '9';
}
// http://jsfromhell.com/array/chunk
function chunk(a, s){
    for(var x, i = 0, c = -1, l = a.length, n = []; i < l; i++)
        (x = i % s) ? n[c][x] = a[i] : n[++c] = [a[i]];
    return n;
}<commit_msg>fixing matches: away team<commit_after>/**
 Work with World Cap API and Apps script to get interesting insights

 Author: Ido Green
 Date: 19-June-2014

 Improvements:
 1. Integration with BigQuery to give more stats on match vs different worlds cap.
 2. Gain more data (e.g. bets, weather and http://fivethirtyeight.com/) to try and find better prediction.

Thanks to: http://softwareforgood.com/soccer-good/ for their API!
*/

//
// A Menu to work with this service
//
function onOpen() {
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var entries = [{name : "Fetch Today's Scores", functionName : "fetchScoresToday"},
                 {name : "Fetch All Games", functionName : "fetchAll"}
                ];
  spreadsheet.addMenu("World Cap 2014", entries);
};

//
function fetchAll() {
  var url = "http://worldcup.sfg.io/matches";
  fetchScores("ALL", url);
}

//
function fetchScoresToday() {
  var url = "http://worldcup.sfg.io/matches/today";
  fetchScores("Today", url);
}

//
// Fetch the scores and push them to the sheet
//
function fetchScores(sheetname, url) {
  var response = UrlFetchApp.fetch(url);
  var rawData = JSON.parse(response.getContentText());
  var data = new Array();
  for (i in rawData){
   var curObj = new Object();

   curObj.match_number = rawData[i].match_number;
   curObj.location = rawData[i].location;

   var tmpDate = rawData[i].datetime;
   tmpDate = tmpDate.replace("\.000", "");
   //Logger.log("date: " + tmpDate);
   curObj.date = (tmpDate);
   curObj.status = rawData[i].status;
   curObj.winner = rawData[i].winner;

   curObj.htcountry = rawData[i].home_team.country;
   curObj.htcode = rawData[i].home_team.code;
   curObj.htgoals = rawData[i].home_team.goals;

   curObj.atcountry = rawData[i].away_team.country;
   curObj.atcode = rawData[i].away_team.code;
   curObj.atgoals = rawData[i].away_team.goals;
   data.push(curObj);
  }

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var allSheet = ss.getSheetByName(sheetname);
  ss.toast("Yep! We are now inserting "+data.length+" rows into " + sheetname);
  setRowsData(allSheet, data);
}

// ======================================================================================
// setRowsData fills in one row of data per object defined in the objects Array.
// For every Column, it checks if data objects define a value for it.
// Arguments:
//   - sheet: the Sheet Object where the data will be written
//   - objects: an Array of Objects, each of which contains data for a row
//   - optHeadersRange: a Range of cells where the column headers are defined. This
//     defaults to the entire first row in sheet.
//   - optFirstDataRowIndex: index of the first row where data should be written. This
//     defaults to the row immediately below the headers.
function setRowsData(sheet, objects, optHeadersRange, optFirstDataRowIndex) {
  var headersRange = optHeadersRange || sheet.getRange(1, 1, 1, sheet.getMaxColumns());
  var firstDataRowIndex = optFirstDataRowIndex || headersRange.getRowIndex() + 1;
  var headers = normalizeHeaders(headersRange.getValues()[0]);

  var data = [];
  for (var i = 0; i < objects.length; ++i) {
    var values = []
    for (j = 0; j < headers.length; ++j) {
      var header = headers[j];
      values.push(header.length > 0 && objects[i][header] ? objects[i][header] : "");
    }
    data.push(values);
  }
  var colInx = headersRange.getColumnIndex();
  var destinationRange = sheet.getRange(firstDataRowIndex, colInx, objects.length, headers.length);
  destinationRange.setValues(data);
}

// getRowsData iterates row by row in the input range and returns an array of objects.
// Each object contains all the data for a given row, indexed by its normalized column name.
// Arguments:
//   - sheet: the sheet object that contains the data to be processed
//   - range: the exact range of cells where the data is stored
//   - columnHeadersRowIndex: specifies the row number where the column names are stored.
//       This argument is optional and it defaults to the row immediately above range;
// Returns an Array of objects.
function getRowsData(sheet, range, columnHeadersRowIndex) {
  columnHeadersRowIndex = columnHeadersRowIndex || range.getRowIndex() - 1;
  var numColumns = range.getEndColumn() - range.getColumn() + 1;
  var headersRange = sheet.getRange(columnHeadersRowIndex, range.getColumn(), 1, numColumns);
  var headers = headersRange.getValues()[0];
  return getObjects(range.getValues(), normalizeHeaders(headers));
}

// For every row of data in data, generates an object that contains the data. Names of
// object fields are defined in keys.
// Arguments:
//   - data: JavaScript 2d array
//   - keys: Array of Strings that define the property names for the objects to create
function getObjects(data, keys) {
  var objects = [];
  for (var i = 0; i < data.length; ++i) {
    var object = {};
    var hasData = false;
    for (var j = 0; j < data[i].length; ++j) {
      var cellData = data[i][j];
      if (isCellEmpty(cellData)) {
        continue;
      }
      object[keys[j]] = cellData;
      hasData = true;
    }
    if (hasData) {
      objects.push(object);
    }
  }
  return objects;
}

// Returns an Array of normalized Strings.
// Arguments:
//   - headers: Array of Strings to normalize
function normalizeHeaders(headers) {
  var keys = [];
  for (var i = 0; i < headers.length; ++i) {
    var key = normalizeHeader(headers[i]);
    if (key.length > 0) {
      keys.push(key);
    }
  }
  return keys;
}

// Normalizes a string, by removing all alphanumeric characters and using mixed case
// to separate words. The output will always start with a lower case letter.
// This function is designed to produce JavaScript object property names.
// Arguments:
//   - header: string to normalize
// Examples:
//   "First Name" -> "firstName"
//   "Market Cap (millions) -> "marketCapMillions
//   "1 number at the beginning is ignored" -> "numberAtTheBeginningIsIgnored"
function normalizeHeader(header) {
  var key = "";
  var upperCase = false;
  for (var i = 0; i < header.length; ++i) {
    var letter = header[i];
    if (letter == " " && key.length > 0) {
      upperCase = true;
      continue;
    }
    //if (!isAlnum(letter)) {
    //  continue;
    //}
    if (key.length == 0 && isDigit(letter)) {
      continue; // first character must be a letter
    }
    if (upperCase) {
      upperCase = false;
      key += letter.toUpperCase();
    } else {
      key += letter.toLowerCase();
    }
  }
  return key;
}

// Returns true if the cell where cellData was read from is empty.
// Arguments:
//   - cellData: string
function isCellEmpty(cellData) {
  return typeof(cellData) == "string" && cellData == "";
}

// Returns true if the character char is alphabetical, false otherwise.
function isAlnum(char) {
  return char >= 'A' && char <= 'Z' ||
    char >= 'a' && char <= 'z' ||
    isDigit(char);
}

// Returns true if the character char is a digit, false otherwise.
function isDigit(char) {
  return char >= '0' && char <= '9';
}
// http://jsfromhell.com/array/chunk
function chunk(a, s){
    for(var x, i = 0, c = -1, l = a.length, n = []; i < l; i++)
        (x = i % s) ? n[c][x] = a[i] : n[++c] = [a[i]];
    return n;
}<|endoftext|>